# Investor Flow — Functional Design (as built) **Audit date:** 2026-07-23 **Source of truth for status:** this file + code under `app/`. Older slice SPECs and HANDOFF.md are historical. **Product intent:** Multi-tenant **investment management** workbench (portfolio, risk, monitor, research context) that helps users become better at market awareness and risk management *while managing*. Not a course app. Legal posture for copy/outputs: educational publisher (ADR-0007) - process and math, never buy/sell advice. --- ## Status legend | Status | Meaning | |--------|---------| | **Live** | Backend + UI end-to-end usable for the intended job | | **Backend-ready** | Engine and/or tRPC exist with tests; little or no product UI | | **UI-local** | Screen exists but state is browser-only (localStorage / Zustand), not multi-device / multi-tenant | | **Stub** | Surface or procedure exists but incomplete (empty timeline, thin universe, etc.) | | **Missing** | Designed in domain model; not implemented as a product path | --- ## 1. User jobs and surfaces ### 1.1 Identity, access, onboarding | Capability | Status | Notes | |------------|--------|-------| | Email/password signup | **Live** | New users get `status=pending_approval`; no session until admin approves | | Login + session cookie | **Live** | Non-active users rejected at login and `protectedProcedure` | | TOTP 2FA + backup codes | **Live** | Settings page | | GitHub / Google OAuth | **Backend-ready** | Router complete; env-dependent; OAuth users default `active` | | Onboarding wizard | **Live** | Workspace interview (experience, goal, horizon, jargon) → density + risk defaults + starter pack; optional portfolio; queues SEC fetch | | Workspace density | **Live** | `focused` \| `standard` \| `full` filters nav, symbol Overview panels, strategy templates; editable in Settings | | Admin approve/reject | **Live** | `/admin/users` | | Settings / profile | **Live** | `/settings` | ### 1.2 Research workbench (desktop) | Surface | Route | Status | Data path | |---------|-------|--------|-----------| | Symbol overview | `/` | **Live** | `market.snapshot`, company meta, X feed, collapsible filings + options | | Multiple watchlists | sidebar | **Live** | Create/delete/rename/reorder, dropdown selector in sidebar, per-watchlist symbols | | Charts | `/chart-lab` | **Live** | candles, indicators, institutional buy markers; equity volume-by-price profile (visible range, from OHLC bars) | | Institutional dashboard | `/institutional` | **Live** | dashboard rollup, flow, insider stream, filings; Q-o-Q / M-o-M | | Filings | `/filings` | **Live** | EDGAR index + 13F + Form 4 detail | | Options DD | `/options-dd` | **Live** | chain + greeks (read-only teaching surface) | | Dealer Flow | `/dealer-flow` | **Live (MVP)** | Heatmap-first IA: GEX/VEX is the only map toggle (convention lives in Method); reading / method / study in drawers; point-in-time book clock; **integrity gates** (incomplete vs degraded vs complete); IV hygiene; keep last good map; as-of ET; `dealer-map-replay` CLI + Admin → Queue **Dealer map integrity** buttons; Layer-0 + optional L1 | | Study Desk | (drawer on `/dealer-flow`) | **Live** | Educational setups from map; hist rank; log; auto-grade; scorecard; promote to journal draft; CSV export | | Mentor ledger | (Study Desk tab) | **Live (MVP)** | Local import from harvest → confirm drafts → path-match grade + mentor scorecard (not buy signals) | | Market outlook | `/market-outlook` | **Live (Phase 1–3 core)** | Beginner language. Condition strip; stronger/weaker-vs-market map; seasonality + calendar; rank snapshots; auto leadership check; truck/factory; macro notes. True ETF flow/COT still later. | | Social / X feed | on overview | **Live** | DB-backed 30d history + admin X credentials/accounts | | Command palette + nav | shell | **Live** | ⌘K, g-key shortcuts, theme presets | ### 1.3 Process / journal workflow | Surface | Route | Status | Gap | |---------|-------|--------|-----| | Decision plan | `/plan` | **Live** | Server `trades.save`; optional thesis create | | Theses | `/theses` | **Live** | CRUD on `theses` table | | Journal / close | `/journal` | **Live** | `trades.list` / `close` + reflection | | Screener | `/screener` | **Live** | Filter + strategy screen over watchlist | | Strategy lab | `/lab` | **Live** | Backtest equity curve + evaluate latest | | Reports | `/reports` | **Live** | HTML research notes | | Daily focus / goals | `/daily-focus` | **UI-local** | localStorage goals | | Emotion logger | API | **Partial** | API live; journal reflection covers close notes | | Sizing math | `/risk` (calculator) | **Live** | `sizing.compute` + UI cascade (math only, ADR-0007) | | Risk posture (M20) | `/risk` | **Live** | `risk.posture` / `risk.haltStatus` + RiskPosturePanel; halt persisted on drawdown breach | | Derisking suggestions | (no screen) | **Backend-ready** | `derisking.suggest` | | Thesis monitor | (no screen) | **Stub** | `thesisMonitor.assess` / `timeline` (empty events / empty timeline) | ### 1.4 Discovery & strategy lab | Capability | Status | Notes | |------------|--------|-------| | Filter screener (M15a) | **Live** | `/screener` + `screener.filter` over watchlist quotes | | Strategy screener (M15b) | **Live** | `/screener` strategy mode when density ≥ standard | | Strategy authoring | **Partial** | presets + fork; custom authoring still light | | Backtest | **Live** | `/lab` equity curve + evaluate latest | | Sector confirmation cross-link | **Stub** | `sectorCrosslink.confirm` with empty universe in practice | | Screener saved filters | **Schema only** | tables exist; incomplete product loop | ### 1.5 Options convexity sleeve (M17) | Capability | Status | Notes | |------------|--------|-------| | Options DD (read-only) | **Live** | M3 teaching panel | | Unlock ladder + payoff API | **Backend-ready** | `optionsConvexity.unlock` / `getPayoff` | | Option legs book + risk contribution | **Live (MVP)** | `OptionLegsPanel` on `/portfolio` + `/risk`; `portfolio.optionLegs` / add / remove; posture folds premium-at-risk + CSP cash reserve into exposure/flags | | Portfolio sleeve workflow (M17 full) | **Missing** | Unlock UX + sleeve risk budget not enforced in product path | ### 1.6 Macro (M18) | Capability | Status | Notes | |------------|--------|-------| | FRED series / key admin | **Live** | Admin X Accounts page also manages FRED key | | Truck sales + manufacturing PMI charts | **Live** | Market routes | | Sector rotation heatmap-style panel | **Live** | Relative-strength style rotation, not full designed phase library UI | | Regime classify / history | **Backend-ready** | `macro.regimeClassify`, `regimeHistory` | | Portfolio-impact commentary | **Live** (partial) | `macro.commentary` via Market Outlook; **2 unit tests failing** on wording assertions | | Full economic calendar UI | **Stub** | `macro.calendar` | ### 1.7 Alerts & mobile | Capability | Status | Notes | |------------|--------|-------| | Alert list / ack / unacked count | **Live** | `/alerts` page with event history + subscription management | | Alert subscriptions (create/list/update/delete) | **Live** | Per-user with ticker-level / list-level / global inheritance | | Alert producers: informed_buy, informed_sell | **Live** | Insider tx comparison state, batched every 10 min | | Alert producer: new_13da | **Live** | New 13D/13G filing detection, batched every 10 min | | Alert producers: 7 more types (rotation, regime, conviction, thesis, cluster, drawdown, asymmetry) | **Stub** | Engine types exist; producers not wired | | Email delivery (SMTP) | **Live** | Nodemailer, admin SMTP config page, rate limit 1/hr per type/symbol/user | | SSE push | **Missing** | Design called for SSE; poll/list only | | Mobile companion `/mobile` | **Redirect** | Redirects to Portfolio; main shell is phone-optimized companion (Job A) | | Mobile shell (iPhone Air) | **Live** | Fixed `dvh` chrome, safe-area insets, bottom tabs (Portfolio · Risk · Research · Alerts · More), slim header + search overlay; no desktop layout flash | | Mobile lists sheet | **Live** | Header list icon opens portfolio + watchlist bottom sheet for symbol switch | | Portfolio on phone | **Live** | Card list + 2×2 snapshot under `md`; wide table from `md` up | | Rotation / institutional on phone | **Live** | Card rows with key horizons; full tables from `md` up with sticky first column | | Mobile polling hygiene | **Live** | Snapshot / alerts / market condition pause while document is hidden | | Portfolio book | **Live** | Unified holdings + live marks + add/remove (`HoldingsBookView`). `/monitor` redirects here. | ### 1.8 Admin / operator | Capability | Status | |------------|--------| | Users, sessions, reset password | **Live** | | Pending approval queue | **Live** | | Adapter queue health, pause/resume, retry, schedules, error stacks | **Live** | Cooldown column ticks 429 pauses; blank is not-paused. Unhealthy Yahoo shows backlog/notes. T0/focused quotes drain first. | | SEC queue fetch + lint holders/insiders + data quality | **Live** | | X credentials, accounts, prune | **Live** | | FRED key | **Live** | | SMTP config (host, port, auth, test) | **Live** | Admin page at `/admin/smtp` | | Audit log | **Live** | | Server restart control | **Live** | | GDPR export | **Backend-ready** (admin API) | ### 1.9 Reports | Capability | Status | |------------|--------| | HTML research note generator | **Live** | `/reports` + `reports.generate` | --- ## 2. Functional architecture (intended jobs) ``` Job A — Monitor (mobile + alerts) alerts.list/ack · portfolio.holdings · rotation chip Job B — Research (desktop workbench) watchlist → active symbol → market + SEC + institutional + options + social market outlook (macro + rotation) Job C — Process (planned investor loop) thesis + confluence + sizing → plan → execute → emotion → close → unlock [mostly UI-local today; engines exist but not productized] Job D — Discover (planned) filter/strategy screener → open in workbench [API only] ``` --- ## 3. Design principles still in force Unchanged from domain model / ADRs: 1. **Primary Rule (ADR-0007)** — education, not advice; Primary-Rule lint test on curated strings. 2. **Analyst Voice (ADR-0005)** — Alfred/Druckenmiller blend where LLM copy is used. 3. **P6 plain English / P7 teach mechanics** — in-context cockpit labels (not a curriculum product). 3b. **Adaptive workspace density** — experience interview sets focused/standard/full; user can change anytime. 4. **Local-first multi-tenant (ADR-0001)** + shared cache dedupe (ADR-0004). 5. **LLM data provenance (ADR-0006)** — sensitive data stays on local-class providers; full gateway module is thin/incomplete vs original design. 6. **Anti-gamification** — no confetti / outcome celebration. --- ## 4. Explicit non-goals (still) - Brokerage execution or custody - Investment adviser recommendations - Mobile-first full research workbench - Undefined-risk options strategies for beginners - Training on user portfolio/thesis content via external LLMs --- ## 5. Gap priority (product value) | P | Gap | Why it matters | |---|-----|----------------| | P0 | Fix failing MacroRegime commentary tests | **Done 2026-07-18** — suite green (504 pass / 1 skip) | | P0 | Expose SizingEngine + RiskEngine on tRPC + M20 UI | **Done 2026-07-18** — `/risk` + `sizing`/`risk` routers | | P1 | Persist trade plan / thesis / execution / closure server-side | Today process screens are single-browser toys | | P1 | Frontend client coverage for backend-only routers | APIs unreachable from SPA client | | P1 | Wire emotion logger UI to `emotionLogger` API | Schema + API exist; dual paths confuse | | P2 | Strategy Lab + backtest UI | Engines exist; no learning surface | | P2 | Screener UI (filter + strategy) | Discovery job unfinished | | P2 | Derisking + thesis monitor product surfaces | Process depth | | P2 | Options convexity sleeve UI | M17 incomplete | | P3 | Reports UI | Export pedagogy | | P3 | Wire remaining 7 alert producers | rotation, regime, conviction, thesis, cluster, drawdown, asymmetry | | P3 | SSE alerts / continuous event producers | Ops polish | | P3 | Full LLM Gateway as designed | Provenance enforcement completeness | --- ## 6. Related docs - Tech design (modules, stack, API map): [`TECH_DESIGN.md`](./TECH_DESIGN.md) - Domain glossary: [`../CONTEXT.md`](../CONTEXT.md) - ADRs: [`adr/`](./adr/) - Living wiki page: Obsidian `investor-flow.md` (synced with this audit)