# Handover: Respellion Learning Platform

## Purpose of this document

This document captures the **design decisions as actually built**. The platform
diverged substantially from its original design vision (a Next.js multi-service
system with Qdrant and OpenAI embeddings). This handover reflects what shipped:
a React/Vite SPA on PocketBase with local TF-IDF retrieval.

When sources conflict, trust the code in `src/` first, then this document, then
`docs/data-model.md` (schema), then `docs/architecture.md`.

---

## What this application does

Employees use the platform to build and maintain knowledge of the company's
internal handbook, roles, and processes.

Core mechanics:
- Admins upload source documents → Claude extracts a structured knowledge graph (topics + relations)
- AI generates learning content and micro-learnings per topic
- Each employee follows a 26-week curriculum, **starting whenever they enroll**
- Each week presents an assigned topic; the employee completes micro-learnings and a test
- After week 26 the cycle restarts at week 1 with the same content
- R42, an AI assistant, answers KB-grounded questions on every screen
- A gamification layer (points, badges, leaderboard) motivates completion

---

## Key decisions as built

### Architecture
- **Single-page React app, not microservices.** All logic runs in the browser
  (`src/`). PocketBase is the only backend; the Anthropic API is reached through a
  reverse proxy (Caddy in prod, Vite in dev). The original `app/` Next.js scaffold
  was abandoned and is not deployed.
- **PocketBase for everything stateful** — auth, structured data, file storage.
  SQLite is sufficient at this scale.
- **No vector database.** Retrieval is a dependency-free TF-IDF index over the
  knowledge graph (`src/lib/retrieval.js`). Qdrant and the embedding service from
  the original design were never built.

### Knowledge base
- **Extracted, not hand-authored.** Admins upload `.txt` / `.md` (≤5 MB). Claude
  (standard tier) extracts topics and relations chunk by chunk.
- **Flat graph, not a Theme→Topic tree.** The KB is `topics` + `relations`. A
  topic's `theme` is a string used for curriculum grouping, not a separate entity.
- **Relation types:** `related_to`, `depends_on`, `part_of`, `executed_by`.
- **Topic relevance** (`core` / `standard` / `peripheral` / `exclude`) controls
  what enters learning/curriculum; `relevance_locked` protects admin overrides on
  re-ingestion.

### Learning content
- **Long-form content is generated on demand**, three types: `article`, `slides`,
  `infographic` (the `content` collection). New types shallow-merge into the cached
  object. **No podcast type.**
- **Micro-learnings**, three types: `concept_explainer`, `scenario_quiz`,
  `flashcard_set` (the `micro_learnings` collection). A former `reflection_prompt`
  type was dropped.
- **Employee chooses the format** per topic per session. Completion is not
  quality-gated; engaging with the full micro-learning counts.

### Curriculum
- **AI generates, admin confirms.** Claude proposes a 26-week schedule from the
  themed/weighted topic set; the admin previews and activates it. Versions move
  `draft → active → superseded`; exactly one is active.
- **Per-user, self-paced start (current behavior).** Each employee enrolls on first
  login; their week/cycle is derived from `curriculum_started_at`. There is **no
  shared calendar week**. Week 1 is the first 7 days after they enroll.
- **Perpetual, repeating cycles.** After week 26, the cycle restarts at week 1 with
  the same content. Completion history (`micro_learning_completions`) is append-only.
- **Hash fallback.** If no curriculum version is active, topic assignment falls back
  to a deterministic hash of user id + week. Keep this fallback.

### R42 chatbot
- **KB-grounded via TF-IDF**, not vector search. Context = top-K topics + verbatim
  mentions + filtered relations + limited deep content.
- **Conversation persists per user** in `localStorage` (cap 50 messages; ~12 turns
  sent to the API). It is not stored server-side.
- **Can propose graph edits** (`propose_graph_delta`, ≤3 topics / ≤5 relations).
  Admins apply immediately; non-admins queue a suggestion for admin approval.
- **Hidden during quizzes** to protect test integrity.

### Gamification
- **Points:** +2 per correct quiz answer, in the `leaderboard` collection.
- **Badges** computed at render time: First Steps (1 test), Veteran (5 tests),
  Perfectionist (a 100% score).
- Admins are excluded from the public leaderboard.

### Auth & infrastructure
- **PIN auth** against `team_members`; the session id lives in `sessionStorage`.
  Role `admin` unlocks the Admin panel.
- **Claude model tiers:** `fast` = Haiku 4.5, `standard` = Sonnet 4.6,
  `reasoning` = Opus 4.7. Admins can override per tier from Settings.
- **Simulation mode** (`admin:use_simulation`) returns stub LLM output for UI work.
- **Deploy:** Docker image (Caddy serving the built SPA) + PocketBase container;
  Ansible playbooks under `infra/` for dev and prod.

---

## Notable divergences from the original vision

| Original design (not built) | What shipped |
|---|---|
| Next.js 14 PWA + 6 Fastify services | Single React/Vite SPA, no backend services |
| Qdrant + OpenAI embeddings | Local TF-IDF, no embeddings |
| Theme/Topic entity hierarchy, batch approval | Flat `topics` + `relations` graph |
| 10 micro-learning types | 3 micro-learning types |
| `employee_curriculum_state`, `badges`, `milestone_cards`, etc. | `team_members` fields + `leaderboard` + render-time badges |
| Shared calendar-week curriculum | Per-user start, self-paced |

The abandoned scaffolding for the original design still exists under `/app` — it is
not part of the running system.
