Schema changes
The schema lives in codika-os-app/src/lib/db/schema.ts. Migrations land in codika-os-app/drizzle/. The CLI’s payload shape and the app’s ingestion endpoint are both downstream of this file — when you change it, you usually need to update the CLI too.
Workflow
Section titled “Workflow”cd codika-os-app
# 1. Edit src/lib/db/schema.ts
# 2. Generate the migrationnpm run db:generate# → writes drizzle/<NNNN>_<name>.sql
# 3. Review the SQL by hand# (Drizzle's default migrations are good but not perfect — read the diff)
# 4. Apply to devnpm run db:migrate drizzle/<NNNN>_<name>.sql
# 5. Verify in the dashboard
# 6. Apply to prodDB_TARGET=prod npm run db:migrate drizzle/<NNNN>_<name>.sql
# 7. Update aggregators that read the new columns# (src/lib/server/tracking-overview.ts, project-detail.ts, session-detail.ts, …)- Don’t run
npm run db:push. It’s interactive, needs a TTY, and prompts for destructive ops you can miss in CI. Usedb:migrateagainst generated SQL. - Don’t edit a generated
drizzle/<NNNN>_*.sqlfile after it’s applied to prod. Roll forward with a new migration.
Cross-repo follow-ups
Section titled “Cross-repo follow-ups”A schema change usually means follow-up work in sibling repos. Make the change in all of them in the same PR (or back-to-back PRs):
| You changed… | Check / update |
|---|---|
| A column the CLI sends | codika-os-cli/src/core/uploader.ts payload shape, and codika-os-app/src/routes/api/sync/+server.ts ingestion |
| A column an aggregator reads | The aggregator under codika-os-app/src/lib/server/ |
| A column the page renders | The component under src/lib/components/tracking/ and the page route |
An immutable column (e.g. projects.slug) | Don’t — see the projects page for why |
| Anything user-facing | Update this docs site (and AGENTS.md + llms.txt if relevant) |
The four repos are versioned independently but documented as one system. When a change crosses repos, mirror it everywhere or the docs lie.