nexus/.planning/phases/44-video-presentations/44-01-SUMMARY.md

158 lines
8.7 KiB
Markdown

---
phase: 44-video-presentations
plan: 01
subsystem: content-renderer
tags: [remotion, video, presentations, workspace-package, typescript, content-jobs]
# Dependency graph
requires:
- phase: 40-job-infrastructure
provides: content_jobs table, renderContent switch pattern, contentJobRunner dispatch
provides:
- packages/content-renderer workspace package with remotion 4.0.445
- PitchDeck and DemoVideo Remotion compositions (Series-based, calculateMetadata)
- getBundlePath (cached bundle) and renderPresentationComposition (concurrency:1) exports
- UI-safe compositions/index.ts sub-export (no bundler/renderer imports)
- content_job.progress LiveEventType in shared constants
- PresentationBundle interface in ContentBundle union
- presentation case in renderContent dispatching to presentation-renderer stub
affects:
- 44-video-presentations/44-02 (server renderer uses getBundlePath, renderPresentationComposition)
- 44-video-presentations/44-03 (UI consumes PresentationBundle, compositions sub-export)
# Tech tracking
tech-stack:
added:
- remotion@4.0.445
- "@remotion/bundler@4.0.445"
- "@remotion/renderer@4.0.445"
patterns:
- Remotion isolated in packages/content-renderer/ workspace package — webpack bundler must not enter Vite/tsc server context
- getBundlePath caches bundle path at module level — called once at startup, reused per render
- compositions/index.ts is UI-safe (no @remotion/bundler or @remotion/renderer imports)
- tsconfig.json overrides module to CommonJS + moduleResolution Node — required for Remotion's rspack internal resolution
- calculateMetadata static function on component for dynamic duration based on slide count
- Stub renderer pattern: throws "not implemented" to satisfy tsc module resolution (plan 02 replaces)
key-files:
created:
- packages/content-renderer/package.json
- packages/content-renderer/tsconfig.json
- packages/content-renderer/src/index.ts
- packages/content-renderer/src/Root.tsx
- packages/content-renderer/src/compositions/index.ts
- packages/content-renderer/src/compositions/PitchDeck.tsx
- packages/content-renderer/src/compositions/DemoVideo.tsx
- packages/content-renderer/src/components/SlideFrame.tsx
- packages/content-renderer/src/components/TitleSlide.tsx
- server/src/services/renderers/presentation-renderer.ts
modified:
- packages/shared/src/constants.ts
- server/src/services/renderers/types.ts
- server/src/services/content-job-runner.ts
key-decisions:
- "Remotion workspace package uses CommonJS module resolution (no type:module) — Remotion rspack bundler requires CommonJS"
- "getBundlePath caches bundle path at module level — bundle() called once, not per-render"
- "compositions/index.ts is UI-safe sub-export — no @remotion/bundler or @remotion/renderer imports"
- "renderPresentationComposition uses concurrency:1 to avoid competing with LLM inference"
- "renderMedia called with outputLocation:null to get Buffer return from RenderMediaResult"
- "presentation-renderer.ts stub added to satisfy tsc module resolution — plan 02 implements real renderer"
- "renderContent extended with optional companyId and jobId params for presentation SSE progress events"
patterns-established:
- "Remotion isolated workspace package: webpack context never enters server tsc/Vite context"
- "calculateMetadata on component exports enables dynamic durationInFrames from slide count"
- "UI-safe sub-export: compositions/index.ts imports only from remotion (not bundler/renderer)"
requirements-completed: [PRES-01, PRES-02, PRES-04]
# Metrics
duration: 3min
completed: 2026-04-04
---
# Phase 44 Plan 01: Video Presentations — Remotion Workspace Foundation Summary
**Remotion 4.0.445 workspace package with PitchDeck/DemoVideo compositions, cached getBundlePath, concurrency:1 renderPresentationComposition, and presentation job wiring in content-job-runner**
## Performance
- **Duration:** ~3 min
- **Started:** 2026-04-04T23:20:41Z
- **Completed:** 2026-04-04T23:24:00Z
- **Tasks:** 2
- **Files modified:** 13
## Accomplishments
- Created `packages/content-renderer/` as isolated pnpm workspace package with remotion 4.0.445, @remotion/bundler, @remotion/renderer
- Root.tsx registers PitchDeck and DemoVideo compositions via registerRoot; tsconfig uses CommonJS resolution for Remotion rspack compatibility
- Extended shared constants with `content_job.progress` LiveEventType, added `PresentationBundle` to ContentBundle union, wired `presentation` case in content-job-runner
## Task Commits
1. **Task 1: Create packages/content-renderer workspace package with Remotion compositions** - `ba7ac20d` (feat)
2. **Task 2: Extend shared constants, renderer types, and content-job-runner for presentations** - `a0365020` (feat)
## Files Created/Modified
- `packages/content-renderer/package.json` - Workspace package, remotion deps, CommonJS exports
- `packages/content-renderer/tsconfig.json` - Extends base, overrides module/moduleResolution to CommonJS/Node
- `packages/content-renderer/src/Root.tsx` - registerRoot, PitchDeck + DemoVideo Compositions
- `packages/content-renderer/src/compositions/PitchDeck.tsx` - Slide/PitchDeckProps types, Series-based layout, calculateMetadata
- `packages/content-renderer/src/compositions/DemoVideo.tsx` - DemoSlide/DemoVideoProps types, gradient layout with narration overlay, calculateMetadata
- `packages/content-renderer/src/components/SlideFrame.tsx` - fade-in animation, accent bar, slide counter
- `packages/content-renderer/src/components/TitleSlide.tsx` - spring scale-in, centered company name
- `packages/content-renderer/src/compositions/index.ts` - UI-safe sub-export (no bundler/renderer)
- `packages/content-renderer/src/index.ts` - getBundlePath (cached), renderPresentationComposition (concurrency:1, outputLocation:null for Buffer)
- `packages/shared/src/constants.ts` - Added content_job.progress to LIVE_EVENT_TYPES
- `server/src/services/renderers/types.ts` - Added PresentationBundle interface and to ContentBundle union
- `server/src/services/content-job-runner.ts` - Added presentation case, optional companyId/jobId params, updated runJob call site
- `server/src/services/renderers/presentation-renderer.ts` - Stub renderer for tsc module resolution (plan 02 implements)
## Decisions Made
- `content-renderer` uses `"module": "CommonJS"` (no `"type": "module"` in package.json) — Remotion's rspack bundler requires CommonJS resolution internally
- `getBundlePath` caches the bundle path at module level; `bundle()` is called once at startup and reused per render request
- `compositions/index.ts` is strictly UI-safe — imports only from `remotion`, never from `@remotion/bundler` or `@remotion/renderer`
- `renderMedia` called with `outputLocation: null` so `RenderMediaResult.buffer` is populated as `Buffer | null` (non-null on success)
- `renderContent` signature extended with optional `companyId` and `jobId` to enable SSE progress events in the presentation renderer
- Stub `presentation-renderer.ts` throws "not yet implemented" — satisfies tsc module resolution without breaking existing build
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 2 - Missing Critical] Added presentation-renderer.ts stub**
- **Found during:** Task 2 (content-job-runner wiring)
- **Issue:** content-job-runner dynamically imports `./renderers/presentation-renderer.js` — TypeScript module resolution requires the source file to exist at compile time
- **Fix:** Created stub `presentation-renderer.ts` that exports `renderPresentation` throwing "not yet implemented" — identical pattern used for all renderer stubs in phases 41-43
- **Files modified:** `server/src/services/renderers/presentation-renderer.ts`
- **Verification:** Server tsc --noEmit passes with no errors
- **Committed in:** `a0365020` (Task 2 commit)
---
**Total deviations:** 1 auto-fixed (1 missing critical — tsc module resolution)
**Impact on plan:** Stub is required for correct TypeScript compilation. No scope creep.
## Issues Encountered
None - plan executed as specified.
## Known Stubs
- `server/src/services/renderers/presentation-renderer.ts``renderPresentation` throws "not yet implemented". Phase 44 plan 02 replaces with real Remotion render pipeline.
## Next Phase Readiness
- packages/content-renderer is linked workspace package, all Remotion deps installed
- Root.tsx, compositions, and index.ts are ready for plan 02 server renderer to use getBundlePath and renderPresentationComposition
- PresentationBundle type is defined and in ContentBundle union — plan 03 UI can consume it
- content_job.progress is a valid LiveEventType — plan 02 can publish SSE progress events
- presentation case in content-job-runner dispatches to plan 02 renderer stub
---
*Phase: 44-video-presentations*
*Completed: 2026-04-04*