T3: D1 + Drizzle schema and migrations #3

Merged
dzenda merged 110 commits from t3-d1-drizzle into t2-i18n 2026-11-14 17:51:01 +01:00
Owner

T3: D1 + Drizzle

Stacked on #2 (t2-i18n) → #1 (t1-scaffold). Merge those first.

What

  • src/db/schema.ts:
    • Better Auth core tables with plural names (users, sessions, accounts, verifications), for drizzleAdapter(..., { usePlural: true }) in T6.
    • users.username (FIT username) as an additional field.
    • connections: one row per (user, provider ∈ fit|gitlab), kind oauth|pat. The token columns are *_enc and hold ciphertext only (the T4 crypto envelope).
    • Every user-owned table has ON DELETE CASCADE on users.id, so deleting an account is a single hard delete (needed by T23).
    • Timestamps are timestamp_ms with SQL defaults and $onUpdate for updatedAt.
  • migrations/0000_init.sql is generated by drizzle-kit (bun run db:generate) and applied locally with bun run db:migrate (wrangler d1 migrations apply fit-os --local).
  • wrangler.jsonc: a DB D1 binding with a placeholder database_id. No Cloudflare resources were created. Regenerated worker-configuration.d.ts.
  • src/db/client.ts: createDb(env.DB).
  • /api/health now probes D1 and returns { ok, db }, with 503 when the DB or migrations are missing and no error details.
  • Tests use the real migration SQL on in-memory node:sqlite, through Drizzle sqlite-proxy with PRAGMA foreign_keys=ON like D1. @cloudflare/vitest-pool-workers only supports Vitest 4, and we're on Vitest 5.

Verified

  • bun run lint && bun run typecheck && bun run test (24 tests): migrations apply, round trip, UNIQUE(user_id, provider), FK enforcement, cascade hard delete that leaves other users intact, unique email/username, updatedAt bump.
  • bun run db:migrate → 14 commands OK. bun run dev + curl /api/health → {"ok":true,"db":"ok"}. unixepoch('subsec') defaults verified in local D1 with wrangler d1 execute --local.

Astra review (gpt-6-astra)

  • No defects or secret-leakage issues reported.
  • Note: Better Auth 1.7.0–1.7.2 also require accounts.issuer. Dismissed: T6 installs the current 1.7.x (≥1.7.3), which matches this schema. I'll recheck when adding Better Auth.

🤖 Generated with Claude Code

## T3: D1 + Drizzle **Stacked on #2 (`t2-i18n`) → #1 (`t1-scaffold`)**. Merge those first. ### What - `src/db/schema.ts`: - Better Auth core tables with plural names (`users`, `sessions`, `accounts`, `verifications`), for `drizzleAdapter(..., { usePlural: true })` in T6. - `users.username` (FIT username) as an additional field. - `connections`: one row per (user, provider ∈ `fit|gitlab`), kind `oauth|pat`. The token columns are `*_enc` and hold **ciphertext only** (the T4 crypto envelope). - Every user-owned table has `ON DELETE CASCADE` on `users.id`, so deleting an account is a single hard delete (needed by T23). - Timestamps are `timestamp_ms` with SQL defaults and `$onUpdate` for `updatedAt`. - `migrations/0000_init.sql` is generated by drizzle-kit (`bun run db:generate`) and applied locally with `bun run db:migrate` (`wrangler d1 migrations apply fit-os --local`). - `wrangler.jsonc`: a `DB` D1 binding with a **placeholder** `database_id`. No Cloudflare resources were created. Regenerated `worker-configuration.d.ts`. - `src/db/client.ts`: `createDb(env.DB)`. - `/api/health` now probes D1 and returns `{ ok, db }`, with 503 when the DB or migrations are missing and no error details. - Tests use the real migration SQL on in-memory `node:sqlite`, through Drizzle `sqlite-proxy` with `PRAGMA foreign_keys=ON` like D1. `@cloudflare/vitest-pool-workers` only supports Vitest 4, and we're on Vitest 5. ### Verified - `bun run lint && bun run typecheck && bun run test` (24 tests): migrations apply, round trip, `UNIQUE(user_id, provider)`, FK enforcement, cascade hard delete that leaves other users intact, unique email/username, `updatedAt` bump. - `bun run db:migrate` → 14 commands OK. `bun run dev` + `curl /api/health` → `{"ok":true,"db":"ok"}`. `unixepoch('subsec')` defaults verified in local D1 with `wrangler d1 execute --local`. ### Astra review (gpt-6-astra) - No defects or secret-leakage issues reported. - Note: Better Auth 1.7.0–1.7.2 also require `accounts.issuer`. **Dismissed:** T6 installs the current 1.7.x (≥1.7.3), which matches this schema. I'll recheck when adding Better Auth. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dzenda merged commit 7b526bf26c into t2-i18n 2026-11-14 17:51:01 +01:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
dzenda/os!3
No description provided.