1
stars
5,670
commits
JavaScript
primary language
Sep 11, 2026
updated
APML v14.0: Course Builder Consolidation
Course production dashboard for SSi language learning system. Content lives in Supabase, audio files in S3.
v14.0 Features:
npm install
cp .env.example .env # Configure environment variables
npm run dev # Frontend (port 5173)
# .env
SUPABASE_URL=https://xxxxx.supabase.co
SUPABASE_SERVICE_KEY=sb_secret_xxxxx
# AWS S3 (for course files and audio storage)
AWS_ACCESS_KEY_ID=xxxxx
AWS_SECRET_ACCESS_KEY=xxxxx
AWS_REGION=eu-west-1
┌─────────────────────────────────────────────────────────────────┐
│ v14 COURSE PRODUCTION PIPELINE │
└─────────────────────────────────────────────────────────────────┘
Content Creation: Course Builder API (Port 3471)
────────────────────────────────────────────────
Agent reads brief → POST /api/seed/complete for each seed → Supabase
┌──────────────────────────────────────┐
│ For each seed: │
│ 1. Translate seed to target lang │
│ 2. Decompose into LEGOs (peda- │
│ gogical order, not sentence) │
│ 3. Generate practice phrases │
│ 4. POST to /api/seed/complete │
│ │
│ API validates atomically: │
│ - Tiling (seed = LEGO assembly) │
│ - ZUT conflicts │
│ - Vocabulary constraints │
│ - Phrase progression │
└──────────────────────────────────────┘
↓
Supabase (course_seeds, course_legos, course_practice_phrases)
Audio Generation: Phase 8 (Port 3465)
─────────────────────────────────────
Supabase content → TTS generation → S3 upload → course_audio table
Manifest Compilation: Phase 9 (Port 3466)
─────────────────────────────────────────
course_audio → 100% coverage check → course_manifest.json
S3 (ssi-audio-stage)
└── courses/{course_code}/
├── lego_pairs.json (Phase 2 output - SSoT)
├── lego_baskets.json (Phase 3 output - SSoT)
└── course_manifest.json (Phase 9 output)
S3 (ssiborg-assets)
└── mastered/{uuid}.mp3 (all audio files)
Tables:
├── voices # TTS and human voice registry
├── audio_samples # Master Audio Registry (MAR)
├── course_audio_usage # Which courses use which audio
├── sample_flags # QA workflow state
├── recording_provenance # Human recording metadata
└── courses # Course configuration
| Service | Port | Description |
|---|---|---|
| Course Builder | 3471 | Content creation (replaces Phase 1-3) |
| Audio Generator | 3465 | TTS generation → Supabase + S3 |
| Manifest Compiler | 3466 | Compile manifest from Supabase |
| Production API | 3470 | QA workflow + WebSocket |
| Orchestrator | 3456 | Proxy hub for all services |
Course Builder handles:
Deprecated (v13): Phase 1 (3457), Phase 2 (3458), Phase 3 (3459)
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/courses | List all courses (from S3) |
| GET | /api/courses/:code/files/:filename | Get course file (proxy to S3) |
| POST | /api/courses/:code/outputs | Save phase outputs to S3 |
| Method | Endpoint | Description |
|---|---|---|
| POST | /generate | Start audio generation |
| GET | /status/:courseCode | Check job status |
| GET | /health | Health check |
| Method | Endpoint | Description |
|---|---|---|
| POST | /compile | Compile manifest from Supabase |
| GET | /validate/:courseCode | Validate audio coverage |
| GET | /health | Health check |
PM2 is gone (2026-07-30 to 2026-08-07 migration, docs/DECISIONS.md "orchestrator off pm2, onto
systemd" — ecosystem.config.cjs no longer exists and pm2 manages nothing). Services run as
per-user systemd units, prefixed popty-, watched by a cron watchdog:
systemctl --user list-units 'popty-*'
systemctl --user status popty-orchestrator.service
| Service | Port | Description | Status |
|---|---|---|---|
| orchestrator | 3456 | Main proxy hub | Active |
| course-builder | 3471 | Content creation API | Active |
| phase8-audio | 3465 | Audio generation (Supabase) | Active |
| phase9-manifest | 3466 | Manifest compilation (Supabase) | Active |
| production-api | 3470 | QA workflow + WebSocket | Active |
| Deprecated | |||
| Deprecated | |||
| Deprecated |
npm run build
vercel --prod
| Data | Owner | Location |
|---|---|---|
| Seeds | Course Builder | Supabase: course_seeds |
| LEGOs | Course Builder | Supabase: course_legos |
| Phrases | Course Builder | Supabase: course_practice_phrases |
| Audio metadata | Phase 8 | Supabase: course_audio |
| Audio files | Phase 8 | S3: mastered/{uuid}.mp3 |
| Manifest | Phase 9 | S3: courses/{code}/course_manifest.json |
| QA flags | Production API | Supabase: sample_flags |
Deprecated (JSON files): lego_pairs.json, lego_baskets.json - data now in Supabase
Version: 14.0.0 APML: v14.0 (Course Builder Consolidation) Pipeline: v3.0 (Course Builder + Supabase) S3 Bucket: ssi-audio-stage (eu-west-1) Date: 2026-01-15
JavaScript
76.4%
Vue
18.2%
HTML
1.7%
TypeScript
1.6%
1
stars
5,670
commits
JavaScript
primary language
Sep 11, 2026
updated
APML v14.0: Course Builder Consolidation
Course production dashboard for SSi language learning system. Content lives in Supabase, audio files in S3.
v14.0 Features:
npm install
cp .env.example .env # Configure environment variables
npm run dev # Frontend (port 5173)
# .env
SUPABASE_URL=https://xxxxx.supabase.co
SUPABASE_SERVICE_KEY=sb_secret_xxxxx
# AWS S3 (for course files and audio storage)
AWS_ACCESS_KEY_ID=xxxxx
AWS_SECRET_ACCESS_KEY=xxxxx
AWS_REGION=eu-west-1
┌─────────────────────────────────────────────────────────────────┐
│ v14 COURSE PRODUCTION PIPELINE │
└─────────────────────────────────────────────────────────────────┘
Content Creation: Course Builder API (Port 3471)
────────────────────────────────────────────────
Agent reads brief → POST /api/seed/complete for each seed → Supabase
┌──────────────────────────────────────┐
│ For each seed: │
│ 1. Translate seed to target lang │
│ 2. Decompose into LEGOs (peda- │
│ gogical order, not sentence) │
│ 3. Generate practice phrases │
│ 4. POST to /api/seed/complete │
│ │
│ API validates atomically: │
│ - Tiling (seed = LEGO assembly) │
│ - ZUT conflicts │
│ - Vocabulary constraints │
│ - Phrase progression │
└──────────────────────────────────────┘
↓
Supabase (course_seeds, course_legos, course_practice_phrases)
Audio Generation: Phase 8 (Port 3465)
─────────────────────────────────────
Supabase content → TTS generation → S3 upload → course_audio table
Manifest Compilation: Phase 9 (Port 3466)
─────────────────────────────────────────
course_audio → 100% coverage check → course_manifest.json
S3 (ssi-audio-stage)
└── courses/{course_code}/
├── lego_pairs.json (Phase 2 output - SSoT)
├── lego_baskets.json (Phase 3 output - SSoT)
└── course_manifest.json (Phase 9 output)
S3 (ssiborg-assets)
└── mastered/{uuid}.mp3 (all audio files)
Tables:
├── voices # TTS and human voice registry
├── audio_samples # Master Audio Registry (MAR)
├── course_audio_usage # Which courses use which audio
├── sample_flags # QA workflow state
├── recording_provenance # Human recording metadata
└── courses # Course configuration
| Service | Port | Description |
|---|---|---|
| Course Builder | 3471 | Content creation (replaces Phase 1-3) |
| Audio Generator | 3465 | TTS generation → Supabase + S3 |
| Manifest Compiler | 3466 | Compile manifest from Supabase |
| Production API | 3470 | QA workflow + WebSocket |
| Orchestrator | 3456 | Proxy hub for all services |
Course Builder handles:
Deprecated (v13): Phase 1 (3457), Phase 2 (3458), Phase 3 (3459)
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/courses | List all courses (from S3) |
| GET | /api/courses/:code/files/:filename | Get course file (proxy to S3) |
| POST | /api/courses/:code/outputs | Save phase outputs to S3 |
| Method | Endpoint | Description |
|---|---|---|
| POST | /generate | Start audio generation |
| GET | /status/:courseCode | Check job status |
| GET | /health | Health check |
| Method | Endpoint | Description |
|---|---|---|
| POST | /compile | Compile manifest from Supabase |
| GET | /validate/:courseCode | Validate audio coverage |
| GET | /health | Health check |
PM2 is gone (2026-07-30 to 2026-08-07 migration, docs/DECISIONS.md "orchestrator off pm2, onto
systemd" — ecosystem.config.cjs no longer exists and pm2 manages nothing). Services run as
per-user systemd units, prefixed popty-, watched by a cron watchdog:
systemctl --user list-units 'popty-*'
systemctl --user status popty-orchestrator.service
| Service | Port | Description | Status |
|---|---|---|---|
| orchestrator | 3456 | Main proxy hub | Active |
| course-builder | 3471 | Content creation API | Active |
| phase8-audio | 3465 | Audio generation (Supabase) | Active |
| phase9-manifest | 3466 | Manifest compilation (Supabase) | Active |
| production-api | 3470 | QA workflow + WebSocket | Active |
| Deprecated | |||
| Deprecated | |||
| Deprecated |
npm run build
vercel --prod
| Data | Owner | Location |
|---|---|---|
| Seeds | Course Builder | Supabase: course_seeds |
| LEGOs | Course Builder | Supabase: course_legos |
| Phrases | Course Builder | Supabase: course_practice_phrases |
| Audio metadata | Phase 8 | Supabase: course_audio |
| Audio files | Phase 8 | S3: mastered/{uuid}.mp3 |
| Manifest | Phase 9 | S3: courses/{code}/course_manifest.json |
| QA flags | Production API | Supabase: sample_flags |
Deprecated (JSON files): lego_pairs.json, lego_baskets.json - data now in Supabase
Version: 14.0.0 APML: v14.0 (Course Builder Consolidation) Pipeline: v3.0 (Course Builder + Supabase) S3 Bucket: ssi-audio-stage (eu-west-1) Date: 2026-01-15
JavaScript
76.4%
Vue
18.2%
HTML
1.7%
TypeScript
1.6%