typescript-boot-seed-migration-ordering
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.
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 - 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": ""}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.
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 - 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": ""}