Skip to content

feat: Migration plan graph with dependency ordering and per-step SQL preview #36

@Lazialize

Description

@Lazialize

Problem

The current strata generate --dry-run displays the generated SQL as a single block, without making step dependencies or execution order clear. For complex migrations (multi-table changes, ENUM recreation, FK dependencies, etc.), it's difficult to understand why each step runs in a particular order. Inserting manual approval steps in CI/CD is also difficult.

Proposed Solution

Manage migration execution plans as a graph structure and display a dependency-annotated step list.

Features

  1. Dependency graph visualization

    $ strata generate --dry-run --plan
    
    📋 Migration Plan (8 steps)
    ═══════════════════════════════════
    
    Step 1: CREATE TYPE user_role AS ENUM (...)
      Dependencies: none
    
    Step 2: CREATE TABLE users (...)
      Dependencies: Step 1 (user_role enum)
    
    Step 3: CREATE TABLE posts (...)
      Dependencies: Step 2 (users.id FK reference)
    
    Step 4: CREATE INDEX idx_posts_user_id ON posts(user_id)
      Dependencies: Step 3
    
    Step 5: ⚠️ DROP TABLE legacy_data
      Dependencies: none
      ⚠️  DESTRUCTIVE: This will delete all data in legacy_data
    
  2. Per-step SQL preview

    • --plan --verbose shows the complete SQL for each step
    • --plan --step N shows only a specific step
  3. JSON output (for CI/CD)

    {
      "steps": [
        {
          "order": 1,
          "type": "create_enum",
          "target": "user_role",
          "sql": "CREATE TYPE ...",
          "dependencies": [],
          "destructive": false
        }
      ]
    }

Implementation Plan

  1. MigrationPlan model (src/core/src/core/migration_plan.rs — new)

    pub struct MigrationPlan {
        pub steps: Vec<MigrationStep>,
    }
    
    pub struct MigrationStep {
        pub order: usize,
        pub step_type: StepType,
        pub target: String,           // Table name, ENUM name, etc.
        pub sql: Vec<String>,
        pub dependencies: Vec<usize>, // Orders of dependent steps
        pub is_destructive: bool,
    }
    
    pub enum StepType {
        CreateEnum, AlterEnum, DropEnum,
        CreateTable, AlterTable, DropTable,
        CreateIndex, DropIndex,
        AddConstraint, DropConstraint,
        CreateView, DropView,
    }
  2. Extend MigrationPipeline (src/db/src/services/migration_pipeline/mod.rs)

    • Attach dependency information to the existing 9-stage pipeline
    • Structure each stage's output as MigrationStep
    • Leverage the existing circular dependency detection logic (FK cycle detection)
  3. Extend dry-run formatter (src/cli/src/cli/commands/dry_run_formatter.rs)

    • Step-based display when --plan flag is used
    • Tree display for dependencies
  4. CLI argument additions (src/cli/src/cli/cli.rs)

    • generate --plan: Display in plan mode
    • generate --plan --step N: Details for a specific step

Files Affected

  • src/core/src/core/migration_plan.rs (new)
  • src/db/src/services/migration_pipeline/mod.rs — Step structuring
  • src/cli/src/cli/commands/generate.rs--plan flag
  • src/cli/src/cli/commands/dry_run_formatter.rs — Plan display

Alternatives Considered

  • Graphviz output: Output in DOT format for graph visualization. Excellent visuals but adds external tool dependency. Consider as a future --format dot option
  • Mermaid output: Markdown-friendly graph notation. Can be added later as --format mermaid

Additional Context

  • Corresponds to "Generate a migration plan graph with dependencies" and "Show ordered steps in dry-run with per-step SQL" in ROADMAP.md
  • The existing MigrationPipeline has a 9-stage ordered pipeline, providing a foundation for dependency extraction
  • Circular FK dependency detection logic is already implemented (table_stages.rs)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions