# TODO — advmfr-gui

Sovereign local AI assistant (CRM & RAG) for the agency. Status board for the work in progress.
Language: English by default (single language for now). See `docs/brief.md` for the vision and
`docs/superpowers/specs/` for per-iteration design specs.

Last updated: 2026-06-29 (Iteration 2 e2e validated — email drafting from Zammad)

---

## ✅ Done

### Infra & repo
- [x] Git repo + private GitHub `bastienallain/advmfr-gui` (`main` = prod, `dev` = integration).
- [x] Dev stack runs on **Colima** (not Docker Desktop), managed by Compose (`test/dev/mac-mini/`).
- [x] Open WebUI **config-as-code** hardening: branding, signup off, role `pending`,
      community sharing off, dev cookies, secrets via `.env`/`env_file`.
- [x] Migrated the manual `docker run` Open WebUI → Compose-managed, data preserved
      (old volume `open-webui` kept as backup).
- [x] Models limited to **`claude-sonnet-4-6`** + **`claude-haiku-4-5-20251001`** only (Anthropic
      via OpenAI-compatible endpoint).

### Iteration 1 — Email Drafting Assistant (read-only)
Spec: `docs/superpowers/specs/2026-06-29-email-drafting-assistant-design.md`
- [x] Design brainstormed + spec written/committed.
- [x] Fake Postgres DB shaped like Zammad (`crm.organizations/users/tickets/ticket_articles`),
      English seed (4 orgs / 10 users / 10 tickets / 26 article threads). Applied to `postgres_vector`.
- [x] **Read-only enforced at DB layer**: role `owui_reader` = SELECT only (INSERT rejected — proven).
- [x] Tool `tools/crm_reader.py` (find_customer / get_customer_context / get_ticket_thread),
      parameterized, no secret leak. Smoke test **5/5** against the DB.
- [x] Tool imported into Open WebUI + Valves DSN/password set.
- [x] Model "Email Drafting Assistant": base model `claude-sonnet-4-6`, system prompt,
      CRM Reader tool enabled, **Function Calling = Native** (required for tool chaining).
- [x] Deliverables committed on branch `feature/email-drafting-assistant`
      (compose mounts `db/` into `/docker-entrypoint-initdb.d`; `.env.example`, `README.md`).
- [x] **End-to-end test passed** — *"Draft a reply to emily.carter@…"* → chained
      `find_customer → get_customer_context → get_ticket_thread`, drafted a grounded reply
      (real order #INV-4821, signed as the ticket's agent, no invented ETA). Unknown customer
      (`john.doe@nonexistent-corp.com`) → reported nothing found, refused to invent.

- [x] Merged `feature/email-drafting-assistant` → `dev` (fast-forward); branch deleted.

### Iteration 2 — Email drafting from Zammad (read-only, no CRM)
Spec: `docs/superpowers/specs/2026-06-29-zammad-email-drafting-design.md`
Scope change: Zammad is now used **only to retrieve emails**; client data moves to a separate DB
(not built yet). Assistant **drafts only** (no classification/routing).
- [x] Design brainstormed + spec written/committed.
- [x] `tools/mail_reader.py` — read-only Zammad REST client (GET only): `list_recent_emails`,
      `get_email_thread`. Token via Valve, no write verbs, number→id resolution.
- [x] `seed/seed_zammad.py` — one-shot dev seeder (admin token via env), 3 orgs / 5 customers /
      8 inbound jewelry emails. Idempotent. Seeded the live (empty) Zammad.
- [x] Revised system prompt (no CRM grounding, `[placeholder]` for absent client facts, domain
      context) + `tools/test_mail_reader.py`.
- [x] Wired in Open WebUI: Mail Reader tool imported + token Valve set; Model swapped CRM→Mail Reader.
- [x] **End-to-end test passed** — *"List the recent emails"* → 8 seeded emails; *"Draft a reply to
      the reorder email (ticket 86019)"* → read the real thread (SKU NW-1182, 50 pcs, DAP New York)
      and drafted a grounded reply with `[placeholder]` for price/date/lead-time.

---

## 🔜 Next

- [ ] Merge `feature/zammad-email-drafting` → `dev` (fast-forward).
- [ ] Optional: delete the backup volume `open-webui` (`docker volume rm open-webui`) once confident.

---

## 🗺️ Future iterations (out of current scope)

Each gets its own spec → plan → implementation:
- [ ] **Separate client-side DB** (orders, prices, project status) + its read tool, composed with
      `mail_reader` (email) — `crm_reader.py` + `db/` are kept as the starting point for this.
- [ ] **Classification & routing** of incoming emails into the sheet's types (Reorder → Data →
      Costing/PI → Marketing; "prepare photos" → PD; etc.) and the daily metal/silver-rate feed.
- [ ] **RBAC — 7 departments** (Quote, Sales, CAD, Logistics, Accounting, After-sales, Triage) as
      Open WebUI groups + per-department Model/Folder/Tool.
- [ ] **Write operations** (send/reply through Zammad) where the access matrix allows.
- [ ] **Ollama engine** for sovereignty (tool-capable local model; switch each Model's base model).
      Required before any real client data touches the system.
- [ ] **pgvector RAG** folders per department (meeting notes, unstructured docs).

---

## ⚠️ Sovereignty reminder
Claude API is a **dev crutch only**, used with the **fake** database. No real client data may transit
an external API. Switch the data-facing assistants to **Ollama local** before going live.
