--- phase: 41-diagrams-icons-theme-engine plan: "01" subsystem: api tags: [culori, resvg, svgo, wcag-contrast, playwright-core, shadcn, sse, content-jobs] # Dependency graph requires: - phase: 40-job-infrastructure provides: content_jobs table, renderContent stub, SSE events, contentJobRunner.dispatch, content-job routes provides: - culori, @resvg/resvg-js, wcag-contrast, svgo, playwright-core installed in server - server/src/services/renderers/types.ts — RenderResult, DiagramBundle, IconSetBundle, ThemePaletteBundle, PaletteRole, ContentBundle - content-job-runner switch dispatching diagram/icon-set/theme-palette to renderer imports - stub renderer files: diagram-renderer.ts, icon-renderer.ts, theme-renderer.ts (ready for Phase 41 plans 02-04) - ui/src/api/contentJobs.ts — submitContentJob, getContentJob, getContentJobAsset - ui/src/hooks/useContentJob.ts — submit, reset, SSE progress tracking - ui/src/components/ui/progress.tsx and toggle.tsx (shadcn) affects: [41-02-diagram, 41-03-icon, 41-04-theme, 41-05-ui-generator, 41-06-ui-theme] # Tech tracking tech-stack: added: [culori, "@resvg/resvg-js", wcag-contrast, svgo, "playwright-core@1.58.2"] patterns: - "Dynamic import renderer dispatch: switch(jobType) { case 'x': const { fn } = await import('./renderers/x-renderer.js') }" - "useContentJob hook: companyId parameter, submit/reset, EventSource SSE, progress = queued:5% / running:50% / done:100%" - "culori ESM (converter/formatHex) works directly under NodeNext — no fn/ import needed" key-files: created: - server/src/services/renderers/types.ts - server/src/services/renderers/diagram-renderer.ts - server/src/services/renderers/icon-renderer.ts - server/src/services/renderers/theme-renderer.ts - ui/src/api/contentJobs.ts - ui/src/hooks/useContentJob.ts - ui/src/components/ui/progress.tsx - ui/src/components/ui/toggle.tsx modified: - server/src/services/content-job-runner.ts - server/package.json - pnpm-lock.yaml key-decisions: - "Renderer stub files created to satisfy tsc module resolution — plans 02-04 replace with real implementations" - "playwright-core@1.58.2 pinned to match @playwright/test version in root" - "culori ESM import confirmed working under NodeNext — no workaround needed" patterns-established: - "Renderer pattern: each renderer in server/src/services/renderers/{name}-renderer.ts, exports async function with RenderResult return type" - "UI hook pattern: useContentJob(companyId) — accept companyId as parameter (not from context) matching other hooks in codebase" requirements-completed: [DIAG-01, DIAG-02, ICON-01, THEME-01] # Metrics duration: 15min completed: 2026-04-04 --- # Phase 41 Plan 01: Foundation — Shared Types, Deps, Job Runner, UI Hook Summary **culori/resvg/svgo deps installed, RenderResult bundle types defined, content-job-runner wired to diagram/icon-set/theme-palette switch, and useContentJob SSE hook ready for UI plans** ## Performance - **Duration:** ~15 min - **Started:** 2026-04-04T20:30:00Z - **Completed:** 2026-04-04T20:45:00Z - **Tasks:** 2 - **Files modified:** 9 ## Accomplishments - All 5 server deps (culori, @resvg/resvg-js, wcag-contrast, svgo, playwright-core@1.58.2) installed and verified importable via tsx - Bundle type contracts (RenderResult, DiagramBundle, IconSetBundle, ThemePaletteBundle) defined as stable API for all Phase 41 renderers - content-job-runner.ts `renderContent` stub replaced with dynamic import switch dispatching to three renderer files - useContentJob hook with SSE progress tracking, EventSource cleanup on unmount/done/failed - shadcn progress and toggle components added to UI ## Task Commits 1. **Task 1: Install dependencies and add shadcn components** - `f3c08690` (feat) 2. **Task 2: Shared types, content-job-runner switch, useContentJob hook, API helpers** - `39af92c6` (feat) ## Files Created/Modified - `server/src/services/renderers/types.ts` - Shared bundle type contracts for all renderers - `server/src/services/renderers/diagram-renderer.ts` - Stub (tsc resolution; Phase 41-02 implements) - `server/src/services/renderers/icon-renderer.ts` - Stub (tsc resolution; Phase 41-03 implements) - `server/src/services/renderers/theme-renderer.ts` - Stub (tsc resolution; Phase 41-04 implements) - `server/src/services/content-job-runner.ts` - Replaced stub renderContent with switch dispatch - `ui/src/api/contentJobs.ts` - submitContentJob, getContentJob, getContentJobAsset - `ui/src/hooks/useContentJob.ts` - submit/reset, SSE EventSource progress tracking - `ui/src/components/ui/progress.tsx` - shadcn Progress component - `ui/src/components/ui/toggle.tsx` - shadcn Toggle component - `server/package.json` - Added 5 new dependencies - `pnpm-lock.yaml` - Updated lockfile ## Decisions Made - Created stub renderer files (diagram-renderer.ts, icon-renderer.ts, theme-renderer.ts) to satisfy TypeScript module resolution. The plan noted runtime failure is expected until renderers are implemented — tsc still requires the files exist for `import()` to resolve. - playwright-core pinned at 1.58.2 to match @playwright/test version in root to avoid binary mismatch. ## Deviations from Plan ### Auto-fixed Issues **1. [Rule 2 - Missing Critical] Created renderer stub files for tsc resolution** - **Found during:** Task 2 (content-job-runner switch implementation) - **Issue:** TypeScript's `--noEmit` check fails on dynamic imports to non-existent files even when the plan explicitly says runtime failure is expected - **Fix:** Created minimal stub files exporting the expected function signatures with `throw new Error("not yet implemented")` - **Files modified:** server/src/services/renderers/diagram-renderer.ts, icon-renderer.ts, theme-renderer.ts - **Verification:** `pnpm tsc --noEmit --project server/tsconfig.json` passes with exit 0 - **Committed in:** 39af92c6 (Task 2 commit) --- **Total deviations:** 1 auto-fixed (Rule 2 - missing for correctness) **Impact on plan:** Necessary for tsc verification criterion. Stubs are clearly marked and will be replaced by plans 02-04. ## Issues Encountered - Pre-existing TypeScript errors exist in ui/tsconfig.json (unrelated files: AgentConfigForm.tsx, useKeyboardShortcuts.ts, useNexusMode.ts, usePiperTts.ts, useVadRecorder.ts, InstanceGeneralSettings.tsx, PersonalAssistant.tsx). These are out-of-scope pre-existing issues, not caused by this plan. Server TSC passes cleanly. ## User Setup Required None - no external service configuration required. ## Next Phase Readiness - Plans 41-02 (diagram renderer), 41-03 (icon renderer), 41-04 (theme renderer) can now import from `./renderers/types.js` and implement their functions against the stub signatures - useContentJob hook ready for consumption by UI plans 41-05 and 41-06 - All deps available: culori for OKLCH color math, @resvg/resvg-js for SVG→PNG, svgo for SVG optimization, wcag-contrast for WCAG AA checks --- *Phase: 41-diagrams-icons-theme-engine* *Completed: 2026-04-04*