# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What this project is

`advmfr-gui` is the infrastructure and deployment definition for a **100% sovereign, local AI assistant** (internal CRM + RAG) for an agency. No client data may ever transit external APIs (OpenAI, Anthropic, etc.) — everything runs on-premise. The goal is a ChatGPT-style web UI that lets staff draft/correct client emails while querying project status and billing in natural language.

The full intent is in `docs/brief.md` (French). Read it before making infra decisions.

At this stage the repo contains **only deployment configs (Docker Compose) and planning notes** — there is no application source code, build step, or test suite yet. The "Tools" (Python scripts bridging the LLM to PostgreSQL) described in the brief are not written yet.

## The stack (fixed by the brief — don't substitute without asking)

- **Frontend / orchestration:** Open WebUI (handles UI, system prompts, and execution of Python *Tools*). Served on `localhost:3000` (container port 8080).
- **Inference engine:** Ollama for dev/test; vLLM for production at scale.
- **Database:** PostgreSQL + `pgvector` — single DB holding both structured business data (prices, quotes, project states) and RAG embeddings.
- **Connectivity:** Python *Tools* injected into Open WebUI that bridge the LLM to PostgreSQL (hybrid search: exact SQL + semantic RAG).

## Three deployment phases

The repo is organized as a progression across the three phases in `docs/brief.md`. Each Compose file targets a different phase — know which one you're editing:

| Phase | File | Target | Key traits |
|-------|------|--------|-----------|
| 1 — Dev / prototyping | `test/dev/mac-mini/docker-compose.yaml` | Mac Mini M4, macOS | Ollama runs **natively** (Metal GPU); Open WebUI reaches it via `host.docker.internal:11434`. Open WebUI + pgvector containerized. |
| 2 — Pilot node | `idee/cluster.yaml` | Single GPU server | Ollama **containerized** with `nvidia` GPU reservation (`count: all`); full Open WebUI + pgvector + Ollama stack in one Compose. |
| 3 — Scalable cluster | `test/50-users/docker-compose.yaml` | Multi-user / HA | External Postgres + Redis (websocket manager), Traefik labels for TLS routing, `replicas` for horizontal scale, admin-approval signup. |

Planning notes (not runnable) live in `idee/`: `setup-dev.md` (recommended dev hardware), `cluster-prod.md` (the K8s + Ray + vLLM + Traefik production architecture for scaling 2→20 GPUs with zero downtime).

## Running the stacks

Each Compose file is self-contained. From the directory containing the file:

```bash
# Phase 1 — dev on Mac Mini (Ollama must already run natively: `ollama serve`)
cd test/dev/mac-mini && docker compose up -d

# Phase 2 — single GPU node (Ollama containerized, needs NVIDIA Container Toolkit)
cd idee && docker compose -f cluster.yaml up -d

# Phase 3 — multi-user (needs an external `proxy` Docker network for Traefik)
docker network create proxy   # once, if missing
cd test/50-users && docker compose up -d

docker compose logs -f open-webui   # follow UI logs
docker compose down                 # stop (add -v to also drop volumes/data)
```

## Conventions that matter here

- **`WEBUI_SECRET_KEY` must be identical across all Open WebUI replicas** (Phase 3) or sessions break. Generate with `openssl rand -base64 32`. Placeholder values (`CHANGE`, `dev_secret_key_change_me`, `secretpassword`) are intentional — never commit a real secret.
- Phase 3 sets `DEFAULT_USER_ROLE: pending` — new accounts require admin approval. Keep this when editing that file; it's a deliberate security control.
- Persistent state lives in Docker volumes/bind-mounts (`pg_data`, `open-webui_data`/`owui-data`, `ollama_data`). Dropping them loses the client DB and chat history.
- Phase 1 reaches native Ollama through `host.docker.internal` — this is macOS-specific and must not be copied into the Linux server phases (which talk to Ollama by service name or run vLLM).
