# Product Implementation Plan: 0 → 1 → Scale

*Updated: 2026-04-05*

How to get Angels from a component library with no backend to a live product with paying users. This plan covers architecture, build order, and the exact sequence of work.

---

## Where We Are (0)

**What exists:**
- 53 UI component manifests across 13 journey graphs — all verified and wired
- Vanilla JS component library (atoms → molecules → organisms) in Storybook
- Full event system (`journey:action`, `journey:data` CustomEvents)
- 1 organism built (PrivacySafeguards), remaining screens rendered via story fixtures
- Journey graph runtime engine (`journeys/lib/runtime.ts`)
- Research pipeline: transcripts → insights → requirements → journeys
- 15 API endpoints extracted from journey effects (none implemented)
- Landing page + animation gallery deployed to Vercel (static)

**What doesn't exist:**
- No backend, no database, no auth
- No working app — only Storybook stories
- No screen transitions between journey nodes
- No real API layer
- No deployment pipeline for the app itself

---

## Phase 0: The Demo (2 weeks)

### Goal
A URL you can share with investors where they tap through real flows with realistic data.

### Architecture: Demo App

```
demo/
├── index.html              ← App shell (mobile viewport, status bar)
├── runtime/
│   ├── player.ts           ← Journey walkthrough engine
│   ├── router.ts           ← Maps journey nodes → component renders
│   ├── transition.ts       ← Screen transition choreography
│   └── fake-api.ts         ← Static JSON responses for all 15 endpoints
├── screens/                ← Journey screen renderers (reuse story components)
│   ├── onboarding/
│   ├── checkin/
│   ├── crisis/
│   ├── safety/
│   ├── consent/
│   ├── privacy/
│   └── home/
├── scenarios/              ← Scripted demo sequences
│   ├── kai-first-week.ts
│   ├── james-joins.ts
│   ├── danny-recovery.ts
│   └── priya-circle.ts
└── styles/
    ├── tokens.css          ← Reuse from stories/tokens.css
    └── transitions.css     ← Motion design tokens from animation study
```

### Build Order

| Day | Task | Detail |
|-----|------|--------|
| 1 | App shell | Mobile frame (375×812), status bar, bottom nav, viewport setup |
| 1 | Screen router | Given a storyId, render the right component in the frame |
| 2 | Journey player | Walk a journey graph: current node → render screen → listen for action → transition → next node |
| 2 | Fake API layer | Map all 15 effect keys to static JSON responses |
| 3 | Screen transitions | Forward slide, back slide, modal scale-up — use CSS from animation study |
| 3 | Micro-interactions | Button press, toggle spring, input focus glow — wire to components |
| 4-5 | Survivor onboarding demo | Kai: persona select → onboarding (6 screens) → home |
| 5-6 | Daily check-in demo | Kai: home → mood → journal → streak |
| 6-7 | Crisis flow demo | Kai: crisis trigger → angel alert → post-crisis recovery |
| 7-8 | Guardian demo | James: invitation → onboarding → see Kai's mood |
| 8-9 | Recoverer + Connector demos | Danny and Priya onboarding flows |
| 9-10 | Polish | Transitions, timing, edge cases, responsive |

### Key Technical Decisions

1. **Reuse existing components** — Don't rebuild. Import story fixtures and component factories directly.
2. **Fake API is synchronous** — `fakeApi.handle('save_checkin', data)` returns immediately with static success response. Add 300ms artificial delay for realism.
3. **State is in-memory only** — No persistence. Refresh = restart. That's fine for demos.
4. **Deploy as static site** — Same Vercel config, add `/demo` route.

---

## Phase 0→1: The Bridge (1 week between demo and alpha)

### What changes between demo and real app

| Demo | Real |
|------|------|
| Static HTML + vanilla JS | Next.js 15 app |
| In-memory state | Neon Postgres via Drizzle |
| Fake API | Real API routes |
| No auth | Better Auth (magic link) |
| No push notifications | Web Push API |
| Deployed as static files | Deployed as Next.js on Vercel |

