Atlas Plan
Plans006 2026 02 20 Present Service

Phase 1: Package Scaffold + Adapter Interface

  • Purpose: Create the workspace package and define the PresentAdapter contract

T-001 - Scaffold @services/present package

Create package.json, tsconfig.json, eslint.config.mjs for @services/present.

  • Status: pending
  • Priority: P0
  • Dependencies: none

Acceptance

  • @services/present/package.json with name @services/present, scripts (build/dev/lint/test:type), deps: pptxgenjs, @packages/format (workspace:*)
  • @services/present/tsconfig.json extending @repo/typescript/lib
  • @services/present/eslint.config.mjs using base() from @repo/lint/base
  • Root package.json catalogs extended with pptxgenjs if not present

Files

  • @services/present/package.json
  • @services/present/tsconfig.json
  • @services/present/eslint.config.mjs

T-002 - Define PresentAdapter interface and output types

Define the PresentAdapter interface, OutputOptions, PresentResult types, and add stub implementations for future adapters.

  • Status: pending
  • Priority: P0
  • Dependencies: T-001

Acceptance

  • PresentAdapter interface: { name: string; render(report: Report, options: OutputOptions): Promise<PresentResult> }
  • OutputOptions: { outputDir: string; filename: string }
  • PresentResult: { pptxPath?: string; pdfPath?: string; }
  • GoogleSlidesAdapter stub: implements PresentAdapter, throws Error('Not implemented')
  • NotebookLMAdapter stub: implements PresentAdapter, throws Error('Not implemented')
  • All exported from @source/adapters/index.ts

Files

  • @services/present/@source/adapters/base.ts
  • @services/present/@source/adapters/google-slides.ts
  • @services/present/@source/adapters/notebooklm.ts
  • @services/present/@source/adapters/index.ts

Phase 2: PptxAdapter

  • Purpose: Implement the pptxgenjs-based PPTX renderer

T-003 - Implement PptxAdapter

The main pptxgenjs adapter. Creates a PptxGenJS instance, calls all slide generators, saves the PPTX file.

  • Status: pending
  • Priority: P0
  • Dependencies: T-002

Acceptance

  • PptxAdapter implements PresentAdapter
  • Creates pptx instance with slide dimensions 13.33" × 7.5" (widescreen)
  • Iterates report units, calls appropriate slide generators in order
  • Saves to options.outputDir/options.filename.pptx
  • Returns PresentResult with pptxPath

Notes

  • Slide order per unit: revenue-comparison → key-comparison → program-progress → school-progress
  • Channel marketing slide comes after all per-unit slides (combined view)

Files

  • @services/present/@source/adapters/pptx.ts

Phase 3: Slide Implementations

  • Purpose: Implement all 6 slide types matching the reference PDF

T-004 - slides/cover.ts

Cover slide: gradient background (dark blue → teal), bold report title, date, and brand logos.

  • Status: pending
  • Priority: P0
  • Dependencies: T-003

Acceptance

  • Background: gradient fill from #0d47a1 to #006064 (left to right)
  • Title: "PLAN [MONTH] [YEAR]" in bold white, large font
  • Date line: formatted date in white, smaller font
  • Brand logo placeholders (or actual logo images if available in @services/present/assets/)
  • Matches reference PDF page 1 layout

Files

  • @services/present/@source/slides/cover.ts

T-005 - slides/revenue-comparison.ts

Revenue comparison slide per unit: summary table (last month, last year, all-time best, target, actuals) + bar chart below.

  • Status: pending
  • Priority: P0
  • Dependencies: T-003

Acceptance

  • Slide number badge (e.g. "1") and title "Perbandingan Target Revenue – [Unit]" with unit brand color
  • Summary table: 5 columns (Bulan Sebelumnya, Tahun Sebelumnya, Pencapaian Tertinggi, Target, Realisasi), 2 rows (header + values)
  • Bar chart: 5 bars (Last Month, Last Year, Highest, Target, Current) in unit brand color
  • Realisasi column highlighted in green if met/exceeded target, red if below
  • Matches reference PDF pages 2–3

Files

  • @services/present/@source/slides/revenue-comparison.ts

T-006 - slides/key-comparison.ts

Key comparison slide per unit: table comparing last year, target, actuals, gap%, and status for revenue + student types.

  • Status: pending
  • Priority: P0
  • Dependencies: T-003

Acceptance

  • Slide number badge "2" and title "Komparasi Utama" with unit brand color
  • Table rows: Total Revenue, Total Siswa Baru, Total Siswa Lanjut, Total Siswa Alumni
  • Columns: Parameter, Realisasi [Last Year] (Full), Target [Current Period], Realisasi [Current Period] (Ongoing), Gap to Goal (%), Status
  • Status cell color: Completed=green bg, On Track=light blue bg, Needs Attention=salmon bg
  • Matches reference PDF pages 4–5

Files

  • @services/present/@source/slides/key-comparison.ts

T-007 - slides/program-progress.ts

Program progress slide per unit: per-program table with last year, target, actuals, and status.

  • Status: pending
  • Priority: P0
  • Dependencies: T-003

