Three channels, one orchestrator
Board Game Librarian runs on 20 PM2 processes. All three user-facing channels -- Telegram bot, web chat, and partner widget -- route through a single orchestrator service. That is where the Q&A logic lives.
The orchestrator is the critical path. If it goes down, all three channels stop answering questions. Everything else can be degraded without a total outage.
The 20 services
Critical (must run)
| Service | Port | Role |
|---|
| rules-orchestrator | 3460 | Q&A pipeline, AI synthesis |
| telegram-bot | 3461 | Telegram webhook handler |
| web-frontend | 3474 | Next.js: chat, admin, marketing |
| game-library-api | 3459 | Game catalog, user management |
| embedding-api | 3462 | Vector generation (Python/Flask) |
Supporting (degraded without)
| Service | Port | Role |
|---|
| pdf-api | 3457 | PDF extraction (Apache Tika) |
| crawlee-api | 3456 | BGG forum scraping |
| redis-cache-api | 3463 | Game data cache |
| game-data-sync | 3471 | Nightly BGG metadata sync |
| corpus-analyzer | 3481 | Query expansion, intent detection |
Publisher sync (scheduled)
| Service | Port | Schedule |
|---|
| eog-sync | 3466 | Daily 03:30 |
| gmt-sync | 3470 | Daily 03:31 |
| stonemaier-sync | 3469 | Daily 03:32 |
| tabletopia-sync | 3464 | Daily + weekly |
| ludus-magnus-sync | 3473 | Weekly Sun 01:00 |
Technology stack
| Layer | Technology |
|---|
| Database | PostgreSQL 16 + pgvector extension |
| Vector indexing | HNSW (approximate nearest neighbor) |
| AI synthesis | OpenRouter -> GPT-4o / Claude |
| Embeddings | jina-v2-small-en (768-dim, Python) |
| Web framework | Next.js 15 (App Router) |
| Backend APIs | Express 4.x (Node.js) |
| Cache | Redis 7 |
| Process manager | PM2 |
| Observability | Jaeger + Phoenix + OpenTelemetry |