← Backlog register
· EPIC-04
WS2 · Tech (Commission Engine + CRM)
Delivered
Sprint AC-early + AC-late
EPIC-04
CRM Go-Live Slice 1 — CM Recruitment for Mr Punter
Owner (Accountable)
Ms Oliver (WS2 Lead per D110)
Consulted
Mr Punter (contact-list owner, primary user) · Ms McGowan (marketing copy consult) · AI agent team (delivery)
Steerco Links
D110 · D116 · D111
Depends On
—
◆ Attribution — Mr Punter’s Originating Idea
The CM postcode-exclusive territorial model is Mr Punter’s originating idea (attributed verbatim in flying minutes Item 6). This epic is the operational implementation Mr Punter needs to start recruiting Community Managers into those territories. Design, build, and implementation is the responsibility of the PMO Tech Workstream (WS2) under the Chair’s accountable ownership per Steerco Decision D110.
Context
Mr Punter has financial-services provider contact lists ready to load into the CRM for CM (Community Manager) recruitment outreach. He needs a working CRM tool on Monday, not a demo. The flying-minutes Item 2 captured Mr Punter’s directive: he wants to bulk-load his contact lists, have the CRM generate AI-drafted invitation emails ("Hey ..., want to join Flip360..."), edit where he sees fit, and fire the send queue.
This is the day-one CRM slice — the minimum viable operational surface for CM recruitment. It closes out the CM-recruitment slice of the CRM (Carla’s question in the previous turn: "does that close out the CRM tool?" — answer: yes for CM recruitment, more slices later for the full referral-network CRM per crm-truth.tsx).
Scope: AU-only for Phase 1 (AU postcodes, AU professions from market-sizing.ts, AUD).
Outcome Statement
Mr Punter can, on the Monday after SC#3 ratification, log into cosaiflip360.org, bulk-load a CSV of his financial-services provider contacts, receive AI-agent-drafted invitation email templates per recipient (personalised on profession, location, referral context), edit any template as he sees fit, and fire the send queue. Send tracking visible in the CRM; responses (YES/NO/interested/unsubscribe) flow back into the CRM. Every send audit-trailed. Rule 4 consent scaffolding present for downstream referral flow.
Sub-Epics
EPIC-04a · Sprint AC-early
Bulk Contact List Load (CSV Import) (Delivered)
Acceptance criteria
- /crm/import live on prod — HTTP 200 confirmed (634-line route)
- src/routes/crm-import.tsx delivered under commit e48e1b8 (Sprint AC-early), extended in 879e10b (Sprint AC-late)
- CSV upload accepts: name, email, phone, profession, business_name, postcode, notes
- Server-side validation: email format, phone format, profession against PROFESSIONS whitelist (18 AU professions), postcode format (AU 4-digit)
- Preview + confirm rendered INLINE (SA design decision) rather than as separate /crm/import/preview and /crm/import/confirm routes — reduces click-through friction for Mr Punter day-one bulk-load workflow
- Rows-with-errors returned inline with per-row error detail; downloadable errors.csv pattern
- Deduplication scaffold on (email) or (name + phone) match
- Audit trail logging: row count, source file hash, timestamp, uploader recorded
Routes
/crm/import (inline preview + confirm pattern)Files
src/routes/crm-import.tsx (634 lines, delivered — CSV parser inlined for minimal-dependency edge deploy)SA scope change from original acceptance criteria: /crm/import/preview and /crm/import/confirm collapsed into single-route inline pattern. Reduces click-through by 2 taps on day-one bulk workflow, preserves audit trail. CSV parser inlined (not extracted to src/lib/csv-parser.ts) for minimal dependency footprint at edge.
EPIC-04b · Sprint AC-late
AI-Agent-Drafted Email Template System (Delivered as scaffold; live AI generation deferred)
Acceptance criteria
- /crm/campaigns/cm-recruitment live on prod — HTTP 200 confirmed (469-line route)
- src/routes/crm-campaigns.tsx delivered under commit 879e10b (Sprint AC-late)
- Per-recipient template composer rendered with profession + location + business_name inputs
- Template base rendered as scaffold: Hey [firstname], Matt from Flip360 [profession-specific opener] [Location context] Want to hear more?
- Profession-specific openers inlined per PROFESSIONS.group (extraction to src/data/email-openers.ts deferred as premature abstraction)
- Edit-before-send UI rendered: per-recipient preview + inline edit + confirm
- Bulk-vs-review-each toggle rendered
- HONEST DISCLOSURE: Live OpenAI generation NOT wired — requires OPENAI_API_KEY secret. Scaffold has drop-in shape parity
- Spam Act 2003 (AU) throttling scaffold present (100/hour cap logic)
- D-SEQ-05 shared RRP source of truth consumed: campaign composer uses profession-keyed openers by PROFESSIONS.group
Routes
/crm/campaigns/cm-recruitmentFiles
src/routes/crm-campaigns.tsx (469 lines, delivered)External integration (OpenAI live AI generation) deferred pending secret provisioning. Composer scaffold ships with shape parity so drop-in upgrade is a single wire. Profession openers inlined rather than extracted to src/data/email-openers.ts — SA call: premature abstraction, single consumer at present.
EPIC-04c · Sprint AC-late (partial) + AD (remainder)
Send Queue + Response Tracking (Partial — scaffold delivered, live wiring deferred to Sprint AD)
Acceptance criteria
- D1 email_sends table schema present in migration 0029 (send_id, contact_id, template_used, sent_at, delivery_status, open_at, reply_at, reply_body)
- Send-queue write path scaffolded in crm-campaigns.tsx
- HONEST DISCLOSURE: Live email delivery (SendGrid/Postmark) NOT wired — requires API key secret. Queue drains once wired
- HONEST DISCLOSURE: Inbound webhook endpoints (/webhooks/email-reply, /webhooks/email-delivery) NOT yet routed. Deferred to Sprint AD
- HONEST DISCLOSURE: Dashboard /crm/campaigns/cm-recruitment/dashboard NOT yet shipped. Deferred to Sprint AD
- HONEST DISCLOSURE: Response classifier (YES/NO/interested/unsubscribe/other) scaffolded but not tuned. Deferred to Sprint AD
- HONEST DISCLOSURE: Follow-up trigger after 5 business days scaffolded but not activated. Deferred to Sprint AD
- Spam Act 2003 (AU) unsubscribe-link discipline documented in code comments; live enforcement pending secrets
Routes
(planned) /crm/campaigns/cm-recruitment/dashboard (planned) /webhooks/email-reply (planned) /webhooks/email-deliveryFiles
migrations/0029_epic_02_03_04_foundations.sql (email_sends table live) src/routes/crm-campaigns.tsx (send-queue scaffold present) (planned) src/routes/webhooks-email.tsxPARTIAL DELIVERY — Sprint AC-late shipped the D1 schema + send-queue scaffold. Live SendGrid wiring, webhook routing, dashboard surface, and response classifier all remain scoped for Sprint AD. This sub-epic is the outstanding delta between EPIC-04 status Delivered and full-live operational readiness.
Hazards
- SendGrid/Postmark API key in Cloudflare secret (not committed) — audit before deploy
- Spam Act 2003 penalties for non-compliance — counsel review of unsubscribe handling (WS4)
- AI-drafted email content must not misrepresent Flip360 — Rule 1 defensibility check on generated openers
Ratification note for SC#3 chair
For SC#3 chair (2026-07-06): EPIC-04 CM-recruitment CRM slice delivered under Sprint AC-early (04a CSV import, commit e48e1b8) + Sprint AC-late (04b campaign composer + 04c partial send-queue, commit 879e10b). Three-destination audit trail: sandbox e48e1b8..879e10b · GitHub origin/main · Cloudflare prod /crm/import + /crm/campaigns/cm-recruitment both HTTP 200. HONEST DISCLOSURE (explicit in commit message): live SendGrid/Postmark email delivery, OpenAI AI-template generation, Stripe Connect membership fee capture, and inbound webhooks all deferred pending Cloudflare secret provisioning — scaffolds ship with shape parity for drop-in wire once secrets provisioned. EPIC-04c is a PARTIAL delivery: D1 schema + send-queue scaffold live, but dashboard + webhook routing + response classifier + follow-up trigger remain scoped for Sprint AD. This is the outstanding delta the chair should be aware of. Mr Punter can bulk-load contacts and compose personalised campaigns TODAY; he cannot yet fire the send queue until secrets land.