synergi-course

This is a living vision for modernizing the Synergi course framework. It outlines goals, architecture, and migration direction to guide ongoing work. It is not a user guide and the API is subject to change during the migration.

Scope & Non‑Goals

  • Scope: Client‑side course playback (slides, transitions, media sync, quizzes), progress tracking, and backend persistence hooks.

  • Non‑Goals: Course authoring UI, content CMS, SCORM/xAPI packaging, routing/deep‑linking beyond slide index, analytics pipeline.

Target Stack & Removals

  • Target: React 19, Vite, MUI 7, valibot schemas, CSS files co‑located with components.

  • Remove/Replace: react‑redux (move to local state/hooks), legacy remark pipeline usage, ad‑hoc CSS‑in‑JS except small sx/Box tweaks.

Architecture Overview

  • Deck: Orchestrates navigation, transitions between slides, progress and persistence; renders outer slide shell.

  • Slide Types: Manual Slide vs media‑driven (AudioSlide, VideoSlide, VimeoSlide), plus QuizSlide; each manages its own inner transitions. VideoSlide accepts WebVTT subtitle tracks in its slide props.

  • Segment Model: Optional sub‑sections within a slide; only one visible; slide controls segment transitions.

  • Transition Engine: Ordered steps with triggers (manual next/prev or media timecodes), timing guarantees, and view‑transition CSS between slides.

Interfaces & Adapters

  • PersistenceAdapter: load/save progress (e.g., currentSlide, lastUnlockedSlide).

  • MediaSync: map media timecodes to transition triggers; pause/resume hooks.

  • AnalyticsAdapter: emit navigation/interaction events.

  • AssetLoader (optional): resolve media sources and preloading strategy.

State Model

  • Deck State: currentSlide, lastUnlockedSlide, direction, in‑flight slide transition.

  • Slide State: current transition index/segment, local timing; only one active transition at a time.

  • Event Flow: user/media → slide transition → deck (boundary events) → adapters (persistence/analytics).

Schema & Types (directional)

  • Course: { slides: Slide[]; currentSlide: number; lastUnlockedSlide: number }.

  • Slide: discriminated by type ("Slide" | "AudioSlide" | "VideoSlide" | "QuizSlide" | "VimeoSlide"), props, transition, optional children.

  • Component: { type: string; props: Record<string, unknown>; transition: { type: "always" | "transition"; trigger: string }; children? }.

  • Validation: valibot schemas in packages/synergi-course/src/schemas.ts; schema remains flexible during migration.

Accessibility & i18n

  • Keyboard navigation parity for all actions; visible focus management.

  • Media captions/subtitles; ARIA labels for controls.

  • Text content and labels externalizable; RTL‑safe layouts where applicable.

Theming & Styling

  • Public theming via CSS classes/variables; prefer CSS files next to components.

  • Limit inline styling to minor layout tweaks; document stable class hooks as they emerge.

Performance Goals

  • Slide transition budget: ~300ms with CSS view transitions.

  • Media start latency minimized; lazy load off‑screen slides/assets.

  • Avoid unnecessary re‑renders on transition ticks.

Migration Plan (phased)

  1. Replace redux stores with local component state and hooks.

  2. Introduce valibot schemas; adapt slide/component props.

  3. Implement transition engine and view‑transition CSS.

  4. Add media‑driven triggers and segment model.

  5. Wire Persistence/Analytics adapters; stabilize minimal public API.

Open Questions

  • Authoring source of truth: JSON vs JSX (or hybrid)?

  • Deep‑linking and shareable slide state (URL params)?

  • Analytics event schema (naming, payloads, sampling)?

  • Long‑term quiz model and scoring/persistence boundaries?

Last updated

Was this helpful?