Skip to content

Commit e781649

Browse files
committed
refactor: transition from MobX to React Query and clean up legacy code
- Updated the `CLAUDE.md` documentation to reflect the migration from MobX to React Query for state management, including changes to project context and data fetching practices. - Removed deprecated MobX hooks and utilities, streamlining the codebase and enhancing maintainability. - Consolidated project context management under `ProjectContext`, ensuring all new features utilize React Query for data handling. These changes support a more efficient architecture and improve the overall clarity of the application.
1 parent 2fea226 commit e781649

23 files changed

+206
-1290
lines changed

CLAUDE.md

Lines changed: 48 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
title: TON Console — AI Project Guide
44
version: 1.0.0
5-
last_verified: 2025-10-27
5+
last_verified: 2025-10-31
66
owners:
77

88
* <fill in: owner GitHub handle/email>
@@ -18,7 +18,7 @@ This file is a source of truth for AI assistants and developers:
1818
* sets unambiguous do's and don'ts;
1919
* contains **safe blocks for AI auto‑updates** without clutter.
2020

21-
> Rule #1: **For new CRUD/server data we use React Query.** MobX is allowed only in inherited/complex areas and is gradually phased out.
21+
> Rule #1: **For new CRUD/server data we use React Query.**
2222
2323
---
2424

@@ -42,7 +42,6 @@ This file is a source of truth for AI assistants and developers:
4242
| Core | React **19.2.0**, TypeScript **5.9.3** (strict) | **Only** functional components |
4343
| Build | Vite **5.4.6** | Code-splitting by routes/features |
4444
| Server state | **@tanstack/react-query 5.90.5** | Mandatory for CRUD/fetching |
45-
| Local/legacy | MobX **6.15.0** | ❗️legacy only; migrating away |
4645
| UI | Chakra UI **2.10.9** | Single theme/tokens |
4746
| Charts | Recharts **2.5.0** | Time series, see §7 |
4847
| Routing | React Router DOM **6.9.0** | Pages are thin, composition only |
@@ -68,17 +67,18 @@ src/
6867
│ │ │ ├─ queries.ts # React Query hooks (new standard)
6968
│ │ │ └─ interfaces/ # domain types
7069
│ │ └─ ui/ # "dumb" UI components
71-
│ ├─ webhooks/ # to migrate to React Query
72-
│ ├─ statistics/ # MobX (legacy)
73-
│ └─ liteproxy/ # MobX (legacy)
70+
│ ├─ webhooks/ # React Query
71+
│ ├─ statistics/ # React Query
72+
│ └─ liteproxy/ # React Query
7473
├─ entities/ # domain models/entities (if shared)
7574
├─ shared/
7675
│ ├─ api/
7776
│ │ └─ console/ # ⚙️ auto-generated from swagger.yaml
78-
│ ├─ stores/ # global stores: projectsStore, userStore, appStore
7977
│ ├─ lib/ # utilities (Loadable — legacy)
8078
│ ├─ ui/ # reusable UI components
81-
│ └─ hooks/ # shared hooks (legacy helpers)
79+
│ ├─ hooks/ # shared hooks (legacy helpers)
80+
│ ├─ contexts/ # ProjectContext.tsx — selected project context
81+
│ └─ queries/ # projects.ts — React Query for projects
8282
└─ processes/ # side-effects initialization
8383
```
8484

@@ -123,7 +123,6 @@ src/
123123

124124
**Do not**
125125

126-
* ❌ Write new MobX code for server data.
127126
* ❌ Create global stores for feature-local concerns.
128127
* ❌ Mix several unrelated API calls in a single `queryFn`.
129128

@@ -137,7 +136,7 @@ src/
137136

138137
```ts
139138
// NEW: Use useProjectId() hook (preferred in new features)
140-
import { useProjectId } from 'src/shared/contexts/ProjectIdContext';
139+
import { useProjectId } from 'src/shared/contexts/ProjectContext';
141140

142141
const projectId = useProjectId();
143142

