Files
dbis_core/db/migrations/README.md
2026-03-02 12:14:07 -08:00

100 lines
2.9 KiB
Markdown

# Database Migrations
This directory contains SQL migrations that enforce ledger correctness boundaries.
## Migration Order
Run migrations in this order:
1. `001_ledger_idempotency.sql` - Add unique constraint for idempotency
2. `002_dual_ledger_outbox.sql` - Create outbox table
3. `003_outbox_state_machine.sql` - Enforce state machine constraints
4. `004_balance_constraints.sql` - Enforce balance integrity (apply after data cleanup)
5. `005_post_ledger_entry.sql` - Create atomic posting function
6. `006_sal_positions_fees.sql` - SAL extension: positions (asset x chain), fees, reconciliation snapshots
## Running Migrations
### Option 1: Direct SQL execution
```bash
# Set your database connection
export DATABASE_URL="postgresql://user:password@host:port/database"
# Run migrations in order
psql $DATABASE_URL -f db/migrations/001_ledger_idempotency.sql
psql $DATABASE_URL -f db/migrations/002_dual_ledger_outbox.sql
psql $DATABASE_URL -f db/migrations/003_outbox_state_machine.sql
psql $DATABASE_URL -f db/migrations/004_balance_constraints.sql
psql $DATABASE_URL -f db/migrations/005_post_ledger_entry.sql
psql $DATABASE_URL -f db/migrations/006_sal_positions_fees.sql
```
### Option 2: Prisma migrate (if using Prisma migrations)
These SQL files can be added to a Prisma migration:
```bash
npx prisma migrate dev --name add_ledger_correctness_boundaries
```
Then copy the SQL into the generated migration file.
## Important Notes
### Column Naming
These migrations assume **snake_case** column names in the database (Prisma default).
If your database uses camelCase, adjust the SQL accordingly:
- `ledger_id``ledgerId`
- `debit_account_id``debitAccountId`
- etc.
### Balance Constraints
The balance constraints in `004_balance_constraints.sql` will fail if you have existing inconsistent data.
**Before applying:**
1. Audit existing balances
2. Fix any inconsistencies
3. Then apply the constraints
### Testing
After applying migrations, verify:
```sql
-- Check idempotency constraint exists
SELECT constraint_name
FROM information_schema.table_constraints
WHERE table_name = 'ledger_entries'
AND constraint_name LIKE '%reference%';
-- Check outbox table exists
SELECT COUNT(*) FROM dual_ledger_outbox;
-- Test posting function
SELECT * FROM post_ledger_entry(
'Test'::TEXT,
'account1'::TEXT,
'account2'::TEXT,
100::NUMERIC,
'USD'::TEXT,
'fiat'::TEXT,
'Type_A'::TEXT,
'test-ref-123'::TEXT,
NULL::NUMERIC,
NULL::JSONB
);
```
## Rollback
These migrations are designed to be additive. To rollback:
1. Drop the function: `DROP FUNCTION IF EXISTS post_ledger_entry(...);`
2. Drop the outbox table: `DROP TABLE IF EXISTS dual_ledger_outbox CASCADE;`
3. Remove constraints: `ALTER TABLE ledger_entries DROP CONSTRAINT IF EXISTS ledger_entries_unique_ledger_reference;`
4. Remove balance constraints: `ALTER TABLE bank_accounts DROP CONSTRAINT IF EXISTS ...;`