Atlas Plan
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 @config workspace package with shared entity, unit, and brand definitions
  • Create @services/slides as 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 .md templates (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 — @config package, @services/slides scaffold, 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/present constants
  • Phase 7: Export & Finalize — PDF/PPTX export, architecture doc updates

Success

  • @config package exists and exports entity/unit/brand types
  • pnpm slides -- dev --entity IONS --period 2026-02 starts 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-02 produces a PDF
  • @services/present still 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-chromium for 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.
  • @config must be framework-agnostic (plain TypeScript, no Vue/React imports) so both services can consume it.
  • Report data shape comes from @packages/pipeline Report type — slides must adapt to this structure, not define their own.
  • Port prefix 15xxx per 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/present for PPTX if insufficient.
  • Adding ~200MB to node_modules (Playwright + Slidev) — acceptable given shamefullyHoist: true deduplication.
  • Components duplicated between @services/present and @services/slides initially — will converge formatting logic into @config in Phase 6.

Skills

  • slidev — Slidev syntax, layouts, components, export, configuration
  • unocss — UnoCSS config for fonts, shortcuts, brand tokens (isolated to slides service)
  • hono — Not needed directly, but Vite config patterns apply
  • turborepo — 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 @config framework-agnostic (no Vue/React imports)
  • Ask first: Modifying @services/present code (Phase 6 migration)
  • Ask first: Modifying @plan/architecture.md
  • Never: Import Vue components from @services/slides into 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 @config also export pipeline-related constants (e.g., sheet mappings)? (Deferred)

On this page