Plans010 2026 02 22 Slides Service
Slides Service
Overview
Add a Slidev-based report presentation service (@services/slides) to replace the styling limitations of pptxgenjs. Uses the single-project + picker pattern (like ~/Code/studio) with data-driven Vue components that render Report JSON into styled slides. Introduces a root @config package for shared entity/brand definitions consumed across services.
The current @services/present (pptxgenjs) produces functional but hard-to-style PPTX reports. Slidev provides full CSS/Vue control over slide design, exports to PDF/PPTX/Web, and enables rapid design iteration via hot-reload dev server.
Goals
- Create
@configworkspace package with shared entity, unit, and brand definitions - Create
@services/slidesas a Slidev project with custom layouts, components, and data integration - Build reusable Vue components (DataTable, BarChart, KpiCard, StatusBadge, BrandLogo) for data-driven slides
- Port all 5 report slide types as reusable
.mdtemplates (cover, revenue, key comparison, program progress, school progress, channel marketing) - Build CLI with interactive picker for dev/export/build workflows
- Support per-entity/unit branding (colors, logos, fonts) via
@config - Export to PDF (Playwright) and PPTX (slidev-addon-pptx)
- Coexist alongside
@services/present(not replace it)
Non-Goals
- Replacing
@services/present— both services coexist - Reusing deck styling from
~/Code/studio— new styling for this repo - Building a formal Slidev theme package — start with single project, extract later if needed
- Dashboard integration — slides are standalone, not embedded in
@services/dashboard - Automated pipeline trigger — manual CLI invocation for now
Phases
- Phase 1: Infrastructure —
@configpackage,@services/slidesscaffold, monorepo config updates - Phase 2: Layouts & Styles — Custom Slidev layouts and base CSS
- Phase 3: Data Components — Vue composables and data-rendering components
- Phase 4: Report Templates — Port all 5 slide types as reusable markdown templates
- Phase 5: CLI & Picker — CLI entry point with new/dev/export/build commands + interactive picker
- Phase 6: Brand System — Per-entity themes in
@config, migrate@services/presentconstants - Phase 7: Export & Finalize — PDF/PPTX export, architecture doc updates
Success
-
@configpackage exists and exports entity/unit/brand types -
pnpm slides -- dev --entity IONS --period 2026-02starts a working Slidev dev server - All 5 report slide types render with real Report JSON data
- Per-entity branding works (IONS blue, TM red overrides)
-
pnpm slides -- export --entity IONS --period 2026-02produces a PDF -
@services/presentstill works unchanged (coexistence) - NETWORK.yml, turbo.json, root package.json updated
Requirements
- Slidev v52+ (
@slidev/cli,@slidev/client,@slidev/theme-default) - UnoCSS (isolated to
@services/slides) playwright-chromiumfor PDF/PPTX export- Report JSON from
@packages/pipeline(format stage output) - LibreOffice not required (Slidev handles PDF natively)
Context
Why This Approach
- pptxgenjs gives no design iteration loop — changes require rebuild + open in PowerPoint to preview. Slidev provides hot-reload in browser.
- The studio repo (
~/Code/studio) is for strategic/creative presentations (proposals, talks). Atlas needs data-driven report presentations — different content, different styling, different repo. - Studio's
@themes/directory is empty after 6+ decks — the single-project pattern is proven to work without premature theme extraction. - Alternative A (theme package + per-report project) was rejected: reports share the same visual identity parameterized by brand config, not fundamentally different designs. Per-report component override is unlikely to be needed.
Key Constraints
- Vue (Slidev) and React (dashboard) coexist in the same monorepo — must be isolated via pnpm workspaces with no cross-imports.
@configmust be framework-agnostic (plain TypeScript, no Vue/React imports) so both services can consume it.- Report data shape comes from
@packages/pipelineReporttype — slides must adapt to this structure, not define their own. - Port prefix
15xxxper NETWORK.yml convention — slides service gets port 15003. catalogMode: strict— all new dependencies must be added to pnpm-workspace.yaml catalogs.
Edge Cases
- Reports with missing units (e.g., entity has WLC + TM but only WLC has data) — templates must handle sparse data gracefully.
- Channel marketing slides stack up to 2 units per slide — need chunking logic.
- School progress matrix has variable year columns (up to 6) — component must be flexible.
- Entity with no brand config yet — should fall back to a default theme.
Tradeoffs
- Accepting PPTX export quality uncertainty — Slidev's PPTX addon is community-maintained. Will try it first, fall back to
@services/presentfor PPTX if insufficient. - Adding ~200MB to
node_modules(Playwright + Slidev) — acceptable givenshamefullyHoist: truededuplication. - Components duplicated between
@services/presentand@services/slidesinitially — will converge formatting logic into@configin Phase 6.
Skills
slidev— Slidev syntax, layouts, components, export, configurationunocss— UnoCSS config for fonts, shortcuts, brand tokens (isolated to slides service)hono— Not needed directly, but Vite config patterns applyturborepo— Task pipeline config for new service
Boundaries
- Always: Follow existing monorepo conventions (
@source/for source,build/for output,catalog:for deps) - Always: Update NETWORK.yml when assigning ports
- Always: Add new dependencies to pnpm-workspace.yaml catalogs (strict mode)
- Always: Keep
@configframework-agnostic (no Vue/React imports) - Ask first: Modifying
@services/presentcode (Phase 6 migration) - Ask first: Modifying
@plan/architecture.md - Never: Import Vue components from
@services/slidesinto React services - Never: Add Slidev dependencies to root
package.json— they belong in@services/slides/@source/package.json
Questions
- Should Slidev replace or coexist with
@services/present? → Coexist - 1 project per report or 1 project with picker? → 1 project with picker (Alternative B)
- Theme package or single project? → Single project, extract theme later if needed
- Where should report JSON live? → Inside
@services/slides/@source/reports/ - PPTX export strategy? → Try slidev-addon-pptx first, fall back to
@services/present - How to handle per-entity/unit branding? →
@config/brands/with runtime resolution via composable - What fonts should the Atlas report slides use? (To be decided during Phase 2)
- Should
@configalso export pipeline-related constants (e.g., sheet mappings)? (Deferred)