diff --git a/docs/ROADMAP-v2.md b/docs/ROADMAP-v2.md index b1f3435..f65d4fb 100644 --- a/docs/ROADMAP-v2.md +++ b/docs/ROADMAP-v2.md @@ -8,7 +8,8 @@ previous round (1.12.0 – 1.23.0). Where to pick up: [HANDOVER.md](./HANDOVER.m **Theme for 2.0:** turn a feature-rich church app into a product that can be sold — trustworthy (POPIA), flexible (multi-day events, several payment -providers), and maintainable (tests, CI, typed backend, versioned API). +providers), maintainable (tests, CI, typed backend, versioned API), and with +**AI helpers** as the headline feature (§15). **Status (2026-10-23):** all features in this document are approved. Shipped so far: 1.32.0 early-bird ribbon on event cards; 1.33.0 multi-day events @@ -48,8 +49,10 @@ notifications. SnapScan and Zapper are dropped — Yoco and PayFast are enough ( 12. [Multi-campus (one install per church)](#12-multi-campus-one-install-per-church) 13. [Central management platform (Hope Events Hub)](#13-central-management-platform-hope-events-hub) 14. [Foundations (platform work)](#14-foundations-platform-work) -15. [Suggested build order](#suggested-build-order) -16. [Decisions](#decisions-2026-10-22) +15. [AI helpers (2.0 headline)](#15-ai-helpers-20-headline) +16. [AI: later stages](#16-ai-later-stages) +17. [Suggested build order](#suggested-build-order) +18. [Decisions](#decisions-2026-10-22) --- @@ -679,7 +682,8 @@ All later calls are signed with the install secret (HMAC) and go over HTTPS. events people already paid for, and get its own data out (POPIA access rights). Suspension blocks *new* activity only. - **One plan for now.** Plan limits (e.g. number of campuses, WhatsApp) can - be carried in the token later. + be carried in the token later. The first per-licence limit comes with 2.0: the + **monthly AI cap in rand** (§15), kept and enforced on the Hub, since the Hub meters AI. ### Things to be aware of @@ -703,6 +707,8 @@ model Install { id, customerId, licenceId, name, url, secretHash, version, model Heartbeat { id, installId, receivedAt, version, health Json, stats Json } // rolled up to daily after 30 days model InstallEvent { id, installId, type, message, createdAt } // alerts, version changes +// 2.0, AI (§15): Licence gets aiMonthlyCapCents; usage per call, no prompt/response text +model AiUsage { id, installId, helper, model, inputTokens, outputTokens, costCents, createdAt } ``` --- @@ -724,6 +730,134 @@ keep adding to. --- +## 15. AI helpers (2.0 headline) + +Small, one-button AI helpers in the places people already work. **No chat** in 2.0: +each helper is one request with a predictable cost, and a person always reviews +the result before anything is saved or sent. + +**Who:** Supervisors and admins (the people who create events and read reports). + +### The helpers + +| Helper | Where | What it does | +|--------|-------|--------------| +| **Draft an event** | Event wizard, first step: "Describe your event" | *"Youth camp 14–16 March at Camp Wartburg, R450, 60 places, kids need consent"* → fills in title, description, dates/sessions, location, ticket options and prices, capacity, consent settings. The supervisor checks every field and saves as usual | +| **Summarise this report** | Every report (Reports page) | A few plain-language insights under the report: trends, outliers, comparisons with the previous period | +| **Draft a message** | Email / WhatsApp attendees, broadcasts | Turns a short note (*"remind them to bring a sleeping bag, bus leaves 7:30"*) into a friendly message in the right tone and length (shorter for WhatsApp), with placeholders like `{{name}}` | +| **Summarise feedback** | Post-event feedback results | Themes, what people liked, what to improve, notable comments | +| **Improve this text** | Event description, banner, message boxes | Rewrite for clarity, fix spelling, shorten | + +Every helper shows **"AI suggestion — check before saving"**, can be undone, and +never saves, sends or publishes by itself. + +### Provider and model + +- **One provider: Claude (Anthropic), model Claude Haiku 5.5** — the cheapest + current model ($0.10 per million input tokens, $0.50 per million output, for + prompts under 100K tokens; prices as of 2026-10). Good enough for drafting and + summarising; a helper can move to a bigger model later if quality needs it. +- **Rough cost:** a helper call is ~2,000–10,000 tokens in and ~500 out, so well under + US$0.002 per click — about R1.50–R3 per thousand clicks. Fixed instructions are + prompt-cached, which makes repeat calls cheaper still. +- Structured output (a JSON schema) for "Draft an event", so the reply maps straight + onto the event form and is validated before it's shown. + +### Key, caps and billing — through the Hub + +Joshua provides the API key; churches don't need their own. The key must never sit on +an install (one leaked install would leak it for everyone), so: + +- **Installs call AI through the Hub:** `POST /api/ai/complete` on the Hub, signed with + the install secret like the heartbeat. The Hub adds the key, calls Claude, and returns + the result. Still **install → Hub only** — the Hub never reaches into an install. +- **The Hub meters every call** in rand: tokens used × the model's price × an exchange rate + Joshua sets in the Hub (with an optional margin). Usage is kept per install per month. +- **Monthly rand cap per licence**, set by Joshua in the Hub to match what the church pays + (e.g. R0 = AI off, R50, R200). The licence's cap is the first per-plan limit. At 80% the + install's admins get a warning email; at 100% the helpers are switched off until the next + month (or until Joshua raises the cap). Optional per-user daily limit against runaway use. +- **Admins see their usage** in Site settings → AI: used this month (R and number of uses), + the cap, a daily chart, use per helper and per person, and an on/off switch per helper. +- If the Hub or Claude is unavailable, the buttons say so; nothing else in the app is affected. + +### POPIA + +- Anthropic is added to the **operator register** (and Joshua's Hub, which relays the + requests) and to the privacy notice: processing outside South Africa (POPIA s72), + for drafting and summarising only. +- **Send as little personal information as possible:** reports and feedback are sent as + counts, totals and anonymised comments — no names, contact details, medical or + children's information. Drafting an event or a message needs none. +- The Hub stores **no prompt or response text** — only the install, helper, tokens, cost + and time. Check Anthropic's commercial terms on retention and training before launch. +- Uses that include personal information (e.g. feedback comments) go in the access log. + +### Plumbing + +- Install: `backend/src/ai/` — one client for the Hub's AI endpoint, one prompt + schema + per helper, usage shown from the Hub. Feature flag per helper, all off when the licence + has no AI or the Hub isn't connected. +- Hub: the AI proxy, metering, caps, warnings, an exchange-rate setting, and a per-install + usage view for Joshua (alongside the existing install detail page). +- A small **eval set** (example event descriptions, reports, notes, with what a good answer + looks like) to check quality when changing the prompt or model. +- Help content, audit log entries (AI settings changed), CHANGELOG, FEATURES.md, SETTINGS.md. + +--- + +## 16. AI: later stages + +Ideas for after 2.0, in rough order. **Not tied to versions** — each is decided when it's +picked up, and all of them reuse the Hub proxy, metering and caps from §15. + +### Ask AI (read-only assistant) + +A chat panel for supervisors and admins: *"How many paid for Camp compared with last +year?"*, *"Which events this month are under half full?"*, *"Who hasn't paid yet for +Men's Breakfast?"*. + +- The AI can only call **tools the app defines** — the existing stats and report queries, + "find an event", "registrations by week" — never its own SQL. It runs with the + logged-in person's permissions, so it sees nothing they couldn't. +- Answers show the numbers they're based on and link to the matching report. +- Costs more per question than a button (several tool calls), so it counts against the same + cap; may need a bigger model for harder questions. + +### Help and navigation assistant + +*"How do I add a coupon?"*, *"Where do I see who checked in?"* → a short answer from the +in-app help content (`frontend/src/content/help/`) with a link straight to the right page. +No personal information involved, so it's cheap and simple — could also be offered to +ordinary users. + +### Actions with confirmation + +The Ask assistant can also *do* things — create an event draft, schedule a reminder, offer +waitlist places, record a cash payment — always as **"here's what I'll do → Confirm"**, with +each confirmed action in the audit log. + +### More helpers + +Smaller one-button additions as they come up: suggest an event's price tiers from past +events, write a post-event thank-you, draft certificate wording, translate a message into +Afrikaans (ties in with §10), flag unusual payments for the cashup. + +### Self-hosted AI (long term) + +Run an open-weight model on Joshua's own GPU server instead of a paid API, once usage and +income justify the hardware: + +- Because every install already talks to the **Hub's** AI endpoint, moving to self-hosting + is a change on the Hub only — the Hub gets a provider adapter (Claude now, self-hosted + later, or both: simple helpers self-hosted, harder questions on Claude). +- **POPIA bonus:** the data can stay in South Africa — no cross-border transfer. +- **When it makes sense:** compare the monthly API bill with the cost of a GPU server + (hardware or cloud rental, power, upkeep), and check the self-hosted model against the + eval set from §15 before switching any helper over. + +--- + ## Suggested build order | Phase | Version | Features | Why | @@ -740,7 +874,7 @@ keep adding to. | 9 | 1.45.0 – 1.47.0 | Event series & cloning, Wallet passes, Outbound webhooks | Smaller, independent wins | | 10 | 1.48.0 – 1.50.0 | Admin dashboard/Ctrl+K/bulk actions, Afrikaans, Accessibility pass | Polish before the big release | | 11 | 1.51.0 | TypeScript backend + OpenAPI + `/api/v2` alongside v1 | The breaking-change groundwork | -| 12 | **2.0.0** | v1 API removed, migration guide, marketing site/docs for selling | The release | +| 12 | **2.0.0** | **AI helpers** (§15 — headline feature: draft an event, summarise reports and feedback, draft messages, improve text; through the Hub with a rand cap per licence), v1 API removed, migration guide, marketing site/docs for selling | The release. AI needs the Hub (phase 6) for the key, metering and caps | Each phase should add matching help content (`frontend/src/content/help/`), audit log entries, Jest tests, a CHANGELOG entry, and updates to FEATURES.md @@ -773,6 +907,10 @@ feature. | — | Grace period / suspension | 14-day grace; suspended = read-only (tickets still scan, data export still works) (2026-10-23) | | — | Income in the heartbeat | Included, as **ranges** only (R0–R1 000, R1 001–R5 000, …), never exact amounts (2026-10-23) | | — | Licence plans | One plan for now (2026-10-23) | +| — | AI in 2.0 | The **headline feature of 2.0**: one-button helpers only (draft an event, summarise reports and feedback, draft messages, improve text) — no chat yet (2026-10-24) | +| — | AI provider and key | One provider, **Claude** (Haiku 5.5 to start, for cost). Joshua provides the key; installs call AI **through the Hub**, which holds the key and meters usage (2026-10-24) | +| — | AI cost limits | A **monthly rand cap per install**, set in the Hub per licence to match what the church pays; admins see their usage in Site settings → AI (2026-10-24) | +| — | AI later | Ask AI (read-only, tools only), help/navigation assistant, actions with confirmation, more helpers, and long-term **self-hosted** AI behind the same Hub endpoint — not tied to versions (2026-10-24) | | — | POPIA: message kinds | Bulk messages are either **Event updates** (to registrants — still sent after unsubscribing) or **News & announcements** (marketing — opt-in, one-click unsubscribe). Every bulk email links to the preferences (2026-10-23) | | — | POPIA: existing users | Kept opted in to news (logged as "existing account"), asked once at their next login to confirm or opt out. New sign-ups choose with an unticked box (2026-10-23) | | — | POPIA: deleting an account | A request: the account is deactivated at once, personal info is anonymised when an admin approves. Waits while the person has an open registration for an upcoming event (2026-10-23) |