SQLQueryHelperjs - v1.2.6
    Preparing search index...

    Plan Artifact Guide

    This guide defines the operational artifact teams should expect around planReflect(...) even before the runtime exports a persisted plan format directly.

    planReflect(...) already returns useful preview data, but teams operating shared environments usually need more than an in-memory object.

    They need an artifact that can be:

    • reviewed in pull requests or release workflows
    • attached to change approvals
    • archived with release evidence
    • compared across environments when drift is suspected

    A good plan artifact should answer these questions without executing reflect(...):

    • which tables or objects will change
    • whether the change is additive or destructive
    • why a rebuild is required
    • which dependencies are affected
    • whether approvals, change tickets, or production protections will block execution
    • what SQL is likely to be executed or approximated
    • whether a detected rename is only a hint, already approved, or still unresolved

    The recommended shape is a stable JSON document with four sections:

    1. metadata
    2. summary
    3. per-table or per-object details
    4. estimated execution payload

    Recommended filename:

    • plan-reflect-artifact.json
    {
    "metadata": {
    "generatedAt": "2026-04-22T18:15:00.000Z",
    "libraryVersion": "1.1.0",
    "engine": "mysql",
    "environment": "staging",
    "target": {
    "schema": "sqlh_test"
    },
    "source": {
    "command": "npm run plan:staging",
    "gitCommit": "25df719",
    "release": "v1.1.0"
    }
    },
    "summary": {
    "tableCount": 3,
    "actions": {
    "create": 0,
    "alter": 1,
    "rebuild": 1,
    "noop": 1
    },
    "requiresDestructiveApproval": true,
    "requiresChangeTicket": true,
    "blockedInProduction": false,
    "usesDependencyOrchestration": true
    },
    "tables": [
    {
    "qualifiedName": "sqlh_test.users",
    "action": "rebuild",
    "renameHints": [
    {
    "kind": "case-only",
    "from": "Legacy_Code",
    "to": "legacy_code",
    "approved": false
    }
    ],
    "addColumns": ["status"],
    "droppedColumns": ["legacy_code"],
    "incompatibleColumns": [],
    "destructiveReasons": [
    "column removals detected (legacy_code)",
    "dependent objects detected (view:sqlh_test.vw_users)"
    ],
    "blockingDependencies": [
    {
    "kind": "view",
    "qualifiedName": "sqlh_test.vw_users"
    }
    ],
    "indexes": {
    "create": ["idx_users_status"],
    "drop": [],
    "recreate": []
    },
    "policy": {
    "requiresDestructiveApproval": true,
    "requiresChangeTicket": true,
    "blockedInProduction": false
    }
    }
    ],
    "estimatedExecution": {
    "level": "approximate",
    "statements": [
    "DROP VIEW IF EXISTS sqlh_test.vw_users;",
    "CREATE TABLE __sqlh_rebuild_users ...",
    "INSERT INTO __sqlh_rebuild_users (...) SELECT ... FROM sqlh_test.users;",
    "DROP TABLE sqlh_test.users;",
    "RENAME TABLE __sqlh_rebuild_users TO sqlh_test.users;",
    "CREATE VIEW sqlh_test.vw_users AS ...;"
    ]
    }
    }

    The exact keys can still evolve, but the top-level shape should remain stable enough for CI review and diffing.

    The following interface set is the recommended first implementation target.

    type PlanArtifactEngine = "sqlite" | "postgres" | "mysql";

    type PlanArtifactAction = "create" | "alter" | "rebuild" | "destructive-blocked" | "noop";

    type PlanArtifactExecutionLevel = "exact" | "approximate" | "none";

    interface PlanArtifactMetadata {
    generatedAt: string;
    libraryVersion: string;
    engine: PlanArtifactEngine;
    environment?: string;
    target?: {
    schema?: string;
    database?: string;
    };
    source?: {
    command?: string;
    gitCommit?: string;
    release?: string;
    };
    }

    interface PlanArtifactSummary {
    tableCount: number;
    actions: {
    create: number;
    alter: number;
    rebuild: number;
    noop: number;
    };
    requiresDestructiveApproval: boolean;
    requiresChangeTicket: boolean;
    blockedInProduction: boolean;
    usesDependencyOrchestration: boolean;
    }

    interface PlanArtifactDependency {
    kind: string;
    qualifiedName: string;
    details?: string;
    }

    type PlanArtifactRenameHintKind = "case-only" | "suspected-rename";

    interface PlanArtifactRenameHint {
    kind: PlanArtifactRenameHintKind;
    from: string;
    to: string;
    approved: boolean;
    notes?: string;
    }

    interface PlanArtifactTableEntry {
    qualifiedName: string;
    action: PlanArtifactAction;
    renameHints: PlanArtifactRenameHint[];
    addColumns: string[];
    droppedColumns: string[];
    incompatibleColumns: string[];
    destructiveReasons: string[];
    blockingDependencies: PlanArtifactDependency[];
    indexes: {
    create: string[];
    drop: string[];
    recreate: string[];
    };
    policy: {
    requiresDestructiveApproval: boolean;
    requiresChangeTicket: boolean;
    blockedInProduction: boolean;
    };
    }

    interface PlanArtifactEstimatedExecution {
    level: PlanArtifactExecutionLevel;
    statements: string[];
    }

    interface PlanReflectArtifact {
    metadata: PlanArtifactMetadata;
    summary: PlanArtifactSummary;
    tables: PlanArtifactTableEntry[];
    estimatedExecution: PlanArtifactEstimatedExecution;
    }

    This is intentionally narrow. It should be enough for the first persisted implementation without locking the runtime into an oversized schema.

    Metadata should include:

    • generated timestamp
    • library version
    • target engine
    • environment name
    • schema or database target
    • plan command or workflow source
    • git commit or release identifier when available

    Summary should aggregate:

    • number of tables inspected
    • number of creates, alters, rebuilds, and no-op results
    • whether destructive approval is required
    • whether a change ticket is required
    • whether execution would be blocked in production
    • whether dependency orchestration is involved

    Each table entry should expose at least:

    • qualified table name
    • action type
    • rename hints or approved rename signals
    • additive columns
    • dropped columns
    • incompatible columns
    • destructive reasons
    • blocking dependencies
    • indexes to create, drop, or recreate
    • approval and policy flags

    This makes the artifact usable both for engineering review and operational approval.

    Rename handling should be explicit in the artifact instead of being inferred only from dropped and added columns.

    The first useful distinction is:

    • case-only: the runtime detected a casing-only rename that may already map to an existing approval model
    • suspected-rename: the runtime or review tooling believes a drop-plus-add pair may really be a rename, but cannot prove it safely

    Recommended rules:

    • a rename hint must never silently erase the underlying destructive signal
    • approved: true means the runtime already has enough approval data to treat the hint as reviewed
    • approved: false means reviewers still need to decide whether the hint is legitimate
    • unresolved rename hints should remain visible in both table detail and summary review

    The artifact is not responsible for inventing rename semantics. It is responsible for exposing them clearly enough that reviewers do not mistake a rename candidate for a routine destructive delete.

    The summary section should eventually expose rename pressure as well.

    Recommended future summary fields:

    • renameHintCount
    • approvedRenameHintCount
    • unapprovedRenameHintCount

    That makes rename-heavy schema refactors visible before execution.

    To keep the artifact diff-friendly:

    • sort tables by qualified name
    • sort arrays such as addColumns, droppedColumns, and index lists
    • keep boolean policy flags explicit even when false
    • prefer engine-qualified names over ambiguous local names

    Stable ordering matters as much as field coverage if the artifact will live in CI or release evidence.

    The artifact does not need exact final SQL for every engine on day one, but it should aim to provide one of these levels:

    • exact SQL for additive operations
    • estimated SQL sequence for rebuild flows
    • explicit marker when SQL is intentionally approximate

    The important part is that reviewers can see the expected execution boundary before runtime execution begins.

    Suggested execution levels:

    • exact: runtime can provide the real SQL sequence confidently
    • approximate: runtime can provide a faithful execution outline but not every final statement verbatim
    • none: runtime currently cannot emit meaningful SQL estimates for that part of the plan

    When rename hints exist, estimated execution should prefer clarity over confidence. If the runtime cannot guarantee rename-safe SQL, the artifact should still show the likely rebuild or copy path instead of pretending a safe rename statement exists.

    The recommended workflow is:

    1. generate the plan artifact in CI or release tooling
    2. attach it to the review or change request
    3. confirm destructive reasons and dependencies explicitly
    4. approve or reject the rollout
    5. retain the artifact next to release notes or change evidence

    That turns planReflect(...) from a preview helper into an operational review object.

    The current preview types remain the execution-facing contract.

    The plan artifact should be understood as a persisted projection of that data, enriched with:

    • metadata
    • review summary
    • estimated SQL
    • release and environment context

    The minimum useful first version of a persisted plan artifact would be:

    • JSON only
    • one artifact per engine execution target
    • summary plus detailed table entries
    • stable enough to diff in source control or CI artifacts

    That is enough to support review and audit even before richer UI or HTML rendering exists.

    Once the basic JSON artifact exists, the next useful additions would be:

    • a markdown rendering for human review
    • machine-readable risk classification per table
    • explicit environment-policy evaluation output
    • object-level entries for views, triggers, and routines beyond tables

    At that point the likely extension path is a objects array next to tables, instead of overloading table entries with every future engine-specific object kind.

    Another likely extension is a dedicated reviewHints array that can carry rename hints, drift suspicions, and engine-specific cautions without bloating the core table fields too early.

    Use semantic-change-detection.md as the stricter design reference for how rename hints, equivalence, destructive changes, and unknown-risk states should be classified.