@@ -155,14 +154,10 @@ return useQuery({
155154
});
156155
```
157156

158-
**Important: projectId in new features (MIGRATION IN PROGRESS)**
157+
**Important: projectId in new features**
159158

160-
***NEW CODE**: Use `const projectId = useProjectId()` from `ProjectIdContext`
161-
***LEGACY**: Do NOT use `projectsStore.selectedProject?.id` in new query hooks
162-
* **Migration Status**: Currently transitioning from MobX `projectsStore` to React Context API
163-
* `ProjectIdContext` acts as temporary bridge that syncs values from `projectsStore`
164-
* `with-project-id.tsx` translates store changes to context using MobX `reaction()`
165-
* When Phase 3 complete: Context will become sole source of truth, bridge will be removed
159+
***NEW CODE**: Use `const projectId = useProjectId()` from `ProjectContext`
160+
* **Current Status**: `ProjectContext` is the single source of truth (localStorage persistence built-in).
166161
* Include `projectId` in all query keys to prevent cross-project cache collisions
167162

168163
**Mutations & cache**
@@ -188,16 +183,6 @@ return useQuery({
188183
* Simple add: `queryClient.setQueryData(['api-keys', projectId], updater)`.
189184
* Complex cases: `queryClient.invalidateQueries({ queryKey: ['api-keys', projectId] })`.
190185

191-
**observer()**
192-
193-
* Wrap a component with `observer()` **only** if it reads a MobX store (e.g., legacy features).
194-
* Do NOT use in new React Query features.
195-
196-
## 5.2 MobX (legacy)
197-
198-
* Allowed only in existing complex features (`statistics`, `liteproxy`).
199-
* No new MobX code; see migration plan — §10.
200-
201186
---
202187

203188
# 6) Working with the API and models
@@ -293,98 +278,28 @@ npm run generate-airdrop2
293278

294279
---
295280

296-
# 10) Migration plan (MobX → React Query)
297-
298-
**Current Phase: Phase 1 — Simple stores migration**
299-
300-
**Status (2025-10-29) — Detailed Migration Plan Created**
301-
302-
**Phase 1 — Simple Leaf Stores (next, 2-3 days)**
303-
* ✅ API Keys — migrated (reference)
304-
* ✅ Balance — global hook with `refetchInterval: 3000`, `refetchIntervalInBackground: true`
305-
* ✅ Rates — migrated to useQuery
306-
* ✅ Webhooks — migrated to useQuery + error handling for 501
307-
* Created `ProjectIdContext` as temporary bridge to `projectsStore`
308-
* Added `with-project-id.tsx` to sync MobX store → React Context
309-
* Implemented projectId capture in mutations to prevent race conditions
310-
* Added informational 501 error message with API docs link
311-
* ⏳ TonApiStatsStore — next after webhooks
312-
* ⏳ LiteproxysStore, RestApiTiersStore, CNFTStore, FaucetStore
313-
314-
**Phase 1.5 — Replace projectsStore References (0.5-1 day)**
315-
* ⏳ Remove all `projectsStore.selectedProject?.id` from codebase
316-
* ⏳ Replace with `useProjectId()` hook from ProjectIdContext
317-
318-
**Phase 2 — Remaining Stores + Localization (2-3 days)**
319-
* ⏳ JettonStore (wallet-based, no projectId dependency)
320-
* ⏳ DappStore (enable AppMessagesStore refactoring)
321-
* ⏳ Localize InvoicesTableStore & AnalyticsHistoryTableStore to component-level hooks
322-
323-
**Phase 2.5 — Complex Store Refactoring (2-3 days)**
324-
* ⏳ AppMessagesStore → split into 4 hooks
325-
* ⏳ InvoicesAppStore → split into 2 hooks
326-
* ⏳ AnalyticsQueryStore → split into 3+ hooks
327-
328-
**Phase 3 — ProjectsStore Removal (1-2 days, CRITICAL)**
329-
* ⏳ Delete `src/entities/project/model/projects.store.ts`
330-
* ⏳ Move logic to `shared/queries/projects.ts`
331-
* ⏳ Requires all 15 dependent stores migrated first
332-
333-
**Phase 4 — Final Stores (1-2 days)**
334-
* ⏳ UserStore (decision: migrate or keep as exception)
335-
* ⏳ AppStore (→ `useAppInitialized()` hook)
336-
* ⏳ Analytics supporting stores (GPT, Graph, Request)
337-
* ⏳ AirdropsStore
338-
339-
**See:** `MIGRATION_PLAN.md` for detailed phases, checklists, and risk analysis
340-
341-
**Steps**
342-
343-
1. Create `model/queries.ts` with domain types in the feature.
344-
2. Move fetching from Store to `useQuery`/`useMutation`.
345-
3. Add DTO → domain mappers.
346-
4. Update UI to use hooks instead of store.
347-
5. Keep `observer()` only where `projectsStore` is read.
348-
6. Remove the legacy store and `useLocalObservableWithDestroy`.
349-
7. Verify refetch on `projectId` change.
281+
# 10) Migration history (MobX → React Query)
350282

351-
---
283+
**Historical context:** The project previously used MobX stores for server state management. In 2025, we completed a full migration to React Query (`@tanstack/react-query`) for all CRUD and data fetching operations.
352284

353-
# 11) Global stores (rare exceptions)
285+
**Current state:**
286+
- ✅ All major features use React Query (API Keys, Webhooks, Statistics, Liteproxy, Pricing, Balance, Rates, NFT, Faucet, App Messages, Jetton, Projects)
287+
- ⚠️ A few isolated modules (Invoices, Analytics, Airdrop) retain localized MobX stores within their components for internal state management only
288+
- ✅ No global stores — `ProjectContext` manages project selection with React Query
354289

355-
Allowed:
356-
357-
* `projectsStore` — current project selection (often needed for `project_id`)
358-
* `userStore` — auth/profile
359-
* `appStore` — global UI state
360-
361-
**Prohibited:** adding feature stores into `root.store.ts`. That indicates an incorrect responsibility boundary.
290+
**For new features:** Always use React Query. See patterns in §5.1 and examples in §19.
362291

363292
---
364293

365-
# 12) Self‑update protocol (for AI)
366-
367-
**Goal:** keep this file up-to-date and compact, without clutter.
368-
369-
**Golden rules**
370-
371-
1. Do not duplicate rules; if there is a conflict, link to the existing point and refine the wording in a single place.
372-
373-
**Before writing changes AI must:**
374-
375-
* make sure the changes reflect the actual state of the code/repo;
376-
377-
---
378-
379-
# 13) Security and secrets
294+
# 11) Security and secrets
380295

381296
* Do not log secrets/API keys/tokens.
382297
* Environment configuration via **ENV**, no hardcoding.
383298
* TON API permissions — only via backend proxies where applicable.
384299

385300
---
386301

387-
# 14) Performance
302+
# 12) Performance
388303

389304
* Real-time: use `refetchInterval` only where needed (see Balance).
390305
* Use `staleTime` consciously; by default treat data as "stale" for freshness.
@@ -393,15 +308,15 @@ Allowed:
393308

394309
---
395310

396-
# 15) UX, accessibility
311+
# 13) UX, accessibility
397312

398313
* States (loading/error/empty) are mandatory.
399314
* Keyboard accessibility for modals and focus — Chakra is fine by default, do not break it.
400315
* All text is in English.
401316

402317
---
403318

404-
# 16) Time series and periods (TON metrics)
319+
# 14) Time series and periods (TON metrics)
405320

406321
* Time units in API: unix (seconds).
407322
* Common case: last 7 days with 30-minute intervals.
@@ -410,7 +325,7 @@ Allowed:
410325

411326
---
412327

413-
# 17) Git and workflow
328+
# 15) Git and workflow
414329

415330
* Branch from `master`. Commits are atomic.
416331
* Commit messages are meaningful.
@@ -426,13 +341,27 @@ Allowed:
426341

427342
---
428343

429-
# 19) Examples (reference snippets)
344+
# 16) Self‑update protocol (for AI)
430345

431-
## 19.1 CRUD component (pattern)
346+
**Goal:** keep this file up-to-date and compact, without clutter.
347+
348+
**Golden rules**
349+
350+
1. Do not duplicate rules; if there is a conflict, link to the existing point and refine the wording in a single place.
351+
352+
**Before writing changes AI must:**
353+
354+
* make sure the changes reflect the actual state of the code/repo;
355+
356+
---
357+
358+
# 17) Examples (reference snippets)
359+
360+
## 17.1 CRUD component (pattern)
432361

433362
```tsx
434363
// features/tonapi/api-keys/ui/ApiKeys.tsx
435-
export const ApiKeys: FC = observer(() => {
364+
export const ApiKeys: FC = () => {
436365
const { data: apiKeys, isLoading, error } = useApiKeysQuery();
437366
const { mutate: deleteKey, isPending } = useDeleteApiKeyMutation();
438367

@@ -448,17 +377,17 @@ export const ApiKeys: FC = observer(() => {
448377
)}
449378
</Overlay>
450379
);
451-
});
380+
};
452381
```
453382

454-
## 19.2 Query hook (pattern)
383+
## 17.2 Query hook (pattern)
455384

456385
```ts
457386
// features/tonapi/api-keys/model/queries.ts
458-
import { useProjectId } from 'src/shared/contexts/ProjectIdContext';
387+
import { useProjectId } from 'src/shared/contexts/ProjectContext';
459388

460389
export function useApiKeysQuery() {
461-
const projectId = useProjectId(); // NEW: Use context hook instead of store
390+
const projectId = useProjectId();
462391
return useQuery({
463392
queryKey: ['api-keys', projectId || undefined],
464393
queryFn: async () => {
@@ -475,7 +404,7 @@ export function useApiKeysQuery() {
475404
}
476405
```
477406

478-
## 19.3 Mutation with projectId capture (pattern - IMPORTANT)
407+
## 17.3 Mutation with projectId capture (pattern - IMPORTANT)
479408

480409
```ts
481410
// features/tonapi/api-keys/model/queries.ts
@@ -507,15 +436,15 @@ export function useDeleteApiKeyMutation() {
507436

508437
---
509438

510-
# 20) Resources
439+
# 18) Resources
511440

512441
* Repository: `ton-console`
513442
* Main branch: `master`
514443
* Liteservers documentation: link available in the UI
515444

516445
---
517446

518-
# 21) Command reference (for convenience)
447+
# 19) Command reference (for convenience)
519448

520449
```bash
521450
# Dev

0 commit comments

Comments
 (0)