### Architecture: Production App

```
app/                        ← Next.js 15 App Router
├── (auth)/
│   ├── login/page.tsx      ← Magic link entry
│   └── callback/page.tsx   ← Auth callback
├── (app)/
│   ├── layout.tsx          ← App shell (mobile frame, bottom nav)
│   ├── page.tsx            ← Home (daily glance)
│   ├── checkin/page.tsx    ← Daily check-in flow
│   ├── safety/page.tsx     ← Safety plan view/edit
│   ├── crisis/page.tsx     ← Crisis mode
│   └── settings/page.tsx   ← User settings
├── (onboarding)/
│   ├── persona/page.tsx    ← Persona selection
│   ├── survivor/page.tsx   ← Survivor onboarding flow
│   └── guardian/page.tsx   ← Guardian onboarding flow
├── api/
│   ├── checkins/route.ts   ← POST (save), GET (streak)
│   ├── safety-plan/route.ts ← GET, PUT
│   ├── crisis/route.ts     ← POST activate, POST resolve
│   ├── invitations/route.ts ← POST send, POST accept/decline
│   └── onboarding/route.ts ← POST survivor, POST guardian
└── invitation/[token]/page.tsx ← Angel invitation landing

lib/
├── db/
│   ├── schema.ts           ← Drizzle schema (6 tables)
│   ├── client.ts           ← Neon connection
│   └── migrations/         ← Drizzle migrations
├── auth/
│   └── config.ts           ← Better Auth setup
├── journey/
│   ├── runtime.ts          ← Journey graph engine (from demo)
│   ├── router.ts           ← Node → component mapping
│   └── definitions/        ← Import from journeys/definitions/
└── components/             ← React wrappers around vanilla JS components
    ├── JourneyScreen.tsx   ← Renders any storyId as a React component
    └── TransitionWrapper.tsx ← Handles screen transitions
```

### Database Schema (Minimum Viable)

```sql
-- 6 tables for Phase 1
users (id, email, persona, display_name, created_at)
safety_plans (id, user_id, triggers, coping, contacts, version, updated_at)
checkins (id, user_id, mood, journal_entry, created_at)
streaks (user_id, current_streak, longest_streak, last_checkin_date)
connections (id, survivor_id, angel_id, status, role, created_at)
invitations (id, from_user_id, token, contact_name, contact_method, status, created_at)
```

### Migration Strategy: Vanilla JS → React

The existing component library is vanilla JS (createElement factories). For Next.js:

1. **Wrap, don't rewrite.** Create a `<JourneyScreen storyId="checkin--mood-prompt" />` React component that:
   - Imports the component factory and fixture from the registry
   - Renders into a `ref` div using the vanilla JS factory
   - Listens for `journey:action` and `journey:data` CustomEvents
   - Translates events into React state / server actions

2. **Gradually replace.** As components need real interactivity (form validation, server mutations), rewrite individual screens as React components. The journey graph doesn't care — it just needs a renderer for each storyId.

---

## Phase 1: Real Safety (6 weeks)

### Week-by-week build plan

**Week 1: Foundation**
- [ ] Next.js 15 project scaffold
- [ ] Neon Postgres setup + Drizzle schema (6 tables)
- [ ] Better Auth with magic link
- [ ] `<JourneyScreen>` React wrapper component
- [ ] Basic app shell (mobile layout, bottom nav)

**Week 2: Onboarding**
- [ ] Persona selection page
- [ ] Survivor onboarding flow (6 screens → saves safety plan + profile)
- [ ] First real API routes: `POST /api/onboarding/survivor`, `POST /api/crisis-plan/save`
- [ ] Redirect to home after onboarding

**Week 3: Daily Loop**
- [ ] Home page (daily glance: mood, streak, next check-in)
- [ ] Check-in flow (mood → journal gate → journal → streak)
- [ ] API routes: `POST /api/checkins`, `GET /api/checkins/streak`
- [ ] Streak tracking logic

