Clean successor to V3 (forge: lilith/atlilith). Seeded from local Mac working tree at ~/Code/@projects/@cocottetech/. node_modules and build artifacts excluded via .gitignore. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 KiB
C — Notifications + settings
Goal
Get Quinn's attention at the right moment, through the right channel, with the right urgency — and let her tune the matrix per-specialist as she learns to trust each one.
Designer skim
- Headline UX: A three-axis matrix Quinn tunes per-specialist: channel (push / iMessage / digest / in-app) × stakes (low / medium / high) × specialist. Stakes-aware deeplinks: high opens full-screen approval modal, medium opens chat at card, low rolls into digest.
- States (5): settings idle · cell-edit popover · reset-to-defaults confirm · channel offline (mac-sync down) · recently-fired log.
- Pair-with:
notification-rich-preview.screen.md. - Blocking Qs: OPEN-DECISIONS.md → C-Q1 push+iMessage exclusivity.
Constraints
- Stakes-aware push behavior (mandatory):
- High stakes → opens a focused, full-screen approval modal on tap; haptic on receipt.
- Medium stakes → opens chat at the relevant card.
- Low stakes → no immediate push; rolled into the daily digest.
- Channels available P0: iOS APNs push, iMessage via
mac-sync:3100send-queue, email digest, in-app badge. - Notifier service (
@features/notifier) reads per-user prefs and dispatches.
Settings UI
A /settings/notifications route on the iOS app (and the same shape on web-fe later — see brief G).
Matrix to render
A three-axis matrix: channel × stakes × specialist.
- Rows: each specialist (
ai-copilot,content-onlyfans,content-x,content-instagram, ...,bookings-tryst,bookings-ts4rent, ...). - Columns: stakes (low / medium / high).
- Cell content: channel toggles (push / iMessage / digest / in-app).
Add a top-level "Default policy" row that all specialists inherit unless overridden.
Defaults (recommended)
| Specialist | Low | Medium | High |
|---|---|---|---|
| (default) | digest only | push + in-app | push + iMessage + in-app (mod.) |
| ai-copilot | (inherit) | (inherit) | always all channels |
| content-onlyfans | digest only | iMessage + in-app | iMessage + push (PPV pricing always high) |
Deeplink behavior
- iOS push action: "Approve" / "Reject" inline action buttons (no app open required for low-stakes).
- iMessage deeplink: open CocotteAI at exact card; fallback to
https://ai.cocotte.maison/approve/:card_id. - Email digest: card list with deeplink per row; "snooze 24h" affordance.
States to design
- Settings page idle.
- Cell-edit popover.
- "Reset to default policy" confirmation.
- Channel offline (iMessage unreachable → mac-sync down → fall back to push silently, surface a banner).
- Recently-fired notifications log (last 50, with deeplink to the originating card).
In-the-wild copy
Push, high stakes (plain — V5 lock-screen rule):
⚠ Tryst bump failed at 14:02. Tap to re-auth.
Push, medium stakes (plain):
content-onlyfans queued a tour-tease for 9pm. Tap to review.
iMessage digest, end of vigil (working — V5 iMessage compact rule):
Cocotte tended to your visibility on Tryst + TS4Rent — twelve bumps, no flags. Three OF drafts in the drawer. One Tryst inquiry waiting your call. ↗
Email digest, morning (hearth — V5 long-form magazine):
Yesterday Cocotte tended to your visibility on three directories, drafted four replies, and held off on one tour update pending your call. Below: the day in pieces.
Channel-offline banner (plain):
mac-sync is unreachable. iMessage paused. Falling back to push.
Out of scope
- SMS as a channel (no provider configured P0).
- Per-prospect notification rules (P4+ engagement-triage concern).
Open questions
- Should iMessage and push be mutually exclusive at the same stakes (avoid double-notify) or always additive?
- "Quiet hours" — single block or per-channel?
- Email digest cadence: daily morning vs end-of-day vs both?