--- phase: 42-wallpapers-social-format-conversion-voice plan: 01 subsystem: api tags: [file-type, xlsx, csv-parse, pandoc, libreoffice, content-jobs, renderers, typescript] # Dependency graph requires: - phase: 40-content-job-infra provides: content_jobs table, renderContent switch stub, async job pattern provides: - WallpaperBundle, AppIconBundle, SocialPostBundle, ConvertBundle type definitions in types.ts - wallpaper, social-post, convert cases in renderContent switch - converter-capabilities.ts startup probe for pandoc/libreoffice with cached result - execFileNoThrow utility for safe binary execution - Stub renderers for wallpaper, social-post, convert (Plans 02-04 replace) affects: - 42-02 (wallpaper renderer uses WallpaperBundle type) - 42-03 (social renderer uses SocialPostBundle type) - 42-04 (convert renderer uses ConvertBundle type, converter-capabilities) - 42-05 (voice renderer) - 42-06 (UI wiring) # Tech tracking tech-stack: added: [file-type@22.0.0, xlsx@0.18.5, csv-parse@6.2.1] patterns: - execFileNoThrow pattern for safe binary probing (no throw on exit code !=0) - Startup probe with module-level cache for binary availability key-files: created: - server/src/services/converter-capabilities.ts - server/src/services/renderers/wallpaper-renderer.ts - server/src/services/renderers/social-renderer.ts - server/src/services/renderers/convert-renderer.ts - server/src/utils/execFileNoThrow.ts modified: - server/src/services/renderers/types.ts - server/src/services/content-job-runner.ts - server/package.json - pnpm-lock.yaml key-decisions: - "execFileNoThrow utility created as new server/src/utils/ helper — plan referenced it as 'project standard' but it did not exist yet; created as Rule 2 (missing critical functionality)" - "Stub renderers import and return RenderResult type to satisfy tsc module resolution — Plans 02-04 replace with real implementations" - "converter-capabilities.ts caches capabilities in module-level variable after first probe" patterns-established: - "execFileNoThrow: safe binary probe returning status 0|1, never throwing — use for all optional binary checks" - "Startup probe pattern: probe() called lazily on first get(), result cached in module-level variable" - "Stub renderer pattern: export async function that throws 'Not implemented', satisfies tsc" requirements-completed: [CONV-08] # Metrics duration: 3min completed: 2026-04-04 --- # Phase 42 Plan 01: Foundation — Bundle Types, Job Runner Switch, Converter Capabilities **file-type/xlsx/csv-parse installed, four bundle types added to types.ts, wallpaper/social-post/convert cases wired in content-job-runner, and converter-capabilities service probing pandoc/libreoffice via new execFileNoThrow utility** ## Performance - **Duration:** 3 min - **Started:** 2026-04-04T22:06:42Z - **Completed:** 2026-04-04T22:09:28Z - **Tasks:** 2 - **Files modified:** 9 (3 modified, 5 created, 1 lockfile) ## Accomplishments - Installed file-type@22.0.0, xlsx@0.18.5, csv-parse@6.2.1 in server/ workspace - Added WallpaperBundle, AppIconBundle, SocialPostBundle, ConvertBundle interfaces to types.ts; updated ContentBundle union - Wired wallpaper, social-post, convert cases in renderContent switch with dynamic imports of stub renderers - Created converter-capabilities.ts probing pandoc/libreoffice at startup, caching result for all subsequent calls - Created execFileNoThrow utility for safe binary probing without exceptions ## Task Commits Each task was committed atomically: 1. **Task 1: Install dependencies and define bundle types** - `e809b706` (feat) 2. **Task 2: Wire content-job-runner switch and create converter capabilities service** - `3ba09889` (feat) **Plan metadata:** (docs commit — see below) ## Files Created/Modified - `server/src/services/renderers/types.ts` - Added WallpaperBundle, AppIconBundle, SocialPostBundle, ConvertBundle; updated ContentBundle union - `server/src/services/content-job-runner.ts` - Added wallpaper, social-post, convert cases to renderContent switch - `server/src/services/converter-capabilities.ts` - Startup probe for pandoc/libreoffice, cached capability map - `server/src/utils/execFileNoThrow.ts` - Safe binary execution utility (no throw on non-zero exit) - `server/src/services/renderers/wallpaper-renderer.ts` - Stub renderer (throws "Not implemented") - `server/src/services/renderers/social-renderer.ts` - Stub renderer (throws "Not implemented") - `server/src/services/renderers/convert-renderer.ts` - Stub renderer (throws "Not implemented") - `server/package.json` - Added file-type, xlsx, csv-parse dependencies - `pnpm-lock.yaml` - Updated lockfile ## Decisions Made - Created `execFileNoThrow` utility in `server/src/utils/` — the plan referenced it as "project standard" but it did not exist. Created it as a Rule 2 auto-fix (missing critical functionality for the converter-capabilities probe). - Stub renderers import `RenderResult` type but use `_input` naming convention for unused parameter to satisfy TypeScript strict mode. ## Deviations from Plan ### Auto-fixed Issues **1. [Rule 2 - Missing Critical] Created execFileNoThrow utility** - **Found during:** Task 2 (converter capabilities service) - **Issue:** Plan referenced `src/utils/execFileNoThrow.ts` as "project standard" but the file did not exist in the codebase - **Fix:** Created `server/src/utils/execFileNoThrow.ts` implementing promisify(execFile) wrapper that returns `{ stdout, stderr, status: 0|1 }` without throwing - **Files modified:** server/src/utils/execFileNoThrow.ts (created) - **Verification:** tsc --noEmit passes with zero errors; converter-capabilities.ts imports and uses it correctly - **Committed in:** 3ba09889 (Task 2 commit) --- **Total deviations:** 1 auto-fixed (1 missing critical) **Impact on plan:** Auto-fix necessary for the converter-capabilities probe to compile and run. No scope creep. ## Issues Encountered None beyond the missing execFileNoThrow utility (handled above). ## User Setup Required None - no external service configuration required. ## Next Phase Readiness - All foundation types available for Plans 02-04 - content-job-runner dispatches wallpaper/social-post/convert jobs to stub renderers - Plans 02 (wallpaper), 03 (social), 04 (convert) can now proceed in parallel - execFileNoThrow utility available for any future binary-probe needs --- *Phase: 42-wallpapers-social-format-conversion-voice* *Completed: 2026-04-04*