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
4 KiB
B — Drawers (contextual full-screen views from chat)
Goal
When a chat reference (a calendar mention, a prospect name, a specialist citation) needs visual context or bulk manipulation, tapping it slides up a full-screen drawer. Drawers dismiss with a swipe back to the same chat scroll position. They never become a permanent navigation tab.
Designer skim
- Headline UX: Chat is home; drawers are rooms you visit. Swipe-back returns to the same chat scroll position. No permanent nav chrome.
- Drawers (6): B1 calendar (
content_plans) · B2 asset library · B3 prospect detail · B4agent_actionslog · B5 persona editor · B6 specialist. - Pair-with:
specialist-drawer.screen.md,audit-row-detail.screen.md. - Blocking Qs: see OPEN-DECISIONS.md → B-Q1 hide-chat-fully, B-Q2 sheet-detents.
Constraints
- SwiftUI sheet presentation, full-height; swipe-down to dismiss; back-stack of one (drawer → drawer is fine, but pressure to keep flat).
- All actions in drawers are also reachable by asking ai-copilot in chat — drawers are for visual + bulk + replay, never required.
- Same auth + design tokens as chat.
Drawers to design
B1 — Calendar drawer (content_plans)
- Week view (default) + month view toggle.
- Per-surface color coding (OF, X, IG, TikTok, ...).
- Inline approval gestures on each plan tile (same swipe semantics as chat cards).
- Tap a plan tile → opens edit drawer.
- Empty state: "No plans yet. Want strategist to draft a week?"
- Inputs:
GET /api/v1/content-plans?user_id=...&from=...&to=....
B2 — Asset library drawer (content_assets)
- Grid (3-col on iPhone, 5-col on iPad — but iPad is brief E).
- Filter chips: surface tag, persona facet, tags array.
- Upload affordance (camera roll picker + native iOS share sheet target).
- Asset detail: thumbnail + variants list + "schedule this on..." sheet.
- Inputs:
GET /api/v1/content-assets?user_id=...andPOST /api/v1/content-assets(asset metadata; binary goes to MinIO via presigned URL).
B3 — Prospect detail drawer
- Cross-surface message history for one
prospect_id(resolved by prospect-resolver worker). - Funnel-stage indicator (free / DM / tip / PPV / subscribe / booking).
- Inline draft reply (sent through quinn-prospector's
draft_messageMCP for consistency). - Inputs:
mcp__quinn-prospector__get_prospect,GET /api/v1/engagement-events?prospect_id=....
B4 — agent_actions log drawer (replay timeline)
- Reverse-chronological list, infinite scroll.
- Filters: specialist_id, action_type, stakes, auto_executed.
- Tap an action → outcome_json viewer.
- Inputs:
GET /api/v1/agent-actions?user_id=....
B5 — Persona editor drawer
- Human-form editor over
personas.facetsJSONB (per-surface voice tabs: OF / X / IG / ...). - Brand voice (global) + off-limits list (kept-secret topics).
- "Re-do the interview" affordance → re-runs persona-seed flow (brief D).
- Inputs:
GET /api/v1/personas/:user_id,PATCH /api/v1/personas/:user_id.
B6 — Specialist drawer
- Identity card (specialist_id + persona snippet + last-N actions).
- "Talk directly" affordance → opens a dedicated thread (defer to P5; show greyed in P0).
- Inputs:
GET /api/v1/agent-actions?specialist_id=....
In-the-wild copy
B1 · calendar empty state (hearth):
No plans yet. Want strategist to draft a week?
B3 · prospect detail header (working):
@felix · OF + Tryst · first DM Mar 12 · last contact 2h ago
B6 · specialist drawer header, talk-directly disabled (working):
content-onlyfans · trust 0.92 over 30 days · talk directly (P5)
Out of scope
- Editing past
agent_actionsrows (append-only at the DB level). - Multi-prospect bulk operations (P4+).
Open questions
- When opening a drawer from a chat card, do we hide the chat fully or show a thin sliver behind?
- Sheet detents: single full-height or expandable (40% / 90%)?
- Cross-drawer navigation: should prospect detail → asset library work, or always dismiss-then-reopen?