mirror of
https://github.com/Cccc-owo/CheckInApp.git
synced 2026-06-17 05:56:29 +00:00
feat(backend): add automatic DB migrations
Add a lightweight migration runner with schema_migrations tracking, run pending migrations during backend startup before the scheduler, and keep a manual backend-migrate entrypoint. The change also moves the existing lockout and task-thread-ID schema steps into shared migration modules, updates docs, and archives the OpenSpec change.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
# backend-auto-migrations Specification
|
||||
|
||||
## Purpose
|
||||
Backend database migration contract for applying ordered schema changes during startup and through a manual operator command.
|
||||
## Requirements
|
||||
### Requirement: Ordered backend migration registry
|
||||
The backend SHALL define a deterministic registry of database migrations with stable identifiers and execution order.
|
||||
|
||||
#### Scenario: Registry order is stable
|
||||
- **WHEN** the migration runner loads available migrations
|
||||
- **THEN** it SHALL evaluate them in the registered order using stable migration identifiers.
|
||||
|
||||
#### Scenario: Existing migrations are registered
|
||||
- **WHEN** the backend migration registry is built
|
||||
- **THEN** it SHALL include migrations for the existing account-lockout fields and task thread ID schema changes.
|
||||
|
||||
### Requirement: Applied migration tracking
|
||||
The backend SHALL store applied migration records in the application database and use those records to skip completed migrations.
|
||||
|
||||
#### Scenario: Migration metadata is initialized
|
||||
- **WHEN** the migration runner starts against a database without migration metadata
|
||||
- **THEN** it SHALL create the migration metadata table before checking pending migrations.
|
||||
|
||||
#### Scenario: Pending migration is marked after success
|
||||
- **WHEN** a pending migration completes successfully
|
||||
- **THEN** the backend SHALL record that migration as applied with its stable identifier and applied timestamp.
|
||||
|
||||
#### Scenario: Completed migration is skipped
|
||||
- **WHEN** a migration identifier is already present in the applied migration metadata
|
||||
- **THEN** the backend SHALL skip that migration instead of executing it again.
|
||||
|
||||
#### Scenario: Failed migration is not marked
|
||||
- **WHEN** a migration fails during execution
|
||||
- **THEN** the backend SHALL NOT record that migration as applied.
|
||||
|
||||
### Requirement: Automatic startup migration execution
|
||||
The backend SHALL run pending database migrations automatically during API startup before runtime background work begins.
|
||||
|
||||
#### Scenario: Startup applies migrations before scheduler
|
||||
- **WHEN** the FastAPI lifespan startup runs
|
||||
- **THEN** it SHALL initialize base database tables, run pending migrations, and only then start the scheduler.
|
||||
|
||||
#### Scenario: Startup stops on migration failure
|
||||
- **WHEN** any pending migration fails during startup
|
||||
- **THEN** the backend SHALL fail startup and SHALL NOT start the scheduler.
|
||||
|
||||
#### Scenario: Startup logs migration activity
|
||||
- **WHEN** startup migration execution runs
|
||||
- **THEN** the backend SHALL log whether migrations were applied, skipped, or failed with the relevant migration identifier.
|
||||
|
||||
### Requirement: Manual migration execution
|
||||
The backend SHALL provide a manual command path that runs the same registered migrations used by automatic startup.
|
||||
|
||||
#### Scenario: Operator runs migrations manually
|
||||
- **WHEN** an operator executes the documented backend migration command
|
||||
- **THEN** the command SHALL apply pending registered migrations and skip already-applied migrations.
|
||||
|
||||
#### Scenario: Manual failure exits unsuccessfully
|
||||
- **WHEN** a migration fails during manual execution
|
||||
- **THEN** the command SHALL exit unsuccessfully after reporting the failing migration.
|
||||
|
||||
### Requirement: Existing migration behavior is preserved
|
||||
The backend SHALL preserve the behavior of existing schema changes when they move into the automatic migration path.
|
||||
|
||||
#### Scenario: Account lockout fields are added
|
||||
- **WHEN** the account-lockout migration runs against a database missing its fields
|
||||
- **THEN** it SHALL add `failed_login_attempts`, `locked_until`, and `last_failed_login` to the users table.
|
||||
|
||||
#### Scenario: Task thread identity is backfilled
|
||||
- **WHEN** the task thread ID migration runs against valid existing task payloads
|
||||
- **THEN** it SHALL add or maintain `check_in_tasks.thread_id`, backfill it from `payload_config.ThreadId`, and ensure the per-user thread ID uniqueness index exists.
|
||||
|
||||
#### Scenario: Invalid legacy task payload blocks migration
|
||||
- **WHEN** the task thread ID migration finds missing or duplicate `ThreadId` values that would make the schema invalid
|
||||
- **THEN** it SHALL fail with a clear validation error instead of silently creating inconsistent task identity data.
|
||||
Reference in New Issue
Block a user