**Week 4: Safety & Crisis**
- [ ] Safety plan view + edit
- [ ] Crisis activation flow
- [ ] API routes: `GET/PUT /api/safety-plan`, `POST /api/crisis/activate`
- [ ] Push notification to angel on crisis (web push API)
- [ ] SMS fallback for crisis (Twilio)

**Week 5: The Angel Side**
- [ ] Invitation flow: survivor sends invite → angel receives link
- [ ] Angel onboarding: accept → set boundaries → notifications
- [ ] API routes: `POST /api/invitations/send`, `POST /api/invitations/accept`
- [ ] Angel sees basic survivor mood (if consented)

**Week 6: Polish & Launch**
- [ ] Screen transitions (reuse demo CSS)
- [ ] Loading states, error handling, empty states
- [ ] Check-in reminders (push)
- [ ] Onboarding analytics (where do people drop off?)
- [ ] Deploy to production + invite first 20 users

### What "done" looks like

A survivor (Kai) can:
1. Open angels.app → magic link login
2. Choose "I'm looking for support" → complete onboarding → safety plan created
3. Every day: open app → mood check-in → optional journal → see streak
4. In crisis: tap crisis button → angel gets push + SMS → crisis resolved
5. After crisis: day-1 check-in
6. Invite someone as their angel → angel gets SMS/email → angel sets up their side

An angel (James) can:
1. Receive an invitation link → accept → create account
2. Set boundaries (quiet hours, notification level)
3. See that their person checked in today (mood only, no journal)
4. Get alerted during crisis

---

## Phase 1→2: Scaling Prep (1 week)

Before adding guardians and the consent system:

| Task | Why |
|------|-----|
| Add observability (Vercel Analytics + error tracking) | Can't improve what you can't measure |
| User feedback mechanism (in-app) | Learn what's broken before adding more |
| Database connection pooling | Free tier → shared plan before 500 users |
| Automated testing (Playwright for critical flows) | Crisis flow MUST NOT break |
| Rate limiting on crisis endpoints | Prevent abuse |
| GDPR: data export + deletion | Legal requirement before scaling |

---

## Phase 2: Trust Network (8 weeks)

### Key additions

1. **Guardian persona** — Full onboarding flow (4 screens already designed)
2. **Consent system** — The 3-screen consent wizard becomes real:
   - Choose what to share (mood, journal, crisis, streaks)
   - Per-person rules (angel A sees mood, angel B sees everything)
   - Review and confirm
3. **Privacy safeguards** — The 6-screen privacy flow (only organism already built):
   - Coercion detection (someone checking too often)
   - Excessive checking alerts
   - Quiet exit (hide the app)
   - Crisis resources
4. **Mood visualisation** — 7-day trend chart visible to consented angels/guardians
5. **Post-crisis recovery** — Full 14-day timeline (day 1, 3, 7, 14 check-ins)

### New database tables

```sql
consent_rules (id, owner_id, viewer_id, metric, permission, updated_at)
privacy_events (id, user_id, event_type, details, created_at)
mood_trends (user_id, date, mood, 7day_avg, trend_direction)
crisis_events (id, user_id, started_at, resolved_at, false_alarm, recovery_status)
notifications (id, user_id, type, channel, sent_at, read_at)
```

### New API endpoints

```
POST   /api/consent/save         ← Save consent rules
GET    /api/consent/:userId      ← Get what I've consented to share
POST   /api/sharing/update       ← Modify sharing on the fly
POST   /api/privacy/log          ← Log privacy event (coercion, excessive checking)
GET    /api/checkins/history     ← 7-day history for mood visualisation
GET    /api/checkins/trend       ← Computed trend (improving/declining/stable)
POST   /api/onboarding/guardian  ← Guardian profile creation
```

---

## Phase 2→3: Revenue Prep (2 weeks)

| Task | Detail |
|------|--------|
| Stripe integration | Subscription billing, webhook handling |
| Feature flag system | Toggle free vs premium features |
| Premium gate UI | "Upgrade to unlock" screens |
| Subscription management | Cancel, pause, change plan |
| App Store prep | PWA manifest OR React Native wrapper |
| Recoverer onboarding | 4 screens already designed, wire to backend |

