docs(05-01): create SUMMARY.md for Phase 5 Plan 1 — offer schema migration

- Documents schema.ts changes (5 new tables, relations, TypeScript types)
- Documents Phase 4+5 DB migration applied via SSH due to drizzle-kit TTY limitation
- Confirms zero data loss; all 5 clients and related data preserved
This commit is contained in:
2026-05-30 15:33:42 +02:00
parent 1b0b2eab73
commit d670d49048
@@ -0,0 +1,102 @@
---
plan_id: 05-01
phase: 5
plan: 1
subsystem: database
tags: [schema, drizzle, migration, offer-system]
dependency_graph:
requires: []
provides: [offer_macros, offer_micros, offer_services, offer_micro_services, project_offers, projects, settings]
affects: [src/db/schema.ts, production-db]
tech_stack:
added: []
patterns: [drizzle-orm pgTable, composite primaryKey, onDelete restrict, direct SSH SQL migration]
key_files:
created: []
modified:
- src/db/schema.ts
decisions:
- "Drizzle-kit push TTY limitation bypassed via direct SQL migration over SSH to clienthub-db container"
- "Phase 4 schema (projects, settings, project_id pivot) applied alongside Phase 5 tables in single atomic transaction"
- "One project per client created with deterministic ID (proj_{client_id}) preserving all FK relationships"
metrics:
duration: "~20 minutes"
completed: "2026-05-30"
tasks_completed: 2
files_modified: 1
---
# Phase 5 Plan 1: Schema migration — 5 new offer tables + Drizzle relations Summary
**One-liner:** Five Offer System tables added to schema.ts and production DB via direct SQL migration, with Phase 4 projects table bootstrapped from existing client data.
## Tasks Completed
| Task | Name | Commit | Files |
|------|------|--------|-------|
| 1 | Append five new table definitions and relations to schema.ts | f003441 | src/db/schema.ts |
| 2 | Run migration — create tables in production database | 1b0b2ea | (DB only, via SSH) |
## What Was Built
**schema.ts changes (Task 1):**
- Added `primaryKey` to `drizzle-orm/pg-core` import
- Defined 5 new tables: `offer_macros`, `offer_micros`, `offer_services`, `offer_micro_services`, `project_offers`
- Added Drizzle relations for all 5 new tables
- Added `projectOffers: many(project_offers)` to `projectsRelations`
- Exported 10 new TypeScript types (Select + Insert for each table)
**Database migration (Task 2):**
- Applied in a single atomic transaction via direct SQL over SSH to production `clienthub-db` container
- Phase 4 additions applied: `projects` table (5 rows from clients), `settings` table, `slug` column on clients
- Project data pivoted: `client_id``project_id` across phases (9), payments (10), documents (1), quote_items (3) — zero data loss
- Phase 5 tables created: all 5 offer tables with correct FK constraints
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 3 - Blocking] drizzle-kit push TTY requirement blocked non-interactive execution**
- **Found during:** Task 2
- **Issue:** `drizzle-kit` v0.31.10 requires an interactive TTY for column conflict resolution prompts; the tool cannot be run non-interactively even with `--force` or `--strict` flags
- **Fix:** Applied migration via direct SQL script executed in `clienthub-db` Docker container over SSH (`docker exec -i clienthub-db psql ... < migration.sql`). Used `IF NOT EXISTS` and `ON CONFLICT DO NOTHING` for idempotency.
- **Files modified:** None (DB only)
- **Commit:** 1b0b2ea
**2. [Rule 2 - Missing Critical Functionality] Phase 4 DB migration was never applied to production**
- **Found during:** Task 2 pre-flight check
- **Issue:** Production DB was at Phase 3 state (no `projects`, no `settings`, `client_id` columns still present). The app image `clienthub:04-08` references `projects` table which didn't exist. Phase 5 offer tables require FK to `projects`.
- **Fix:** Applied Phase 4 migration (projects table, settings table, project_id pivot) as part of the same transaction, before creating Phase 5 tables. Created one project per client using `brand_name` as project name and deterministic ID `proj_{client_id}`.
- **Files modified:** None (DB only)
- **Commit:** 1b0b2ea
## Data Safety Verification
- Zero destructive SQL: `grep -iE 'DROP TABLE|TRUNCATE|DROP COLUMN|DELETE FROM'` → no matches
- All 5 clients preserved (COUNT = 5 before and after)
- All 9 phases have `project_id` populated
- All 10 payments have `project_id` populated
- 18 total tables in production DB after migration
## Verification Results
- `npx tsc --noEmit` → exits 0 (no TypeScript errors)
- `grep -c "offer_macros" src/db/schema.ts` → 6 (table def + FK ref + relation + type × 2)
- `grep "primaryKey" src/db/schema.ts` → 19 matches (import + composite PK + all table PKs)
- `grep "onDelete.*restrict" src/db/schema.ts` → matches on `project_offers.micro_id`
- Production DB: all 5 offer tables confirmed present via `\dt`
## Known Stubs
None — this plan is schema-only. No UI or data-access code was written.
## Threat Flags
None — no new network endpoints or auth paths introduced. Schema changes are purely additive.
## Self-Check: PASSED
- `src/db/schema.ts` exists and is modified: FOUND
- Task 1 commit f003441: FOUND
- Task 2 commit 1b0b2ea: FOUND
- All 5 offer tables in production DB: CONFIRMED via SSH verification