# CLAUDE.md

## What you are building

A mobile-first progressive web application for employee learning. Employees follow
a perpetual 26-week curriculum built from an internal knowledge base. An AI
assistant called R42 is available on every screen. Admins upload source documents
that are processed into the knowledge base by AI.

Read the full design before writing any code:
- /docs/handover.md         — all decisions made, rationale, constraints
- /docs/architecture.md     — system design, data flows, tech stack
- /docs/data-model.md       — all PocketBase collections, Qdrant schema, types
- /docs/ingestion-spec.md   — ingestion service (build this first)
- /docs/implementation-plan.md — ordered build sequence with acceptance criteria

---

## Absolute constraints

These rules are non-negotiable and apply to every session:

1. Never modify any file listed in PROTECTED.md
2. Never modify any file outside /app — the pipeline, Dockerfile, ansible,
   and docker-compose files are frozen
3. Never delete files without explicit confirmation
4. Never change package.json scripts that contain 'deploy' or 'build:prod'
5. Ask before acting when scope is unclear — do not infer intent from legacy/ code

---

## Repository structure

```
repo/
  ├── CLAUDE.md                 ← you are here
  ├── PROTECTED.md              ← files you must never touch
  ├── docs/                     ← spec files — read, never modify
  ├── legacy/                   ← old prototype — read-only reference only
  └── app/                      ← your working directory
        ├── frontend/           ← Next.js 14 PWA
        └── services/
              ├── ingestion/    ← build first
              ├── generation/   ← build second
              ├── curriculum/   ← build third
              ├── embedding/    ← integrated into ingestion, separate later
              ├── chat/         ← R42
              └── progress/     ← gamification
```

All work happens inside /app. No exceptions.

---

## Tech stack

| Layer | Technology |
|---|---|
| Frontend | Next.js 14, TypeScript strict, Tailwind CSS, PWA |
| Backend state | PocketBase (binary, not source — do not scaffold from scratch) |
| Vector store | Qdrant via REST client |
| AI generation | Claude Sonnet 4 — model string: claude-sonnet-4-20250514 |
| AI chat (R42) | Claude Haiku 4.5 — model string: claude-haiku-4-5-20251001 |
| Embeddings | OpenAI text-embedding-3-small |
| Services | Node.js, Fastify, TypeScript strict |
| Validation | Zod on all external data (API responses, AI output, PocketBase) |

---

## Stylesheet

An existing stylesheet lives at /stylesheet.css in the repo root. This is the
authoritative visual style for the application.

Rules:
- Never modify stylesheet.css
- Import it as a global stylesheet in the Next.js frontend
- Do not override its rules with Tailwind utility classes or inline styles
- When Tailwind and the stylesheet conflict, the stylesheet wins
- If a UI element is not covered by the stylesheet, use Tailwind — but match
  the visual language (spacing, colour, type scale) of the existing stylesheet

---

## Code conventions

- TypeScript strict mode everywhere — no `any` types
- All Claude API responses validated through Zod before use
- All PocketBase writes typed against collection schemas in data-model.md
- Qdrant payloads explicitly typed — no untyped objects
- No inline hardcoded API keys — environment variables only
- REST conventions for all service APIs
- Mobile-first CSS — design for 375px width, scale up

---

## Build order

Follow /docs/implementation-plan.md exactly.
Do not skip phases. Do not build phase N+1 before phase N passes its
acceptance criteria.

Current phase: **Phase 1 — Infrastructure + ingestion service**

---

## Session discipline

Each session has a defined scope in implementation-plan.md.
At the start of each session:
1. State which phase and step you are working on
2. Read the relevant spec file(s)
3. Propose a file structure or change plan before writing code
4. Implement after the plan is clear

At the end of each session:
1. State what was completed
2. State what acceptance criteria have been met
3. State what the next session should start with

---

## When you are uncertain

Check the spec files in /docs first.
If the spec does not cover it, flag the gap explicitly rather than making
an assumption. Do not look at legacy/ code for implementation guidance —
it is a different stack and will lead you in the wrong direction.

---

## Environment variables

Each service has its own .env file. Templates are defined in each service spec.
Never commit actual values. Always use .env.example with placeholder values.

The full set across all services:
```
ANTHROPIC_API_KEY=
OPENAI_API_KEY=
POCKETBASE_URL=
POCKETBASE_ADMIN_EMAIL=
POCKETBASE_ADMIN_PASSWORD=
QDRANT_URL=
QDRANT_API_KEY=
INGESTION_PORT=3001
GENERATION_PORT=3002
CURRICULUM_PORT=3003
CHAT_PORT=3004
PROGRESS_PORT=3005
NEXT_PUBLIC_API_URL=
NEXT_PUBLIC_POCKETBASE_URL=
```
