Skip to content

FR: @sqlView escape valve + managed-elsewhere marker — register a hand-written DB object instead of aborting meta migrate #208

Description

@dmealing

Summary

Formalizes the escape valve already chartered as "a separate FR to design with Fable" in the #195 follow-ups (spec/roadmap.md, #195 follow-up (a)) and the #195 design doc (2026-07-15-issue-195-projection-readmodel-origins-design.md:23,152). It is out of scope of #195 itself but blocks the same adoption path.

A genuinely irreducible view — recursive CTE, window function, set operation (UNION), or a base the metadata doesn't (yet) model — cannot be synthesized from origin.*. Today a single such view aborts the entire meta migrate run (extract-view-spec.ts:226-231), so an adopter with even one can't migrate anything. The current fallback (a hand-written, unmodeled view) is invisible to the tool: meta migrate can't own it and meta verify --db can't drift-check it.

Two distinct concepts (both must generalize to ANY DB object, not projections only)

1. @sqlView — a metadata-carried, hand-written view body the tool registers but does not author. A worst-case escape hatch inside the metadata file (keeps the SoR the single source of truth):

{ "source.rdb": { "@kind": "view", "@view": "v_report",
    "@sqlView": "SELECT … FROM … WHERE … UNION ALL …" } }

meta migrate emits the CREATE VIEW verbatim, fingerprints it (reuse view-fingerprint.ts), and meta verify --db drift-checks the fingerprint — managed-but-opaque instead of invisible. The tool never parses/derives the SQL; it owns the object's lifecycle, not its contents.

2. A distinct "managed-elsewhere" marker — "this object exists but Flyway / a hand-migration owns its DDL; do not create, drop, or drift-check it." meta migrate skips it (rather than aborting), so one un-modeled object no longer blocks the tree.

The two are orthogonal: (1) is "I give you the DDL, you manage it"; (2) is "someone else manages it, stay out of the way." Both apply to entities and other DB objects, not just view projections.

Why in-metadata (not a side migration file)

Keeps the object visible in the model and drift-gated, and lets the tool make the create-vs-skip decision per marker — the alternative (raw DDL in a Flyway file) drops the object out of the SoR entirely and out of verify --db's sight.

Scope

The two escape attrs on source.rdb (and entities); migrate emits (@sqlView) or skips ("managed-elsewhere") per marker instead of the all-or-nothing abort; verify fingerprints the raw body; generalize across paradigms so the same escape works for any future backend. Design with Fable per the #195 owner ruling (2026-07-15).

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:toolingCLI, packaging, contracts, MCPenhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions