Skip to content

Commit ab340d5

Browse files
committed
docs: add ASCII diagrams to PredictNext architecture docs
1 parent 5843381 commit ab340d5

9 files changed

Lines changed: 322 additions & 0 deletions

File tree

app/components/UI/PredictNext/docs/adapters.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,20 @@ Adapters do not:
5151

5252
The rest of PredictNext treats adapters as swappable protocol implementations behind a stable domain contract.
5353

54+
```text
55+
[ Service ] [ Adapter ] [ Provider API ]
56+
| | |
57+
|--- call method ---->| |
58+
| |--- request --------->|
59+
| | |
60+
| |<-- provider DTO -----|
61+
| | |
62+
| | [ Transform DTO ] |
63+
| | [ to PredictType ] |
64+
| | |
65+
|<-- PredictType -----| |
66+
```
67+
5468
Adding a new provider should primarily mean implementing one interface.
5569

5670
## 2. PredictAdapter Interface
@@ -271,6 +285,19 @@ Polymarket requires multiple underlying APIs and transports:
271285
- Polymarket account endpoints for balances, positions, and activity
272286
- WebSocket feeds for live price and status updates
273287

288+
```text
289+
PredictAdapter (Interface)
290+
^
291+
|
292+
+-------------------+
293+
| PolymarketAdapter |
294+
+-------------------+
295+
/ | \ \
296+
v v v v
297+
Gamma API CLOB API Account WebSockets
298+
(Events) (Orders) Endpoints (Live)
299+
```
300+
274301
The adapter unifies those sources into the Predict domain model.
275302

276303
### Transformation responsibility

app/components/UI/PredictNext/docs/architecture.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,47 @@ This keeps interfaces stable even as providers change. Polymarket and Kalshi may
114114

115115
PredictNext is organized into four layers, bottom-up.
116116

117+
4-Layer Architecture Overview:
118+
119+
```text
120+
(Responses)
121+
(Requests) ▲
122+
│ │
123+
▼ │
124+
┌──────────────────────────────────────────────────────────┐
125+
│ Layer 4: Components (Views → Widgets → Primitives) │
126+
└───────────────────────────┬──────────────────────────────┘
127+
128+
129+
┌──────────────────────────────────────────────────────────┐
130+
│ Layer 3: Hooks (events/, portfolio/, trading/, etc.) │
131+
└───────────┬───────────────────────────┬──────────────────┘
132+
│ │
133+
│ (Read Path) │
134+
▼ ┌─────────────┘
135+
┌─────────────────────────┤ ▼
136+
│ Layer 2: Controller │ ┌────────────────────────────┐
137+
│ (PredictController) │ │ Layer 2: Services │
138+
└───────────┬─────────────┘ │ (MarketDataService, etc.) │
139+
│ └─────────┬──────────────────┘
140+
▼ │
141+
┌─────────────────────────┐ │
142+
│ Layer 2: Services │ │
143+
│ (TradingService, etc.) │ │
144+
└───────────┬─────────────┘ │
145+
└─────────────┬─────────────┘
146+
147+
148+
┌──────────────────────────────────────────────────────────┐
149+
│ Layer 1: Adapters (PolymarketAdapter, KalshiAdapter) │
150+
└───────────────────────────┬──────────────────────────────┘
151+
152+
153+
┌──────────────────────────────────────────────────────────┐
154+
│ External APIs (Polymarket APIs, Kalshi APIs) │
155+
└──────────────────────────────────────────────────────────┘
156+
```
157+
117158
### Layer 1 — Adapters
118159

119160
Adapters are thin protocol boundaries that translate provider APIs into the canonical Predict model.
@@ -480,6 +521,23 @@ Reference [testing.md](./testing.md).
480521

481522
PredictNext should present a deliberate public surface.
482523

524+
Module Boundary:
525+
526+
```text
527+
┌────────────────────────────────────────────────────────────────┐
528+
│ PredictNext Module Boundary │
529+
├───────────────────────────────┬────────────────────────────────┤
530+
│ PUBLIC (index.ts) │ INTERNAL │
531+
├───────────────────────────────┼────────────────────────────────┤
532+
│ • Views │ • Services │
533+
│ • Components │ • Adapters │
534+
│ • Hooks │ • Widgets │
535+
│ • Types │ • Utils │
536+
│ • Selectors │ • Constants │
537+
│ │ • Provider DTOs │
538+
└───────────────────────────────┴────────────────────────────────┘
539+
```
540+
483541
### Public API
484542

485543
The package-level `index.ts` should export only the stable product surface:

app/components/UI/PredictNext/docs/components.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,31 @@ Core rules:
1919
- Keep domain formatting and rendering logic inside primitives when it improves reuse
2020
- Primitives are pure (no hooks) — widgets wire data hooks to primitives — views compose widgets
2121

22+
```text
23+
TIER 3: Views (route-level)
24+
┌─────────────┐ ┌──────────────┐ ┌─────────────┐ ┌─────────────────┐
25+
│ PredictHome │ │ EventDetails │ │ OrderScreen │ │ TransactionsView│
26+
└──────┬──────┘ └──────┬───────┘ └──────┬──────┘ └────────┬────────┘
27+
│ │ │ │
28+
v v v v
29+
TIER 2: Widgets (composed sections)
30+
┌───────────┐ ┌──────────────────┐ ┌─────────────────┐ ┌──────────────┐
31+
│ EventFeed │ │ FeaturedCarousel │ │ PortfolioSection│ │ OrderForm │
32+
└─────┬─────┘ └────────┬─────────┘ └────────┬────────┘ └──────┬───────┘
33+
│ │ │ │
34+
v v v v
35+
TIER 1: Primitives (reusable building blocks)
36+
┌───────────┐ ┌───────────────┐ ┌──────────────┐ ┌──────────────┐
37+
│ EventCard │ │ OutcomeButton │ │ PositionCard │ │ PriceDisplay │
38+
└───────────┘ └───────────────┘ └──────────────┘ └──────────────┘
39+
```
40+
41+
Legend:
42+
43+
- Primitives: Pure (no hooks), receive data via props
44+
- Widgets: Wire data hooks to primitives
45+
- Views: Compose widgets with imperative/guard hooks
46+
2247
Related docs:
2348

2449
- [hooks](./hooks.md)
@@ -51,6 +76,14 @@ Why this shape works:
5176
- sport, crypto, binary, and multi-market rendering differences remain internal
5277
- compact row and full card layouts can share the same public API
5378

79+
```text
80+
<EventCard event={event}> ← provides context
81+
├── <EventCard.Header /> ← reads from context
82+
├── <EventCard.Markets /> ← reads from context
83+
├── <EventCard.Footer /> ← reads from context
84+
└── <EventCard.Scoreboard/>← reads from context (optional)
85+
```
86+
5487
Suggested file structure:
5588

5689
```text

app/components/UI/PredictNext/docs/error-handling.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,23 @@ The category model keeps UI behavior predictable and limits bespoke handling.
6464

6565
## Error Handling by Layer
6666

67+
```text
68+
Layer: ADAPTER SERVICE HOOK COMPONENT
69+
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
70+
│ │ │ │ │ │ │ │
71+
Error: │ Raw │────────>│Absorb│────────>│Expose│─────>│Render│
72+
│throw │ catch │retry │ throw │state │ props │ UI │
73+
│ │ │wrap │ Predict │ │ │state │
74+
└──────┘ │cache │ Error └──────┘ └──────┘
75+
│fall │
76+
│back │
77+
└──────┘
78+
79+
Transient failures: ABSORBED (retry, cache fallback, reconnect)
80+
User-actionable: SURFACED as PredictError with code + recoverable
81+
UI renders: empty | unavailable | action failed | degraded
82+
```
83+
6784
### Adapter Layer
6885

6986
Responsibilities:

app/components/UI/PredictNext/docs/hooks.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,28 @@ This pattern keeps deep hooks stable and reusable while allowing view code to st
622622

623623
Not every tier uses hooks. The rule is: primitives are pure, widgets wire data, views orchestrate.
624624

625+
```text
626+
Views (PredictHome, EventDetails, OrderScreen)
627+
628+
├── Guard hooks: usePredictGuard
629+
├── Nav hooks: usePredictNavigation
630+
├── Imperative: useTrading, useTransactions
631+
632+
└── Widgets (EventFeed, PortfolioSection, OrderForm)
633+
634+
├── Data hooks: useEventList, useFeaturedEvents, usePositions, useBalance
635+
│ │
636+
│ v
637+
│ BaseDataService (MarketDataService, PortfolioService)
638+
│ │
639+
│ v
640+
│ PredictAdapter
641+
642+
└── Primitives (EventCard, OutcomeButton, PositionCard)
643+
644+
└── No hooks. Pure props only.
645+
```
646+
625647
| Tier | Uses hooks? | Uses services directly? | Receives props? |
626648
| ------------------------------------------- | ------------------------------ | ----------------------- | ------------------------------ |
627649
| Primitives (EventCard, OutcomeButton, etc.) | No | No | Yes — data + callbacks |
@@ -642,6 +664,14 @@ This split means:
642664

643665
## Hook Composition Rules
644666

667+
```text
668+
Read path:
669+
Widget → useEventList → useQuery(queryKey) → messenger → MarketDataService → adapter → API
670+
671+
Write path:
672+
View → useTrading → Engine.context.PredictController → TradingService → adapter → API
673+
```
674+
645675
1. Imperative hooks compose services, not each other.
646676
2. Widgets compose data query hooks with primitives.
647677
3. Views compose widgets and imperative/guard hooks.

app/components/UI/PredictNext/docs/migration/README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,28 @@ Phase 6 — New UI replaces old UI:
5353
(translation layer no longer needed for migrated screens)
5454
```
5555

56+
Inside-Out Migration Order:
57+
58+
```text
59+
┌──────────────────────────────────────────────────────────┐
60+
│ Inside-Out Migration Order │
61+
│ │
62+
│ ┌────────────────────────────────────────────┐ │
63+
│ │ Phase 6: UI (Hooks, Components, Views) │ │
64+
│ │ ┌──────────────────────────────────┐ │ │
65+
│ │ │ Phase 5: PredictController │ │ │
66+
│ │ │ ┌────────────────────────┐ │ │ │
67+
│ │ │ │ Phase 3-4: Services │ │ │ │
68+
│ │ │ │ ┌──────────────┐ │ │ │ │
69+
│ │ │ │ │ Phase 2: │ │ │ │ │
70+
│ │ │ │ │ Adapter │ │ │ │ │
71+
│ │ │ │ └──────────────┘ │ │ │ │
72+
│ │ │ └────────────────────────┘ │ │ │
73+
│ │ └──────────────────────────────────┘ │ │
74+
│ └────────────────────────────────────────────┘ │
75+
└──────────────────────────────────────────────────────────┘
76+
```
77+
5678
## 3. PredictNext/ Approach
5779

5880
- New architecture lives in `app/components/UI/PredictNext/`.
@@ -98,6 +120,32 @@ Note: Phases 3 and 4 can run in parallel because read services and write service
98120

99121
## 5. Parallel Work Streams
100122

123+
Parallel Work Streams:
124+
125+
```text
126+
┌──────────────────────────────────────────────────────────┐
127+
│ Parallel Work Streams │
128+
│ │
129+
│ Phase 1 (Foundation) │
130+
│ │ │
131+
│ ▼ │
132+
│ Split Streams ──────────────────────────┐ │
133+
│ │ │ │
134+
│ Stream A (Read Path) Stream B (Write Path) │
135+
│ Phase 2 → Phase 3 Phase 2 → Phase 4 │
136+
│ │ │ │
137+
│ └────────────────┬─────────────────┘ │
138+
│ ▼ │
139+
│ Phase 5 (Merge Point) │
140+
│ │ │
141+
│ ▼ │
142+
│ Phase 6 (UI Migration) │
143+
│ │ │
144+
│ ▼ │
145+
│ Phase 7 (Cleanup) │
146+
└──────────────────────────────────────────────────────────┘
147+
```
148+
101149
### Stream A: Read path
102150

103151
`Phase 1 → Phase 2 → Phase 3`

app/components/UI/PredictNext/docs/services.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,22 @@ export interface PredictController {
139139

140140
The controller surface stays intentionally small even if internal services are sophisticated. That is the point of the design.
141141

142+
```text
143+
Hooks (read path) Hooks (write path)
144+
| |
145+
| [bypasses controller] v
146+
| PredictController
147+
| (~10 methods)
148+
| / | \
149+
v v v v
150+
MarketData Portfolio Trading Transaction LiveData Analytics
151+
Service Service Service Service Service Service
152+
\ \ | | / /
153+
\_________ \________|_______|________/ ______/
154+
|
155+
PredictAdapter
156+
```
157+
142158
## 3. MarketDataService (BaseDataService)
143159

144160
`MarketDataService` is the read model for market and discovery data.
@@ -416,6 +432,33 @@ The order lifecycle is modeled inside `TradingService`, not in hooks or screens:
416432

417433
The UI can render the current state, but it should not be responsible for deciding transitions.
418434

435+
```text
436+
+-------+ +------------+
437+
| ERROR | <------- | ANY STATE |
438+
+-------+ +------------+
439+
|
440+
| (reset)
441+
v
442+
+-------+ +------------+
443+
+----> | IDLE | <------> | PREVIEWING |
444+
| +-------+ +------------+
445+
| | |
446+
| v |
447+
| +------------+ |
448+
| | DEPOSITING | <---------+
449+
| +------------+
450+
| |
451+
| v
452+
| +---------------+
453+
| | PLACING_ORDER |
454+
| +---------------+
455+
| |
456+
| v
457+
| +---------+
458+
+----- | SUCCESS |
459+
+---------+
460+
```
461+
419462
### Internal responsibilities
420463

421464
`TradingService` hides substantial complexity:
@@ -658,6 +701,16 @@ Typical dependencies:
658701
- `TransactionService``PredictAdapter`
659702
- `LiveDataService``PredictAdapter`
660703

704+
```text
705+
TradingService LiveDataService
706+
/ | | \ / \
707+
v v v v v v
708+
Transac Market Portfol Analytics PredictAdapter
709+
Service Data folio Service ^
710+
| \ / |
711+
+--------+----+---------------------+
712+
```
713+
661714
`AnalyticsService` should not depend back on feature services. `PredictAdapter` should not depend upward on services.
662715

663716
### Constructor injection

0 commit comments

Comments
 (0)