From 3d6459850c558cad54458a08d7e73e160048da4a Mon Sep 17 00:00:00 2001 From: Roberto Musso Date: Thu, 19 Feb 2026 17:02:41 +0100 Subject: [PATCH] chore: mark US-007 complete in prd.json and update progress log Co-Authored-By: Claude Sonnet 4.6 --- prd.json | 4 ++-- progress.txt | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/prd.json b/prd.json index 5e9e67d..9101acb 100644 --- a/prd.json +++ b/prd.json @@ -121,8 +121,8 @@ "Typecheck passes" ], "priority": 7, - "passes": false, - "notes": "" + "passes": true, + "notes": "Completed: tasks.list (LEFT JOIN projects+clients+parentClients for breadcrumb fields, and() filters for projectId/status/search via like(), orderBy CASE for priority), tasks.create (UUID + createdAt + defaults), tasks.update (partial set), tasks.delete. alias() from drizzle-orm/sqlite-core for self-join." }, { "id": "US-008", diff --git a/progress.txt b/progress.txt index 134747d..665e986 100644 --- a/progress.txt +++ b/progress.txt @@ -1,4 +1,7 @@ ## Codebase Patterns +- `alias(table, 'alias_name')` from `drizzle-orm/sqlite-core` enables self-joins (e.g., clients → parentClients for hierarchy) +- `sql\`CASE WHEN ... THEN ... ELSE ... END\`` for conditional SELECT fields (e.g., clientName vs subClientName based on parentId) +- `or(like(col1, pattern), like(col2, pattern))` for multi-column search; SQLite LIKE on NULL columns safely returns NULL (falsy) so OR is safe - Vite configs use `.mts` extension (not `.ts`) to avoid ESM/CJS conflict with electron-forge's externalize-deps plugin - electron-trpc uses `exposeElectronTRPC()` in preload and `createIPCHandler({ router, windows })` in main; renderer uses `ipcLink()` from `electron-trpc/renderer` - appRouter lives at `src/main/router/index.ts`; renderer client at `src/renderer/lib/trpc.ts` @@ -85,3 +88,19 @@ - Guard against empty arrays before using `inArray` — while `allClientIds` is never empty (starts with input.id), `projectIds` could be empty; guarded with `if (projectIds.length > 0)` block - `@typescript-eslint/no-non-null-assertion` is configured as a warning (not error) in this project — `queue.shift()!` is fine after a `length > 0` check --- + +## 2026-02-19 - US-007 +- What was implemented: + - Full `tasksRouter` replacing stubs in `src/main/router/index.ts` + - Added imports: `or`, `like`, `sql` from `drizzle-orm`; `alias` from `drizzle-orm/sqlite-core` + - `tasks.list`: LEFT JOINs projects → clients → parentClients (alias for self-join); CASE WHEN for clientName/subClientName breadcrumb fields; `and()` with optional conditions for projectId/status/search; `like()` OR search on title+description; CASE expression for priority ordering + - `tasks.create`: inserts with UUID, defaults (status='todo', priority='medium'), createdAt=Date.now() + - `tasks.update`: partial set object — only sets defined fields + - `tasks.delete`: deletes by id, returns `{ success: true }` +- Files changed: `src/main/router/index.ts`, `prd.json`, `progress.txt` +- **Learnings for future iterations:** + - `alias(table, 'alias_name')` is from `drizzle-orm/sqlite-core` (NOT `drizzle-orm`) for SQLite self-joins + - `sql\`CASE WHEN ${col} IS NOT NULL THEN ${alias.col} ELSE ${col} END\`` for conditional field selection using drizzle template literals + - `or(like(col1, pattern), like(col2, pattern))` composes safely — null columns evaluate to NULL (falsy) in WHERE + - For priority ordering: `asc(sql\`CASE ${tasks.priority} WHEN 'high' THEN 1 WHEN 'medium' THEN 2 WHEN 'low' THEN 3 ELSE 4 END\`)` puts high priority first +---