docs(14-postgresql-migration): create phase plan

This commit is contained in:
2026-04-04 12:00:22 +02:00
parent ebc1693eb1
commit 88708f962a
7 changed files with 1380 additions and 2 deletions

View File

@@ -0,0 +1,159 @@
---
phase: 14-postgresql-migration
plan: 04
type: execute
wave: 2
depends_on: [14-01]
files_modified:
- src/server/routes/items.ts
- src/server/routes/categories.ts
- src/server/routes/threads.ts
- src/server/routes/setups.ts
- src/server/routes/auth.ts
- src/server/routes/oauth.ts
- src/server/routes/images.ts
- src/server/routes/settings.ts
- src/server/routes/totals.ts
autonomous: true
requirements: [DB-01, DB-02]
must_haves:
truths:
- "Every route handler awaits service function calls"
- "All route handlers that call services are async"
- "No route returns a Promise object instead of resolved data"
artifacts:
- path: "src/server/routes/items.ts"
provides: "Async item route handlers"
contains: "await"
- path: "src/server/routes/settings.ts"
provides: "Async settings handlers with direct DB calls"
contains: "await"
key_links:
- from: "src/server/routes/*.ts"
to: "src/server/services/*.ts"
via: "await service function calls"
pattern: "await .*(get|create|update|delete)"
---
<objective>
Convert all 9 route handler files to properly await async service calls. Route handlers that call service functions must be async and await the results.
Purpose: With services now async (Plan 03), route handlers must await them. Missing awaits would return Promise objects as JSON responses instead of actual data.
Output: All route files properly await service calls.
</objective>
<execution_context>
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
@$HOME/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/phases/14-postgresql-migration/14-CONTEXT.md
@.planning/phases/14-postgresql-migration/14-RESEARCH.md
@.planning/phases/14-postgresql-migration/14-03-SUMMARY.md
@src/server/routes/items.ts
@src/server/routes/settings.ts
</context>
<interfaces>
<!-- Route handlers use Hono pattern: app.get("/path", async (c) => { ... }) -->
<!-- Services are imported and called: const items = await getAllItems(db) -->
<!-- Settings route accesses DB directly (no service layer): await db.select().from(settings) -->
<!-- Some handlers may already be async (for body parsing). Add await to service calls. -->
Conversion rules for routes:
- Handler callback must be `async (c) => { ... }`
- Every service call: `const result = serviceFunction(db, ...)` -> `const result = await serviceFunction(db, ...)`
- Settings route has direct DB calls: add `await` and remove `.all()/.get()/.run()`
- OAuth routes may have direct DB calls for token validation
</interfaces>
<tasks>
<task type="auto">
<name>Task 1: Convert data route handlers to async (items, categories, threads, setups, totals)</name>
<files>src/server/routes/items.ts, src/server/routes/categories.ts, src/server/routes/threads.ts, src/server/routes/setups.ts, src/server/routes/totals.ts</files>
<read_first>src/server/routes/items.ts, src/server/routes/categories.ts, src/server/routes/threads.ts, src/server/routes/setups.ts, src/server/routes/totals.ts</read_first>
<action>
For each route file, read the full file first. Then:
1. Ensure every handler callback is `async (c) => { ... }` (many may already be async for body parsing)
2. Add `await` before every service function call
3. If any handler has direct DB calls (`.select()`, `.insert()`, etc.), apply the same rules as services: remove `.all()/.get()/.run()`, use destructuring for single rows
**items.ts** — Handlers call: `getAllItems(db)`, `getItemById(db, id)`, `createItem(db, data)`, `updateItem(db, id, data)`, `duplicateItem(db, id)`, `deleteItem(db, id)`. Add `await` before each.
**categories.ts** — Handlers call: `getAllCategories(db)`, `createCategory(db, data)`, `updateCategory(db, id, data)`, `deleteCategory(db, id)`. Add `await` before each.
**threads.ts** — Handlers call: `getAllThreads(db)`, `getThreadById(db, id)`, `createThread(db, data)`, `updateThread(db, id, data)`, `deleteThread(db, id)`, `resolveThread(db, id, data)`, `unresolveThread(db, id)`, `addCandidate(db, data)`, `updateCandidate(db, id, data)`, `removeCandidate(db, id)`, `reorderCandidates(db, data)`. Add `await` before each.
**setups.ts** — Handlers call: `getAllSetups(db)`, `getSetupById(db, id)`, `createSetup(db, data)`, `updateSetup(db, id, data)`, `deleteSetup(db, id)`, `updateSetupItems(db, id, data)`, `updateClassification(...)`. Add `await` before each.
**totals.ts** — Handlers call totals service functions. Add `await` before each.
</action>
<verify>
<automated>! grep -n "= getAllItems\|= getItemById\|= createItem\|= getAllCategories\|= getAllThreads\|= getAllSetups" src/server/routes/items.ts src/server/routes/categories.ts src/server/routes/threads.ts src/server/routes/setups.ts 2>/dev/null | grep -v "await" && echo "PASS" || echo "FAIL"</automated>
</verify>
<acceptance_criteria>
- items.ts: every service call is preceded by `await`
- categories.ts: every service call is preceded by `await`
- threads.ts: every service call is preceded by `await`
- setups.ts: every service call is preceded by `await`
- totals.ts: every service call is preceded by `await`
- No route handler assigns a service call result without `await`
</acceptance_criteria>
<done>All data route handlers properly await async service calls.</done>
</task>
<task type="auto">
<name>Task 2: Convert auth, OAuth, settings, and images route handlers to async</name>
<files>src/server/routes/auth.ts, src/server/routes/oauth.ts, src/server/routes/settings.ts, src/server/routes/images.ts</files>
<read_first>src/server/routes/auth.ts, src/server/routes/oauth.ts, src/server/routes/settings.ts, src/server/routes/images.ts, src/server/middleware/auth.ts</read_first>
<action>
**auth.ts** — Handlers call auth service functions. Add `await` before each service call.
**oauth.ts** — Handlers call OAuth service functions. Add `await` before each service call. Also check for any direct DB queries in OAuth routes and apply async conversion.
**settings.ts** — This route likely accesses the database DIRECTLY (no service layer) using `db.select().from(settings)` etc. Apply full async conversion:
- Remove `.all()``const rows = await db.select().from(settings)`
- Remove `.get()``const [row] = await db.select().from(settings).where(...)`
- Remove `.run()``await db.insert(settings).values(...)`
**images.ts** — May call image service functions. Add `await` before each service call.
**Also check `src/server/middleware/auth.ts`** — The auth middleware queries sessions and API keys. If it has direct DB calls, convert them:
- Make the middleware function async (if not already)
- Add `await` before DB queries
- Remove `.get()` -> use destructuring
</action>
<verify>
<automated>! grep -n "\.all()\|\.get()\|\.run()" src/server/routes/settings.ts src/server/routes/auth.ts src/server/routes/oauth.ts src/server/routes/images.ts 2>/dev/null && echo "PASS" || echo "FAIL"</automated>
</verify>
<acceptance_criteria>
- auth.ts: every service call is preceded by `await`
- oauth.ts: every service call is preceded by `await`
- settings.ts: does NOT contain `.all()`, `.get()`, or `.run()`
- settings.ts: contains `await db.select()` and `await db.insert()`
- images.ts: every service call is preceded by `await`
- If auth middleware has DB calls, they are all awaited with no `.get()` or `.all()`
</acceptance_criteria>
<done>Auth, OAuth, settings, and images routes properly await all DB operations. Auth middleware updated if needed.</done>
</task>
</tasks>
<verification>
- `grep -rn "\.all()\|\.get()\|\.run()" src/server/routes/` returns NO matches
- Every route handler that calls a service function uses `await`
</verification>
<success_criteria>
All 9 route files await async service calls. Settings route uses async direct DB calls. No route handler will return a Promise object instead of resolved data.
</success_criteria>
<output>
After completion, create `.planning/phases/14-postgresql-migration/14-04-SUMMARY.md`
</output>