---
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*
