# Migration Consolidation - Pre-v1.0 Baseline **Date**: 2025-12-29 **Reason**: Pre-v1.0 release - consolidate incremental migrations into single baseline per repository --- ## Summary PostgreSQL migrations for SbomService.Lineage created during recent sprint work have been consolidated into a single baseline `00001_InitialSchema.sql` file. This follows best practices for pre-v1.0 development where the schema is still evolving and a clean baseline is preferred over numerous incremental migrations. VexLens.Persistence already had a single baseline migration from a previous sprint, so no consolidation was required. --- ## Consolidated Migrations ### 1. SbomService.Lineage **Consolidated File**: `src/SbomService/__Libraries/StellaOps.SbomService.Lineage/Persistence/Migrations/00001_InitialSchema.sql` **Original Migrations** (deleted): - `20251229_001_CreateLineageTables.sql` - `20251229_002_CreateVexDeltasTable.sql` - `20251229_003_CreateSbomVerdictLinksTable.sql` **Tables Created**: 1. **sbom.sbom_lineage_edges** - SBOM artifact relationships (parent/build/base) - 4 indexes for graph traversal - RLS policy for tenant isolation 2. **vex.vex_deltas** - VEX status transitions between SBOM versions - 5 indexes for delta queries - RLS policy for tenant isolation - Supports replay_hash for determinism 3. **sbom.sbom_verdict_links** - Links SBOM versions to VEX consensus - 5 indexes for efficient joins - RLS policy for tenant isolation **Line Count**: 120 lines (consolidated from 114 total lines across 3 files) --- ### 2. VexLens.Persistence **Status**: Already has baseline migration - no consolidation needed **Existing File**: `src/VexLens/StellaOps.VexLens.Persistence/Migrations/001_consensus_projections.sql` **Note**: VexLens.Persistence already had a single baseline migration in place from a previous sprint (SPRINT_20251228_007_BE). No consolidation was required. --- ## Migration Naming Convention **Pre-v1.0 Format**: `00001_InitialSchema.sql` - **00001**: Sequential migration number (future migrations will be 00002, 00003, etc.) - **InitialSchema**: Descriptive name indicating this is the baseline schema - After v1.0 release, migrations will use timestamp-based naming: `YYYYMMDD_HHmmss_Description.sql` --- ## Repository Pattern Each repository module has its own `Migrations/` directory: ``` src/ ├── SbomService/ │ └── __Libraries/ │ └── StellaOps.SbomService.Lineage/ │ └── Persistence/ │ └── Migrations/ │ └── 00001_InitialSchema.sql │ └── VexLens/ └── __Libraries/ └── StellaOps.VexLens.Persistence/ └── Migrations/ └── 00001_InitialSchema.sql ``` --- ## Schema Organization All tables use schema prefixes: - **sbom.*** - SBOM-related tables (lineage, versions, verdict links) - **vex.*** - VEX-related tables (deltas, consensus projections) This follows the StellaOps multi-schema pattern for logical separation and RLS policy isolation. --- ## Row-Level Security (RLS) All tables include: 1. **tenant_id** column (UUID NOT NULL) 2. **RLS enabled** on table 3. **Policy** using `current_setting('app.current_tenant_id', true)::UUID` Example: ```sql ALTER TABLE sbom.sbom_lineage_edges ENABLE ROW LEVEL SECURITY; CREATE POLICY IF NOT EXISTS lineage_edges_tenant_isolation ON sbom.sbom_lineage_edges FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID); ``` --- ## Index Strategy Each table follows consistent index patterns: 1. **Primary queries**: Covering main query paths (e.g., by digest, by CVE) 2. **Tenant isolation**: All indexes include tenant_id 3. **Temporal queries**: DESC ordering on created_at/computed_at 4. **Partial indexes**: WHERE clauses for filtered queries (e.g., status changes only) Example: ```sql CREATE INDEX IF NOT EXISTS idx_vex_deltas_status_change ON vex.vex_deltas(tenant_id, from_status, to_status) WHERE from_status != to_status; ``` --- ## Verification ```bash # Verify SbomService.Lineage baseline migration exists find src/SbomService -name "00001_InitialSchema.sql" # Output: # src/SbomService/__Libraries/StellaOps.SbomService.Lineage/Persistence/Migrations/00001_InitialSchema.sql # Verify no dated migrations remain in SbomService.Lineage find src/SbomService -name "20251229*.sql" # Output: (empty - all removed) # VexLens uses existing baseline from previous sprint ls src/VexLens/StellaOps.VexLens.Persistence/Migrations/ # Output: # 001_consensus_projections.sql ``` --- ## Post-v1.0 Migration Strategy After v1.0 release, migrations will: 1. Use timestamp naming: `YYYYMMDD_HHmmss_Description.sql` 2. Be applied incrementally (no more consolidation) 3. Include rollback scripts where appropriate 4. Be tracked in a migrations table for version control --- ## Related Documentation - `docs/db/SPECIFICATION.md` - Database schema specification - `docs/operations/postgresql-guide.md` - PostgreSQL operations guide - `docs/implplan/archived/COMPLETION_SUMMARY_20251229.md` - Sprint completion summary --- **Consolidation Completed**: 2025-12-29 **Modules Affected**: SbomService.Lineage **Files Removed**: 3 incremental migrations (20251229_001, _002, _003) **Files Created**: 1 baseline migration (00001_InitialSchema.sql) **Files Unchanged**: VexLens.Persistence (already had baseline from previous sprint)