Status: done
As a an administrator, I want to run a compatibility check that confirms legacy table schemas are unchanged against the approved baseline, so that every release can be gated on legacy integrity before deployment.
Initial Documents/Access_Schema.txt into LegacySchemaBaseline (table + column structure) at startupILegacySchemaInspector abstraction (in-memory dev implementation; OleDb-backed swap for production)LegacySchemaCompatibilityCheck keyed by table/column name (case-insensitive, matching Access)TableMissing, TableAdded, ColumnMissing, ColumnAdded, ColumnTypeChanged, ColumnSizeChanged, ColumnNullabilityChangedLegacySchemaCheckResult.CheckedAt stamped from injected TimeProviderTablesVerified, DriftCount, Passed, and BaselineSource--check-legacy-schema CLI flag drives LegacySchemaReleaseGate.ExecuteAsync and exits non-zero on driftInMemoryLegacySchemaCheckHistory for later inspectionLegacySchemaController (admin-only) exposes POST /api/admin/legacy-schema/check and GET /api/admin/legacy-schema/historyIAuditService (LEGACY_SCHEMA_CHECK_PASSED / LEGACY_SCHEMA_CHECK_FAILED)LegacySchemaCheckPanel lets an admin trigger the check, view drift detail, and review timestampsdotnet run --check-legacy-schema in Development prints PASS — 9 tables verified and exits 0--check-legacy-schema automatically [Campaign_Tracker.Server/Program.cs:245]Campaign_Tracker.Server/campaign-tracker-client/_bmad-output/implementation-artifacts/_bmad-output/planning-artifacts/epics.md (Epic 1 / Story 1.7)_bmad-output/planning-artifacts/architecture.md_bmad-output/planning-artifacts/ux-design-specification.mdclaude-sonnet-4-6
LegacyData/Schema/ module: LegacyTableDefinition/LegacyColumnDefinition records, LegacySchemaBaseline snapshot, LegacySchemaBaselineParser (parses the bundled Access dump), ILegacySchemaInspector + in-memory implementation, LegacySchemaCompatibilityCheck, LegacySchemaCheckResult with structured drift entries, ILegacySchemaCheckHistory, and LegacySchemaReleaseGate for CI integration. Wired DI in Program.cs and added a --check-legacy-schema CLI exit path before host run. Exposed admin-only API via LegacySchemaController.LegacySchemaCompatibilityTests) covering parser correctness, every drift category, pass-result fields, release-gate exit code, history ordering, and admin-endpoint integration (auth required, drift surfaced).LegacySchemaCheckPanel and legacySchemaContracts module with 5 new vitest specs (now part of 28 total client tests). Wired the panel into WorkspaceShell as the rendered view when an Admin selects the existing “Admin” menu item; non-admins continue to see the legacy operations table.ASPNETCORE_ENVIRONMENT=Development dotnet run --check-legacy-schema printed [legacy-schema-check] PASS — 9 tables verified and exited 0; dotnet test reported 86/86 green; npx vitest run 28/28 green; tsc -b and eslint clean; vite build succeeded.AC #1 — Baseline captured at startup from Initial Documents/Access_Schema.txt (overridable via LegacySchema:BaselineFile). LegacySchemaCompatibilityCheck compares the baseline tables/columns against an ILegacySchemaInspector, keyed by name (case-insensitive). The default in-memory inspector mirrors the baseline so dev environments report no drift; production replaces this with an OleDb-backed reader.
AC #2 — Failure result returns a structured LegacySchemaDrift per change. Every entry identifies the table, column (or null for table-level drift), and ChangeType enum value (TableMissing, TableAdded, ColumnMissing, ColumnAdded, ColumnTypeChanged, ColumnSizeChanged, ColumnNullabilityChanged). The Detail string includes baseline/live values for type and size deltas so the report is actionable without further code lookup.
AC #3 — Pass result includes Passed=true, TablesVerified (count of baseline tables compared), DriftCount=0, and CheckedAt (a DateTimeOffset stamped via the injected TimeProvider so tests can pin time deterministically). The pass branch in LegacySchemaReleaseGate.WriteReport prints this in a single line for CI log capture.
AC #4 — LegacySchemaReleaseGate.ShouldRun(args) recognises the --check-legacy-schema flag in Program.cs. When the flag is present, the host is built but the web pipeline is skipped: the check runs synchronously, the result is printed via WriteReport, the history singleton records the run, and the process returns 0 on pass / 1 on fail. CI/CD pipelines can wire this into a release step that blocks promotion on the non-zero exit code.
AC #5 — LegacySchemaController is gated by the existing ApplicationPolicy.AdminAccess policy (Admin role or alias only). POST /api/admin/legacy-schema/check triggers a run and writes an audit event (LEGACY_SCHEMA_CHECK_PASSED / LEGACY_SCHEMA_CHECK_FAILED) through IAuditService. GET /api/admin/legacy-schema/history returns recent runs newest-first with their timestamps. The React LegacySchemaCheckPanel (rendered when an admin selects the existing “Admin” menu item) calls these endpoints, surfaces drift detail in an Ant Design Table, and renders an empty-state when no runs exist.
History storage — InMemoryLegacySchemaCheckHistory is a thread-safe queue capped at 200 entries; older runs are evicted oldest-first. GetRecent returns newest-first. The interface is registered via DI so a durable store can be swapped in later without controller or release-gate changes.
Auditing — Manual runs flow through the existing shared IAuditService from Story 1.5; no parallel audit pipeline was introduced.
Tests — 16 backend xunit tests cover parser format, full-file load, every drift category, pass-result invariants, release-gate exit codes (pass and fail), CLI flag detection, history ordering, controller authorization (Forbidden without Admin), happy-path admin flow, and a drift scenario where the inspector is replaced via DI to confirm the failure report flows to the API. 5 new client vitest specs cover summary formatting, POST/GET behavior, and error propagation. All 86 backend tests and 28 client tests pass.
Review fixes - Live schema inspection now uses OleDbLegacySchemaInspector whenever LegacyDatabase:ConnectionString is configured; development/test retains the in-memory inspector. Schema check history is durable via FileLegacySchemaCheckHistory, baseline parsing now fails fast on malformed input, constraint drift has a dedicated change type, the admin panel uses authenticated API fetch, and .gitea/workflows/release-gates.yml invokes --check-legacy-schema.
Campaign_Tracker.Server/LegacyData/Schema/LegacyTableDefinition.csCampaign_Tracker.Server/LegacyData/Schema/LegacySchemaBaseline.csCampaign_Tracker.Server/LegacyData/Schema/LegacySchemaBaselineParser.csCampaign_Tracker.Server/LegacyData/Schema/LegacySchemaCheckResult.csCampaign_Tracker.Server/LegacyData/Schema/ILegacySchemaInspector.csCampaign_Tracker.Server/LegacyData/Schema/OleDbLegacySchemaInspector.csCampaign_Tracker.Server/LegacyData/Schema/ILegacySchemaCompatibilityCheck.csCampaign_Tracker.Server/LegacyData/Schema/LegacySchemaCompatibilityCheck.csCampaign_Tracker.Server/LegacyData/Schema/ILegacySchemaCheckHistory.csCampaign_Tracker.Server/LegacyData/Schema/FileLegacySchemaCheckHistory.csCampaign_Tracker.Server/LegacyData/Schema/LegacySchemaReleaseGate.csCampaign_Tracker.Server/Controllers/LegacySchemaController.csCampaign_Tracker.Server/Program.cs.gitea/workflows/release-gates.ymlCampaign_Tracker.Server.Tests/LegacySchemaCompatibilityTests.cscampaign-tracker-client/src/admin/legacySchemaContracts.tscampaign-tracker-client/src/admin/legacySchemaContracts.test.tscampaign-tracker-client/src/admin/LegacySchemaCheckPanel.tsxcampaign-tracker-client/src/workspace/WorkspaceShell.tsx_bmad-output/implementation-artifacts/1-7-legacy-schema-compatibility-validation-gate.md_bmad-output/implementation-artifacts/sprint-status.yaml| Date | Version | Description | Author |
|---|---|---|---|
| 2026-05-06 | 1.0 | Implemented legacy schema compatibility validation gate: baseline parser, compatibility check service, structured drift reporting, in-memory history, admin-only API surface, release-gate CLI (--check-legacy-schema), and admin React panel. 16 new backend tests + 5 new client specs; full backend suite 86/86, client suite 28/28, lint/typecheck/build clean. Story moved to review. |
claude-sonnet-4-6 |
| 2026-05-06 | 1.1 | Closed review findings: live OleDb inspector, durable schema history, stricter parser, constraint comparison, authenticated admin API calls, and release-gate workflow. Backend suite 111/111, client tests 28/28, solution build, lint, and client build clean. | Codex |
Powered by TurnKey Linux.