51 lines
4.5 KiB
Plaintext
51 lines
4.5 KiB
Plaintext
## Codebase Patterns
|
|
- 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`
|
|
- `@/*` path alias maps to `src/renderer/*` (configured in tsconfig.json paths)
|
|
- All DB tables use `CREATE TABLE IF NOT EXISTS` for non-destructive migrations
|
|
- All IDs are UUIDs generated via `crypto.randomUUID()`
|
|
- TypeScript strict mode + noUncheckedIndexedAccess enabled; always account for possible undefined on array access
|
|
- electron-store@8 (CJS) used for app settings; use lazy init pattern `getStore()` like `getDb()` to avoid calling before app ready
|
|
- ESLint uses `eslint-import-resolver-typescript` to resolve `@/*` aliases; configured in `.eslintrc.json` under `settings.import/resolver`
|
|
- App settings (sidebar state, etc.) exposed via `settings` tRPC sub-router for type-safe renderer access
|
|
|
|
---
|
|
|
|
## 2026-02-19 - US-003
|
|
- What was implemented:
|
|
- Installed: electron-trpc, @trpc/server, @trpc/client, @trpc/react-query, @tanstack/react-query, zod
|
|
- Created `src/main/router/index.ts` with full appRouter: stub routers for health, clients, projects, tasks, checkpoints, notes, ai
|
|
- Updated `src/preload/index.ts` to call `exposeElectronTRPC()`
|
|
- Updated `src/main/index.ts` to call `createIPCHandler({ router: appRouter, windows: [win] })`; `createWindow()` now returns `BrowserWindow`
|
|
- Created `src/renderer/lib/trpc.ts` with `createTRPCReact<AppRouter>()`
|
|
- Updated `src/renderer/index.tsx` to wrap app in `TRPCProvider` + `QueryClientProvider`
|
|
- Updated `src/renderer/routes/index.tsx` to call `trpc.health.ping.useQuery()` and display 'tRPC IPC bridge: pong'
|
|
- Files changed: package.json, package-lock.json, prd.json, src/main/index.ts, src/main/router/index.ts (new), src/preload/index.ts, src/renderer/index.tsx, src/renderer/lib/trpc.ts (new), src/renderer/routes/index.tsx
|
|
- **Learnings for future iterations:**
|
|
- electron-trpc `exposeElectronTRPC` is imported from `electron-trpc/main` (not a separate package)
|
|
- `ipcLink` is imported from `electron-trpc/renderer` in the renderer process
|
|
- `createTRPCReact<AppRouter>()` requires importing the AppRouter type from the main process router — this is a type-only import so it doesn't bundle main process code into renderer
|
|
- The TRPCProvider must wrap QueryClientProvider (or be a sibling); both need the same queryClient instance
|
|
- Stub routers return empty arrays or null — they will be replaced in US-005 through US-008
|
|
---
|
|
|
|
## 2026-02-19 - US-004
|
|
- What was implemented:
|
|
- Installed: electron-store@8 (CJS-compatible, for persistent app settings), @fontsource/geist (self-hosted Geist font), eslint-import-resolver-typescript (ESLint path alias fix)
|
|
- Created `src/main/store.ts` with lazy `getStore()` pattern using electron-store
|
|
- Added `settings` tRPC sub-router with `getSidebarCollapsed` query and `setSidebarCollapsed` mutation
|
|
- Updated `src/renderer/components/layout/AppShell.tsx` to: persist sidebar collapse via tRPC, add right-edge 'keep scrolling for AI' vertical label with ChevronDown icon
|
|
- Updated `src/renderer/globals.css`: replaced Google Fonts CDN with @fontsource/geist imports (weights 400/500/600)
|
|
- Updated `index.html`: removed Google Fonts CDN links
|
|
- Updated `.eslintrc.json`: added eslint-import-resolver-typescript to fix @/* alias resolution (fixed all 7 pre-existing lint errors)
|
|
- Files changed: .eslintrc.json, index.html, package.json, package-lock.json, src/main/router/index.ts, src/main/store.ts (new), src/renderer/components/layout/AppShell.tsx, src/renderer/globals.css
|
|
- **Learnings for future iterations:**
|
|
- Use electron-store@8 (not v9+) — v9+ is ESM-only and breaks with CommonJS main process
|
|
- electron-store must NOT be initialized at module import time (before app.ready); use lazy `getStore()` like `getDb()` pattern
|
|
- For sidebar/UI state loaded from IPC: use `localState ?? queryData ?? default` pattern to avoid flash while query resolves
|
|
- @fontsource packages are the npm equivalent of Google Fonts — import weight-specific CSS files (e.g., `@fontsource/geist/400.css`)
|
|
- ESLint `import/no-unresolved` requires `eslint-import-resolver-typescript` with `alwaysTryTypes: true` to resolve TypeScript path aliases
|
|
- The `writingMode: 'vertical-rl'` + `transform: 'rotate(180deg)'` CSS pattern creates bottom-to-top text for vertical affordance labels
|
|
---
|