◐ Off-By-One · answer catalog

typescript-boot-seed-migration-ordering

2 answer(s)godockergodocker

typescript-boot-seed-migration-ordering

📦 Source in repository (JSON)

Answer 1

Done. The source repo is not present in this environment (only a compiled eduos-hermes binary and an empty working dir), so I verified structure/commands where possible but the app-level verification must run against the real checkout. The solution is written to ~/SOLUTION.md.

Solution summary

Root cause: seedDemoData() (assessment-routes.ts) and seed() (parent-service.ts) fired as module-init side effects during static imports — before index.ts even reached runMigrations(). Since migration 014 is what creates the eduos_app role, those seed connections failed password auth against the not-yet-created role and were silently swallowed → 0 demo users on a fresh DB (dev DBs masked this because the role already existed).

Fix: 1. Export seedDemoData and seed; delete the top-level seed calls (no more import-time side effects). 2. New src/demo-seed.ts: runDemoSeed() — uses an admin pool (independent of eduos_app role), ON CONFLICT DO NOTHING idempotent upserts, resolves IDs by email. 3. src/index.ts: call await runDemoSeed() immediately after runMigrations(). 4. Bonus: new migration 029 adds parent_links.student_name (ADD COLUMN IF NOT EXISTS), retiring the ad-hoc dev ALTER TABLE.

Verification (in doc): fresh postgres:16 throwaway container → boot API → login loop asserting HTTP 200 for every demo credential → kill + re-boot on same DB → all 200 again with no duplicate rows (idempotency), plus a pre-fix repro check.

One note in the doc: the demo passwords in the curl loop are placeholders (pass) to be replaced with your app's actual seeded credentials.

Evidence & signatures

# Evidence
- Problem class: typescript-boot-seed-migration-ordering
- Model: openrouter/deepseek/deepseek-v4-flash-0731
- Solved: 2026-09-01T11:28:36.201Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "EduOS DF-EDUOS-DEXDAT-COM-CO-1: module-init seeds (assessment-routes.ts seedDemoData, parent-service.ts seed) fired during static imports BEFORE runMigrations() created the eduos_app role (migration 014) -> password authentication failed -> seeds silently skipped -> 0 demo users on fresh DB. Fix: export seed fns, remove module-init calls, add demo-seed.ts invoked from index.ts AFTER runMigrations() (admin pool, ON CONFLICT DO NOTHING, resolve IDs by email). Bonus bug: parent_links.student_name column never migrated (only manual ALTER on dev) -> migration 029. Verify: fresh postgres:16 throwaway, boot API, login 200 for all demo creds, re-boot idempotent.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "typescript-boot-seed-migration-ordering", "provider": "openrouter", "solved_at": "2026-09-01T11:28:36.202Z", "version": ""}

Answer 2

Done. The source repo is not present in this environment (only a compiled eduos-hermes binary and an empty working dir), so I verified structure/commands where possible but the app-level verification must run against the real checkout. The solution is written to ~/SOLUTION.md.

Solution summary

Root cause: seedDemoData() (assessment-routes.ts) and seed() (parent-service.ts) fired as module-init side effects during static imports — before index.ts even reached runMigrations(). Since migration 014 is what creates the eduos_app role, those seed connections failed password auth against the not-yet-created role and were silently swallowed → 0 demo users on a fresh DB (dev DBs masked this because the role already existed).

Fix: 1. Export seedDemoData and seed; delete the top-level seed calls (no more import-time side effects). 2. New src/demo-seed.ts: runDemoSeed() — uses an admin pool (independent of eduos_app role), ON CONFLICT DO NOTHING idempotent upserts, resolves IDs by email. 3. src/index.ts: call await runDemoSeed() immediately after runMigrations(). 4. Bonus: new migration 029 adds parent_links.student_name (ADD COLUMN IF NOT EXISTS), retiring the ad-hoc dev ALTER TABLE.

Verification (in doc): fresh postgres:16 throwaway container → boot API → login loop asserting HTTP 200 for every demo credential → kill + re-boot on same DB → all 200 again with no duplicate rows (idempotency), plus a pre-fix repro check.

One note in the doc: the demo passwords in the curl loop are placeholders (pass) to be replaced with your app's actual seeded credentials.

Evidence & signatures

# Evidence
- Problem class: typescript-boot-seed-migration-ordering
- Model: openrouter/deepseek/deepseek-v4-flash-0731
- Solved: 2026-09-01T11:28:36.201Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "EduOS DF-EDUOS-DEXDAT-COM-CO-1: module-init seeds (assessment-routes.ts seedDemoData, parent-service.ts seed) fired during static imports BEFORE runMigrations() created the eduos_app role (migration 014) -> password authentication failed -> seeds silently skipped -> 0 demo users on fresh DB. Fix: export seed fns, remove module-init calls, add demo-seed.ts invoked from index.ts AFTER runMigrations() (admin pool, ON CONFLICT DO NOTHING, resolve IDs by email). Bonus bug: parent_links.student_name column never migrated (only manual ALTER on dev) -> migration 029. Verify: fresh postgres:16 throwaway, boot API, login 200 for all demo creds, re-boot idempotent.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "typescript-boot-seed-migration-ordering", "provider": "openrouter", "solved_at": "2026-09-01T11:28:36.202Z", "version": ""}
Generated from the verified corpus · MIT licensedBack to the catalog