---

## Phase 3: Revenue (6 weeks)

### Premium features to implement

| Feature | Free | Premium |
|---------|------|---------|
| Angel connections | 1 | Unlimited |
| Mood history | 7 days | 30+ days |
| Streak insights | Basic count | Reflections + patterns |
| Data export | — | CSV/PDF |
| Notification schedule | Default | Custom |
| Recoverer persona | — | Full access |

### Revenue infrastructure

- Stripe Checkout (hosted payment page — simplest)
- Webhook: `checkout.session.completed` → update user subscription status
- Middleware: check subscription status before premium features
- Grace period: 3 days after failed payment before downgrade

---

## Technical Principles (All Phases)

### 1. Journey graphs are the source of truth
Every user-facing flow is a journey graph. The runtime engine processes the graph. Components render nodes. Effects hit APIs. This architecture doesn't change from demo to production — only the renderers and API layer swap out.

### 2. Components are disposable, journeys are not
Rewrite any component (vanilla JS → React → whatever) without touching the journey definition. The graph is the contract. The component is the implementation.

### 3. Privacy is not a feature, it's the architecture
Consent rules are checked on every data access, not just in the consent wizard. Coercion detection runs passively. Quiet exit works even if the user can't navigate to settings.

### 4. Crisis path has no dependencies
Crisis activation must work even if: the database is slow, push notifications fail, the consent system is broken, the user hasn't completed onboarding. Fallback to SMS. Fallback to emergency number. Never fail silently.

### 5. Build for the person in crisis, test with the person who's fine
Every feature should feel effortless when you're calm and still work when you're panicking, shaking, or can't think clearly. Large tap targets. Clear language. Minimal choices during crisis.

---

## Staffing / Resource Model

### Solo founder (Phase 0–1)
- 1 full-stack developer (you)
- Claude Code for acceleration
- Total: 8 weeks to live alpha

### Small team (Phase 2–3)
- 1 full-stack developer
- 1 part-time designer (animations, polish)
- 1 part-time clinical advisor (content, safeguarding)
- Total: 14 weeks to revenue

### Growth team (Phase 4+)
- 2 full-stack developers
- 1 designer
- 1 clinical advisor
- 1 BD/partnerships (NHS, universities)
- Funded by seed round (£1.5M target)

---

## Risk Register

| Risk | Impact | Mitigation |
|------|--------|-----------|
| Crisis feature fails in production | Critical — user safety | Automated Playwright tests on crisis flow. SMS fallback. Manual testing before every deploy. |
| No one invites angels | High — breaks core loop | In-onboarding invitation prompt. Follow-up reminder at day 3. Make it dead simple (SMS link). |
| Consent system too complex | Medium — users skip it | Default to "share mood only" and let users add more later. Progressive disclosure. |
| Coercion detection false positives | Medium — erodes trust | Conservative thresholds. "Are you OK?" prompt, not automatic action. User can dismiss. |
| Free tier too generous | Medium — no conversion | Time-gate premium features (free for 14 days, then limited). |
| MHRA regulatory requirements | High — potential blocker | Stay below "medical device" classification. Wellbeing tool, not clinical tool. No diagnosis, no treatment recommendations. |
| Data breach | Critical — trust destroyed | Encrypt at rest (Neon default). Minimal data collection. No health data in logs. Annual pen test from Phase 2. |

---

## Success Metrics by Phase

| Phase | North Star | Target |
|-------|-----------|--------|
| 0 | Investor conviction | ≥2 investors say "I want to back this" |
| 1 | Daily habit | >60% D7 retention, >40% daily check-in |
| 2 | Trust network works | >30% angel acceptance, >80% consent completion |
| 3 | Revenue | >5% premium conversion, >£500/mo |
| 4 | Institutional traction | >3 paying organisations |
| 5 | Platform | >10K users, multi-country |
