|
| 1 | +# Split TryDiscovery.tsx into focused modules |
| 2 | + |
| 3 | +## Problem |
| 4 | + |
| 5 | +`apps/web/src/pages/TryDiscovery.tsx` is 910 lines — well above the 800-line hard limit. A FILE SIZE EXCEPTION was added to unblock merge of the trial onboarding MVP, but the exception rationale ("tightly coupled SSE state machine + UI rendering") is incorrect. The SSE lifecycle produces three clean values (`events`, `connection`, `isSlow`) consumed by the render tree as plain data — no closure coupling exists. |
| 6 | + |
| 7 | +## Research Findings |
| 8 | + |
| 9 | +### Current structure (910 lines) |
| 10 | +- **Lines 51–54**: `ConnectionState` interface |
| 11 | +- **Lines 56–322**: `TryDiscovery` main component (SSE hook + render) |
| 12 | + - Lines 66–180: SSE lifecycle (refs, useEffect, reconnect logic) — **extractable as custom hook** |
| 13 | + - Lines 182–196: auto-scroll + memoized view derivation |
| 14 | + - Lines 198–321: JSX render tree |
| 15 | +- **Lines 328–374**: `DiscoveryView` interface + `deriveView()` — **extractable as view model** |
| 16 | +- **Lines 381–474**: `FeedItem` type + `buildFeed()` — **extractable as view model** |
| 17 | +- **Lines 480–577**: `DiscoveryHeader` + `ConnectionBadge` — **extractable as header components** |
| 18 | +- **Lines 584–666**: `StageSkeleton` + `TerminalErrorPanel` — **extractable as status components** |
| 19 | +- **Lines 668–865**: `EventCard`, `Card`, `KnowledgeGroupCard`, `IdeaCard`, `AgentActivityGroupCard`, `ActivityRoleIcon` — **extractable as feed card components** |
| 20 | +- **Lines 875–910**: `cleanActivityText()`, `extractRepoName()`, `eventDedupKey()` — **extractable as utils** |
| 21 | + |
| 22 | +### Consumers |
| 23 | +- `App.tsx` imports `TryDiscovery` (page component) |
| 24 | +- `try-discovery-dedup.test.ts` imports `eventDedupKey` |
| 25 | +- `try-discovery-build-feed.test.ts` imports `buildFeed` |
| 26 | + |
| 27 | +### Target layout |
| 28 | +``` |
| 29 | +apps/web/src/ |
| 30 | + hooks/useTrialEvents.ts — SSE lifecycle hook (~130 lines) |
| 31 | + lib/trial-view-model.ts — deriveView, buildFeed, types (~150 lines) |
| 32 | + lib/trial-utils.ts — cleanActivityText, extractRepoName, eventDedupKey (~45 lines) |
| 33 | + components/trial/DiscoveryHeader.tsx — DiscoveryHeader + ConnectionBadge (~100 lines) |
| 34 | + components/trial/DiscoveryCards.tsx — EventCard, Card, IdeaCard, KnowledgeGroupCard, AgentActivityGroupCard, ActivityRoleIcon, StageSkeleton, TerminalErrorPanel (~290 lines) |
| 35 | + pages/TryDiscovery.tsx — main page (~150 lines, imports everything) |
| 36 | +``` |
| 37 | + |
| 38 | +## Implementation Checklist |
| 39 | + |
| 40 | +- [ ] Create `apps/web/src/hooks/useTrialEvents.ts` — extract `ConnectionState`, SSE refs, useEffect, reconnect logic |
| 41 | +- [ ] Create `apps/web/src/lib/trial-view-model.ts` — extract `DiscoveryView`, `FeedItem`, `deriveView()`, `buildFeed()` |
| 42 | +- [ ] Create `apps/web/src/lib/trial-utils.ts` — extract `cleanActivityText()`, `extractRepoName()`, `eventDedupKey()` |
| 43 | +- [ ] Create `apps/web/src/components/trial/DiscoveryHeader.tsx` — extract `DiscoveryHeader`, `ConnectionBadge` |
| 44 | +- [ ] Create `apps/web/src/components/trial/DiscoveryCards.tsx` — extract all card components + `StageSkeleton` + `TerminalErrorPanel` |
| 45 | +- [ ] Rewrite `apps/web/src/pages/TryDiscovery.tsx` to import from new modules |
| 46 | +- [ ] Update test imports (`try-discovery-dedup.test.ts`, `try-discovery-build-feed.test.ts`) |
| 47 | +- [ ] Remove FILE SIZE EXCEPTION comment from TryDiscovery.tsx |
| 48 | +- [ ] Verify TryDiscovery.tsx is under 500 lines |
| 49 | +- [ ] Run lint, typecheck, test, build — all green |
| 50 | + |
| 51 | +## Acceptance Criteria |
| 52 | + |
| 53 | +- [ ] `TryDiscovery.tsx` is under 200 lines (ideally ~150) |
| 54 | +- [ ] No new file exceeds 300 lines |
| 55 | +- [ ] All existing tests pass without modification (only import paths change) |
| 56 | +- [ ] `pnpm lint && pnpm typecheck && pnpm test && pnpm build` all green |
| 57 | +- [ ] No behavioral changes — pure refactor |
0 commit comments