Phase 5: alert subscriptions UI + multiple watchlists + queue fixes
CI / Test & Type-Check (push) Canceled after 0s

UI:
- /alerts page: event history with acknowledge, subscription create/manage with toggle
- /admin/smtp: SMTP config form (host, port, auth, test)
- Watchlist sidebar: dropdown selector for multiple watchlists, create/delete
- Sidebar: alerts count badge, SMTP link under admin
- Mobile tab nav: alerts tab added
- Client trpc.ts: all new API methods + types

Backend:
- watchlists.listByWatchlist procedure + listSymbolsByWatchlist repo fn
- yfinance min-interval 1500->2000ms to reduce Edge 429s
- Fixed e.date.slice error in yfinance-adjustments with typeof guard
- Removed defunct BITF from watchlist+queue
- Cleared 83 failed + 12 backoff queue jobs

Docs:
- FUNCTIONAL_DESIGN.md: alerts + multiple watchlists + SMTP documented
- TECH_DESIGN.md: new modules, tRPC procs, routes updated
This commit is contained in:
Investor Flow Build
2026-07-23 20:51:47 -04:00
parent f71987c119
commit 5b9f770aa4
23 changed files with 1567 additions and 146 deletions
+10 -5
View File
@@ -1,6 +1,6 @@
# Investor Flow — Functional Design (as built)
**Audit date:** 2026-07-18
**Audit date:** 2026-07-23
**Source of truth for status:** this file + code under `app/`. Older slice SPECs, HANDOFF.md, and Automaton WORKFLOW.md are historical.
**Product intent:** Beginner-first multi-tenant educational research terminal for conviction investing (not day trading). Legal posture: educational publisher (ADR-0007).
@@ -37,6 +37,7 @@
| 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 |
| 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 |
@@ -94,9 +95,12 @@
| Capability | Status | Notes |
|------------|--------|-------|
| Alert list / ack / unacked count | **Live** | Used on mobile + rotation alert chip |
| Rotation signal → alert create | **Live** | `market.rotationCheckForAlert` |
| Full hybrid AlertEngine (Form4, thesis, cluster, halt…) | **Partial** | Engine types/tests exist; not all event producers wired continuously |
| 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` | **Live (thin)** | Auth, holdings glance, unacked alerts — not full M19 job A vision |
@@ -110,6 +114,7 @@
| 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) |
@@ -180,7 +185,7 @@ Unchanged from domain model / ADRs:
| P2 | Derisking + thesis monitor product surfaces | Process depth |
| P2 | Options convexity sleeve UI | M17 incomplete |
| P3 | Reports UI | Export pedagogy |
| P3 | Schema cleanup (duplicate `strategies` DDL) | Maintainability |
| 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 |
+11 -8
View File
@@ -1,6 +1,6 @@
# Investor Flow — Technical Design (as built)
**Audit date:** 2026-07-18
**Audit date:** 2026-07-23
**Companion:** [`FUNCTIONAL_DESIGN.md`](./FUNCTIONAL_DESIGN.md)
**Canonical code roots:** `app/src` (Next frontend), `app/server/src` (Node backend)
@@ -83,7 +83,7 @@ app/server/src/
trpc/router.ts ~2k LOC — all routers
trpc/context.ts session, cookies, db, cache, queue injection
db/schema.sql DDL (note: duplicate strategies blocks — debt)
db/*Repository.ts watchlist, portfolio, emotion logs
db/*Repository.ts watchlist, portfolio, emotion logs, alertSubscription
cache/CacheRepository.ts content-addressed cache API
queue/AdapterQueue.ts schedule, pause, retry, source cool-downs (ADR-0009)
queue/sourceRatePolicy.ts 429 detect, cool-down ladders, min-intervals
@@ -91,8 +91,10 @@ app/server/src/
analysis/ indicators, rotation, seasonality, etfHoldingsFallback, tickerContext
admin/ operator functions + CLI
auth/ totp, oauth, backup codes
alerts/AlertEngine.ts
risk/RiskEngine.ts + haltCircuitBreaker.ts ← pure; NOT on tRPC
alerts/AlertEngine.ts
alerts/producers/ types.ts, index.ts (registry), insiderProducer.ts, new13daProducer.ts
services/emailAlertService.ts nodemailer SMTP delivery + rate limit
risk/RiskEngine.ts + haltCircuitBreaker.ts ← pure; NOT on tRPC
sizing/SizingEngine.ts + convictionUnlock + twoAxisMatrix ← pure; NOT on tRPC
strategy/BacktestEngine.ts
screener/UniverseEvaluator.ts + SectorCrosslink.ts
@@ -114,11 +116,11 @@ app/server/src/
| `onboarding` | starter, complete |
| `market` | snapshot, candles, indicators, truckSales, manufacturingPmi, rotation, rotationCheckForAlert, sectorHoldings |
| `dashboard` | rollup |
| `admin` | users, sessions, passwords, queue*, lint, data quality, X creds/accounts/prune, FRED key, pending/approve/reject, audit, serverRestart, gdprExport |
| `alerts` | list, acknowledge, acknowledgeAll, unackedCount |
| `admin` | users, sessions, passwords, queue*, lint, data quality, X creds/accounts/prune, FRED key, pending/approve/reject, audit, serverRestart, gdprExport, smtpConfig, smtpConfigUpdate, smtpConfigTest |
| `alerts` | list, acknowledge, acknowledgeAll, unackedCount, createSubscription, listSubscriptions, updateSubscription, deleteSubscription |
| `institutional` | flow, insiderStream, ownershipHistory, buyEvents |
| `edgar` | filings_index, company_facts, filer_cik_meta, full_text_search, form13f_holdings, form4_tx |
| `watchlists` | list, addSymbol, removeSymbol |
| `watchlists` | list, listByWatchlist, listWatchlists, create, delete, rename, reorder, addSymbol, removeSymbol |
| `portfolio` | holdings, addHolding, removeHolding |
| `options` | chain, greeks |
| `reports` | generate |
@@ -168,9 +170,10 @@ app/src/
| `/options-dd` | Options DD |
| `/market-outlook` | Macro / rotation / notes |
| `/trade-plan`, `/execution`, `/trade-closure`, `/daily-focus` | Process (local) |
| `/alerts` | Alert events + subscriptions |
| `/settings` | Auth + onboarding |
| `/mobile` | Thin companion |
| `/admin`, `/users`, `/queue`, `/audit-logs`, `/x-accounts` | Admin |
| `/admin`, `/users`, `/queue`, `/audit-logs`, `/x-accounts`, `/smtp` | Admin |
### 5.2 Client coverage gap