RaymondVerhoef cbce4555ff
Some checks failed
On Pull Request to Main / test (pull_request) Failing after 24s
On Pull Request to Main / publish (pull_request) Has been skipped
On Pull Request to Main / deploy-dev (pull_request) Has been skipped
fix: TeamManager admin rules, close role self-escalation, escalate-only resync (#27)
TeamManager could not manage the roster: updateRule allowed self-update
only and deleteRule was superuser-only. The same self-update rule also
left a privilege escalation open — it did not restrict fields, so any
authenticated user could PATCH their own role to "admin".

- team_members rules (migration 1781000003 + base migration + setup
  script mirror):
    update: (@request.auth.id = id && @request.body.role:isset = false)
            || @request.auth.role = "admin"
    delete: @request.auth.role = "admin"
  Self-service onboarding keeps working (it never touches role); the
  role field is admin-only; deletion is admin-only.
- pb_hooks/team_members.pb.js: the ENTRA_ADMIN_EMAILS resync is now
  escalate-only — it guarantees admin for allow-list members on every
  login but no longer demotes, otherwise every TeamManager promotion
  would revert on the member's next sign-in (ADR-004 amended).
- TeamManager.jsx: info text updated to the new behaviour.

Verified with a two-identity mock-OIDC matrix (11/11): allow-list vs
regular login, self-escalation blocked while onboarding self-update
still works, cross-user update/delete blocked, admin promote/demote/
delete work, promotion survives the member's next login, allow-list
admin stays admin. Regression: #22 matrix 9/9, #24 matrix 8/8, #18
harness 15/15, npm test 112/112, eslint clean.

Closes #27

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 21:01:28 +02:00
fix
2026-05-25 20:51:11 +02:00

Respellion Learning Platform

An internal AI-powered learning platform that keeps Respellion employees up to date with the company's evolving knowledge base.

Features

  • Onboarding — On first login each employee enrolls into the curriculum with one tap. Their 26-week cycle starts then and there.
  • Weekly Learning Station — Each employee gets a topic for their current curriculum week, drawn from the active 26-week schedule (with a deterministic hash fallback when no curriculum is active). They engage via micro-learnings (concept explainer, scenario quiz, flashcard set) and can also generate long-form formats (Article, Slides, Infographic) on demand.
  • Weekly Test — A 5-question AI-generated quiz for the week's topic. Results feed the leaderboard.
  • Leaderboard & Gamification — Points for correct answers, badges for milestones (First Steps, Veteran, Perfectionist).
  • R42 Chatbot — An always-available AI assistant (Claude) grounded in the knowledge graph via local TF-IDF retrieval. It can propose graph updates that admins approve or reject.
  • Admin Panel — Manage the knowledge graph, upload source files, review/refine generated content, generate the curriculum, and manage the team.

Tech Stack

Layer Technology
Frontend React 19 + Vite 8, React Router 7
Styling Vanilla CSS (custom properties) + Tailwind v4 utilities
Animations Framer Motion
Icons Lucide React
Graph viz D3.js (admin knowledge graph only)
Backend / DB / auth PocketBase (self-hosted, SQLite)
Retrieval Local TF-IDF (no Qdrant, no embeddings API)
AI Anthropic Claude (via Caddy reverse proxy)
Infra Docker + Caddy; Ansible playbooks under infra/

Claude models (by tier): fast = claude-haiku-4-5-20251001, standard = claude-sonnet-4-6, reasoning = claude-opus-4-7.

Getting Started (local dev)

# 1. Install dependencies
npm install

# 2. Start PocketBase
./pocketbase.exe serve

# 3. Bootstrap collections (first run only)
node scripts/setup-pb-collections.mjs

# 4. Start the dev server
npm run dev

Set ANTHROPIC_API_KEY in your environment — the Vite dev server proxies /api/anthropic and injects the key server-side (see vite.config.js). PocketBase migrations in pb_migrations/ apply automatically when the binary starts.

Deployment (Docker)

docker compose up -d

The Caddyfile handles:

  • SPA fallback routing
  • /api/anthropic/* → Anthropic API (server-side API key injection)
  • /api/* and /_/* → the PocketBase sidecar

Key Files

File Purpose
src/lib/llm.js Core Anthropic wrapper (callLLM): tiers, retry, schema validation, telemetry
src/lib/db.js All PocketBase data access
src/lib/extractionPipeline.js Uploaded file → knowledge-graph extraction
src/lib/learningService.js On-demand content generation (article / slides / infographic)
src/lib/microLearningService.js Micro-learning generation (3 types)
src/lib/curriculumService.js 26-week per-user curriculum engine
src/lib/retrieval.js TF-IDF retrieval for R42
src/store/AppContext.jsx Global state; derives the user's curriculum week from their start date
AI_AGENT.md Detailed context guide for AI coding agents

Content Types

On-demand long-form content (the content collection), generated per type and merged into the cached object:

Type Key in DB Description
Article content.article Long-form reading
Slides content.slides Slide deck with speaker notes
Infographic content.infographic Visual summary with stats and steps

The podcast type was removed. Do not re-add it.

Micro-learnings (the micro_learnings collection): concept_explainer, scenario_quiz, flashcard_set.

Documentation

  • CLAUDE.md — project overview and constraints for AI coding agents.
  • AI_AGENT.md — full architectural guide (patterns, gotchas, decisions).
  • docs/ — subsystem specs (architecture, data model, ingestion, generation, curriculum, R42, frontend, gamification).
Description
No description provided
Readme 95 MiB
Languages
JavaScript 95.6%
TypeScript 3.6%
CSS 0.8%