Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

Commit af0df1c

Browse files
committed
feat: add specs for charts, views migration, and table effort
- Introduced spec 10 for AntV G2 charts, kbar command palette, shiki syntax highlighting, and markdown rendering. - Added spec 11 outlining the migration plan for views, including dependencies and acceptance criteria for each batch. - Created spec 12 detailing the table effort, including decisions on using TanStack Table v8, public API, and mobile rendering strategy. Signed-off-by: Innei <tukon479@gmail.com>
1 parent 70b6c55 commit af0df1c

13 files changed

Lines changed: 4517 additions & 0 deletions
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# Vue 3 → React Migration · Roadmap
2+
3+
**Date**: 2026-05-06
4+
**Scope**: New greenfield repo `admin-react`. Source repo (`admin-vue3/apps/admin`, v7.0.1) is frozen during migration and replaced at cutover.
5+
**Goal**: 1:1 functional parity + design redesign (Linear dark-canvas system) on a modern React stack.
6+
7+
This document is the **index**. It carries decisions and milestones, not implementation detail. Each sub-spec under this folder owns one slice of the migration.
8+
9+
---
10+
11+
## Sub-spec layout
12+
13+
```
14+
docs/superpowers/specs/2026-05-06-react-migration/
15+
├── 00-roadmap.md ← this file
16+
├── 01-repo-skeleton.md ← Vite 8, tsconfig, oxlint, env, html, deps, dir layout
17+
├── 02-design-tokens.md ← Linear DESIGN.md → css.ts tokens, theme switching
18+
├── 03-ui-primitives.md ← Base UI wrappers, API + variant + a11y contracts
19+
├── 04-state-layer.md ← Zustand stores, Jotai atoms, event-bus removal, persistence
20+
├── 05-data-layer.md ← request.ts port, TanStack Query patterns, socket.io hook
21+
├── 06-routing-auth.md ← react-router tree, ProtectedRoute, better-auth + passkey
22+
├── 07-layouts-patterns.md ← AppShell, Sidebar, MasterDetailLayout, header-action injection
23+
├── 08-form-system.md ← react-hook-form + zod, ConfigForm DSL port
24+
├── 09-editors.md ← haklex direct-mount, monaco, codemirror, xterm, draft system
25+
├── 10-charts-misc.md ← G2 hook, kbar swap, shiki/marked, diffs, excalidraw, confetti
26+
├── 11-views-migration.md ← 21 views in batches; preconditions + acceptance per batch
27+
└── 12-table-effort.md ← dedicated table effort (TanStack Table or hand-built)
28+
```
29+
30+
**Writing order**: this file + 01–06 first (P0 + P1 ammunition). 07–10 and 12 are written when P1 calibrates tokens and primitives. 11 is written when P2 settles patterns.
31+
32+
---
33+
34+
## Tech stack decisions
35+
36+
| Concern | Choice | Reason |
37+
|---|---|---|
38+
| Framework | React 19 + Vite 8 + `@vitejs/plugin-react-swc` | Vite 8 already on source repo; SWC for speed |
39+
| Routing | `react-router` v7 (classic `<Routes>/<Route>`) | User-specified; data router (loaders) explicitly rejected |
40+
| Server state | `@tanstack/react-query` 5.x + `query-persist-client-core` | 1:1 port; `['ai']` prefix persisted to localStorage |
41+
| Session state | Zustand | auth, theme, layout backbone, ui — singletons that span the session |
42+
| Page-local state | Jotai | drawer toggles, form drafts, selections, AI task queue, layout slots (header actions, page title) |
43+
| UI primitives | Base UI (`@base-ui-components/react`) | headless; pairs with css.ts |
44+
| Styling | css.ts (`@vanilla-extract/css` + vite plugin) | Compile-time CSS; tokens live as TS exports |
45+
| Design system | Linear dark-canvas (per pasted DESIGN.md) | Lavender accent, four-step surface ladder, no second chromatic accent |
46+
| Forms | `react-hook-form` + `zod` | `zod` already in source repo |
47+
| Animation | `motion` | User-specified |
48+
| Icons | `lucide-react` | 1:1 swap from `lucide-vue-next` |
49+
| Toast | `sonner` | 1:1 swap from `vue-sonner` |
50+
| Command palette | `kbar` | Original React lib; replaces `@bytebase/vue-kbar` |
51+
| Code editors | `@monaco-editor/react`, CodeMirror 6 hand-rolled | Slash menu / WYSIWYG depth justifies hand-roll for CM6 |
52+
| Rich editor | `@haklex/*` mounted directly (no Vue bridge) | `@mx-admin/rich-react` already React-native |
53+
| Charts | `@antv/g2` via `useG2Chart` hook | Library is framework-agnostic |
54+
| Terminal | `xterm` via `useEffect` mount | Library is framework-agnostic |
55+
| Realtime | `socket.io-client` via `useSocketIO` hook | Replaces `window.bus` event bus |
56+
| Auth | `better-auth` + `@better-auth/passkey` | Framework-agnostic; same flow |
57+
| API client | `ofetch` + existing `@mx-space/api-client` types | Both framework-agnostic; port unchanged |
58+
| Lint | `oxlint` | Sticks with current toolchain |
59+
60+
### Explicitly rejected
61+
62+
- TanStack Router data router (loaders/actions). Component routing only.
63+
- Tailwind / UnoCSS for the new repo (css.ts wins).
64+
- Naive UI compatibility shim. Full primitive rewrite.
65+
- SSR. SPA only, same as source.
66+
67+
---
68+
69+
## State allocation rule (canonical)
70+
71+
| Bucket | Goes to |
72+
|---|---|
73+
| Server data (anything fetched from API) | TanStack Query |
74+
| Session-level singletons (auth, theme, layout backbone, app config) | Zustand |
75+
| Page-local ephemeral (drawer open, form draft, selected id, AI task queue, header-action slot) | Jotai |
76+
| Truly component-private | `useState` |
77+
78+
Cross-component fan-out without server fetch → Jotai by default. Promote to Zustand only when state outlives the route.
79+
80+
---
81+
82+
## Dependency graph
83+
84+
```
85+
00-roadmap (index)
86+
01-repo ──┬─→ 02-tokens ──→ 03-primitives ──┐
87+
│ ├─→ 07-layouts ──┐
88+
├─→ 04-state ──────────────────────┤ │
89+
├─→ 05-data ───────────────────────┤ ├─→ 11-views
90+
└─→ 06-routing-auth ───────────────┘ │
91+
92+
08-form ──────────────────────┤
93+
09-editors ───────────────────┤
94+
10-charts-misc ───────────────┤
95+
12-table ─────────────────────┘
96+
```
97+
98+
A spec may be **drafted** before its upstream dependencies stabilize, but must be **finalized** in graph order.
99+
100+
---
101+
102+
## Milestones
103+
104+
| Phase | Window | Deliverable | Spec dependency |
105+
|---|---|---|---|
106+
| **P0 thin-foundation** | ~1 wk | repo scaffolding, theme tokens, 5 primitives (Button/Input/Card/Modal/Toast), request layer, query client, router shell, auth client | 01, 02, 03 (subset), 04 (subset), 05 (subset), 06 (subset) |
107+
| **P1 vertical slice** | ~1.5 wk | `/login`, `/setup-api`, `/setup`, AppShell + Sidebar, `/dashboard` (incl. G2 charts, socket, kbar). Tokens **calibrated** against real surface. | 06, 07 (initial), 10 (G2 + kbar partial) |
108+
| **P2 primitive backfill + patterns** | ~1.5 wk | Drawer, Tabs, Tooltip, Popover, Select, Switch, Checkbox, Tag, Skeleton, Empty, Pagination, Avatar, Badge, Progress, Spinner, Ellipsis, Scroll. MasterDetailLayout, ConfigForm DSL, placeholder Table API. | 03 (full), 07 (full), 08 |
109+
| **P3 horizontal sweep** | ~5 wk | 16 views in 6 batches (3a list-read, 3b config, 3c analyze, 3d files, 3e AI, 3f extras). Batches parallelizable. | 11 |
110+
| **P4 rich-write closure** | ~3 wk | `/posts/edit`, `/notes/edit`, `/pages/edit`, `/posts/category`. haklex direct-mount, draft system, agent sidebar, metadata drawer. | 09 |
111+
| **P5 wrap-up** | ~1 wk | debug routes, dev tools, first-paint optimization, bundle split, smoke E2E. ||
112+
| **Table track** | parallel from end of P2 | Real Table replaces placeholder. | 12 |
113+
114+
**Total**: ~13 weeks for the main track + Table track running parallel from week 4.
115+
116+
---
117+
118+
## Critical-path risks
119+
120+
1. **Table is a blocker for ~50% of views.** P2 ships a placeholder `useDataTableState` API + minimal renderer so P3 can proceed; the Table track replaces internals later without view-side rewrites.
121+
2. **haklex bridge removal** is mechanically simple but the **draft system, agent chat state, and Lexical theme injection** need careful porting. Pin haklex package versions across the migration window.
122+
3. **socket.io currently dispatches via `window.bus`.** Migration moves to `useSocketIO` hook + Jotai/context fan-out. Audit every `window.bus` consumer before removing the bus.
123+
4. **css.ts is compile-time.** Dynamic per-instance styling (e.g. `motion` interpolations) must use inline style or `style` props, not generated css.ts variants. 02 + 03 nail down the contract.
124+
5. **Linear tokens** will get hammered during P1. Treat 02 as "v0 → calibrated v1 at end of P1". Do not freeze before that.
125+
6. **Auth cookies need same-origin (or properly configured CORS).** Confirm during 06 implementation; affects local dev proxy config in 01.
126+
127+
---
128+
129+
## Out of scope
130+
131+
- Backend changes. The migration consumes the existing mx-core API surface unchanged.
132+
- E2E test framework choice. Smoke E2E in P5 uses whatever is light (Playwright suggested but not mandated here).
133+
- i18n. Source repo is Chinese-only; new repo inherits the same posture.
134+
- Mobile app. Responsive web only.
135+
136+
---
137+
138+
## Cross-references to source surveys
139+
140+
The six parallel surveys feeding this roadmap are summarized inline across 01–12. The raw survey output is preserved in agent transcripts and not re-pasted here.
141+
142+
- Routes & views — feeds 11
143+
- State stores — feeds 04
144+
- API & data — feeds 05
145+
- UI components — feeds 03, 08
146+
- Heavy assets — feeds 09, 10
147+
- Auth & build — feeds 01, 06

0 commit comments

Comments
 (0)