kura_schema_verify (kura v2.0.6)

View Source

Runtime verification that declared schemas match the live database.

Schemas declare their structure via kura_schema:fields/0 and kura_schema:indexes/0. Migrations are supposed to bring the database into agreement with those declarations — but every step in that chain has been a silent failure mode in production:

  • a generated migration was forgotten and never committed,
  • a hand-written migration had a typo,
  • the migration was applied on staging but rolled back on prod (e.g. a deploy aborted partway),
  • the schema was edited without regenerating the migration,
  • rebar3 kura compile missed the diff (e.g. an index that was declared after the table-creation migration but before index-diffing was supported by the plugin).

Each of these leaves an app that boots cleanly and only fails on the first query that touches the missing column or constraint — often hours later, in production. verify/1,2 is the runtime guardrail: call it from a healthcheck or readiness probe, fail loudly if drift is detected.

The check is structural, not behavioural: column type comparisons across the postgres⇄kura type boundary are too noisy to be useful (e.g. stringcharacter varying(255)text are equivalent in practice and would generate false positives). We pin only:

  • declared tables exist
  • declared columns exist (by name) on those tables
  • declared indexes exist (by generated name)

False negatives are possible (e.g. column type drift), but every issue this does report is a real, blocking problem.

Summary

Functions

The conventional name kura generates for an index declared via kura_schema:indexes/0. Exposed so callers building diagnostics can match against pg_indexes.indexname.

Discover all kura_schema-implementing modules reachable from the application that owns RepoMod. Same discovery contract as kura_migrator:discover_migrations/1: relies on the app's modules list. Useful as a starting point for building scoped verifiers.

Verify all schemas reachable from the repo's owning application.

Verify a specific list of schema modules. Useful when callers want to scope the check (for example, to a single domain) rather than cover the whole app.

Types

drift_issue()

-type drift_issue() ::
          {missing_table, binary()} |
          {missing_column, binary(), binary()} |
          {missing_index, binary(), [atom()], map()}.

Functions

declared_index_name(Table, Cols)

-spec declared_index_name(binary(), [atom()]) -> binary().

The conventional name kura generates for an index declared via kura_schema:indexes/0. Exposed so callers building diagnostics can match against pg_indexes.indexname.

discover_schemas(RepoMod)

-spec discover_schemas(module()) -> [module()].

Discover all kura_schema-implementing modules reachable from the application that owns RepoMod. Same discovery contract as kura_migrator:discover_migrations/1: relies on the app's modules list. Useful as a starting point for building scoped verifiers.

verify(RepoMod)

-spec verify(module()) -> ok | {drift, [drift_issue()]} | {error, term()}.

Verify all schemas reachable from the repo's owning application.

Returns ok if every declared schema's table, columns, and indexes exist in the live database. Returns {drift, Issues} listing each discrepancy. Returns {error, Reason} if the database itself can't be reached.

verify/2

-spec verify(module(), [module()]) -> ok | {drift, [drift_issue()]} | {error, term()}.

Verify a specific list of schema modules. Useful when callers want to scope the check (for example, to a single domain) rather than cover the whole app.