# Join-to-card graph

The public creator link starts and closes the acquisition path. The private personal link is only for the member's check-in.

```mermaid
flowchart TD
    A[Card or creator profile] --> B[Public join/creator URL]
    B --> C[Name, email, protein goal, optional phone]
    C --> D{Mode}
    D -->|Preview| E[Sample profile and round]
    D -->|Email pilot| F[Free pilot round]
    D -->|Paid launch| G[Stripe Checkout]
    G --> H[Verified paid webhook]
    H --> I[Paid round and ledger]
    F --> J[Personal link by email]
    I --> J
    J --> K[Private member session]
    E --> K
    K --> L[Today's check-in]
    L --> M[Save and evaluate requirements]
    M --> N[Persist day, streak and earned free round]
    N --> O[Render personalized card]
    O --> P[Member saves or shares]
    P --> B
    N --> Q[Anonymous creator report]
    R[Evening reminder job] -->|Incomplete day and enabled channel| J
```

## Attribution and trust boundaries

| Step | Source of truth |
| --- | --- |
| Creator attribution | Validated published creator slug at join, stored on the member. |
| Paid access | Verified Stripe event and persisted round, never a success URL alone. |
| Personal access | Signed private link exchanged for an HTTP-only session. No Google login, password, or SMS code. |
| Daily completion | Server validation against the active round, Eastern date, and effective strength schedule. |
| Free-round award | Atomic check-in/reward write and unique reward identity. |
| Public card link | Creator URL built from the authenticated member's creator; never the private access URL or generic demo URL. |
| Sharing metrics | Authenticated member actions with retry deduplication. Join is recorded with profile creation. |
| Money | Actual Stripe fee and verified payment records, with settlement, hold, refund, and dispute status. |

The join event attributes the member to a creator; it does not identify which individual social post caused the visit. Instagram/X clicks are measured as share-button taps, not confirmed publications. There is no participant leaderboard, contact list, or public financial ledger on this path.

## Delivery behavior

The confirmation and recovery email contain the same reusable personal link. Email redemption establishes ownership before SMS can be enabled in preferences. An optional phone entered at signup is not authentication or permission to send texts by itself.

The scheduled job checks the configured Eastern reminder hour (10pm by default), queues at most one reminder per member/date/channel, and skips completed days. Email uses a durable outbox with stable provider idempotency. Ambiguous SMS results are retained for review. Date/streak evaluation works independently of the scheduler.

The live preview has no connected email/SMS delivery or payments. Email-first pilot and paid-launch code exist behind readiness checks. Provider credentials, sender verification, a scheduler, and real delivery/payment checks are still operational prerequisites.

## Implementation map

- Identity and private links: `lib/security.ts`, `lib/messages.ts`.
- Join, member view, schedule, and check-in: `lib/members.ts`, `lib/contracts.ts`, `lib/domain.ts`, `lib/training.ts`.
- Free access and paid access: `lib/rewards.ts`, `lib/payments.ts`.
- Rendering and sharing: `lib/story-design.ts`, `lib/social-card.ts`, `lib/social-share.ts`, `lib/brand.ts`.
- Reporting: `lib/activity.ts`, `lib/admin.ts`.
- Request boundaries: `app/api/[...path]/route.ts`.

These are ordinary application functions. The public library provides readable product documents and six JSON specifications. A Follow action stores a browser bookmark; Fork produces a downloadable local specification draft. Neither action deploys a running agent or changes the graph. The regimen library explains the base plan and its template variations. Live payments, email, and SMS still require provider configuration and operational verification.