Acceptance

  • Slide number badge "3" and title "Progres Program" with unit brand color
  • Table rows: one per program (product_name)
  • Columns: Parameter (program name), Realisasi [Last Year], Target [Current Period], Realisasi [Current Period], Status
  • Status cell color coding matching reference PDF
  • Matches reference PDF pages 6–7

Files

  • @services/present/@source/slides/program-progress.ts

T-008 - slides/school-progress.ts

School progress slide per unit: dense matrix table of organizations × years.

  • Status: pending
  • Priority: P0
  • Dependencies: T-003

Acceptance

  • Slide number badge "4" and title "Progres Sekolah" with unit brand color
  • Organizations as rows, years as columns (sorted ascending: 2021, 2022, 2023, 2024, 2025, 2026)
  • Cells with non-zero student count show the count; empty cells show blank
  • Organizations grouped by education level (Perguruan Tinggi, SMA, SMP, SD) with section headers
  • Two marketing channel checkbox columns (KON, DIG) as in reference
  • Highlighted rows (yellow/cyan) for schools active in current year
  • Matches reference PDF pages 8–9

Notes

  • School progress slide is the most complex — the reference shows dense tables with hundreds of rows; may need font size 6–7pt for dense tables

Files

  • @services/present/@source/slides/school-progress.ts

T-009 - slides/channel-marketing.ts

Channel marketing slide: combined across units, showing leads/follow-ups/closings/contribution per channel.

  • Status: pending
  • Priority: P0
  • Dependencies: T-003

Acceptance

  • Slide number badge "5" and title "Progres Channel Marketing"
  • One table per unit on the same slide (or separate slides if more than 2 units)
  • Columns: Channel Marketing, Jml Respon Masuk, Jml Follow Up, Jumlah Siswa (Closing), Kontribusi (%), Status, Strategi
  • Status color coding: High Performer=green, Solid=blue, Potensial=yellow, Needs Improv...=salmon
  • Matches reference PDF page 10

Files

  • @services/present/@source/slides/channel-marketing.ts

Phase 4: Generator + PDF Conversion

  • Purpose: Orchestrate slide order and produce both PPTX and PDF outputs

T-010 - generator.ts — Slide orchestrator

Calls all slide generators in the correct order for each unit, assembles the full deck.

  • Status: pending
  • Priority: P0
  • Dependencies: T-004, T-005, T-006, T-007, T-008, T-009

Acceptance

  • generate(pptx, report, options) function
  • Slide order: cover → for each unit [revenue-comparison, key-comparison, program-progress, school-progress] → channel-marketing
  • Per-unit brand color resolved from unit code: WLC_ENGLISH and WLC_NON_ENGLISH#1565c0, TM#7b1111, others → #1565c0

Files

  • @services/present/@source/generator.ts

T-011 - PDF conversion via LibreOffice CLI

Implement the PDF conversion step that invokes libreoffice --headless --convert-to pdf.

  • Status: pending
  • Priority: P1
  • Dependencies: T-010

Acceptance

  • convertToPdf(pptxPath, outputDir) uses Bun.spawn to run LibreOffice CLI
  • Detects if LibreOffice is not installed and warns rather than hard-fails
  • Returns path to generated PDF file
  • Exported from @source/pdf.ts

Files

  • @services/present/@source/pdf.ts

Phase 5: CLI + Verification

  • Purpose: Wire the CLI and verify end-to-end output

T-012 - index.ts — CLI entry point

Wire the CLI with --report or --entity + --period flags.

  • Status: pending
  • Priority: P0
  • Dependencies: T-010, T-011

Acceptance

  • --report path/to/report.json reads the JSON directly
  • --entity IONS --period 2026-02 calls assembleReport from @packages/format first, then renders
  • --adapter pptx|google-slides|notebooklm (default: pptx)
  • Outputs paths of generated PPTX and PDF files
  • Exits 0 on success

Files

  • @services/present/@source/index.ts

T-013 - Add root scripts and NETWORK.yml entry

Add present script to root package.json and update AGENTS.md.

  • Status: pending
  • Priority: P1
  • Dependencies: T-012

Acceptance

  • Root package.json has "present": "bun run --filter @services/present start" (or equivalent)
  • AGENTS.md commit scopes list includes present
  • AGENTS.md CLI usage updated with present commands

Files

  • package.json
  • AGENTS.md

T-014 - bun install + type-check

Install and verify type-check.

  • Status: pending
  • Priority: P0
  • Dependencies: T-001, T-002, T-003, T-012, T-013

Acceptance

  • bun install completes
  • bun run test:type --filter @services/present passes

Files

  • bun.lock

T-015 - End-to-end verification

Run the CLI against real 2026-02 report.json and verify both output files.

  • Status: pending
  • Priority: P0
  • Dependencies: T-014

Acceptance

  • bun run present --entity IONS --period 2026-02 exits 0
  • output/monthly/2026-02.pptx exists and is a valid PPTX file (>10KB)
  • output/monthly/2026-02.pdf exists (if LibreOffice installed)
  • PPTX contains slides for WLC and TM units with correct colors
  • Revenue comparison slides match data in report.json

On this page