T3: analysisStore + draftStore
T3: analysisStore + draftStore
Section titled “T3: analysisStore + draftStore”Phase: BCG Phase 1 Depends on: T2 (Zustand установлен, themeStore/wizardStore работают) Effort: ~3h
Context
Section titled “Context”Перенос логики из useAnalysis.ts (181 стр) и useDraftPersistence.ts (170 стр) в Zustand stores. Hook-файлы удаляются, но ПУБЛИЧНЫЙ КОНТРАКТ (имена методов и полей) сохраняется 1:1 для плавной миграции App.tsx в T5.
Читать перед стартом:
app/frontend/src/hooks/useAnalysis.ts— полный файлapp/frontend/src/hooks/useDraftPersistence.ts— полный файлsrc/hooks/useAnalysis.test.tsx— все сценарии должны продолжать работатьsrc/hooks/useDraftPersistence.test.tsxarchive/2026-04-23-bcg-planning-docs/BCG_plan.md§1.2.4, §1.2.6
src/stores/analysisStore.tsс тем же API что уuseAnalysissrc/stores/draftStore.tsс тем же API что уuseDraftPersistence- Удалить старые hook-файлы
- Адаптировать тесты под stores
App.tsxпродолжает работать (временно черезuseAnalysisStoreиuseDraftStoreвместо хуков)
1. src/stores/analysisStore.ts
Section titled “1. src/stores/analysisStore.ts”Перенести ВСЕ поля и методы из useAnalysis:
- state:
results,isAnalyzing,analysisError,statusMessage,validationErrors - actions:
runAnalysis,clearAnalysis,invalidateResults,showStatus,showError,clearFeedback,validateDraft,ensureValidForm,linkResultToProject,getPersistableAnalysis
Сохранить семантику: status и error взаимоисключающи (setError чистит status, setStatus чистит error).
runAnalysis — async, вызывает requestAnalysis из lib/api. Оставить текущую обработку ошибок и retry логику (если есть).
2. src/stores/draftStore.ts
Section titled “2. src/stores/draftStore.ts”Перенести из useDraftPersistence:
- state:
draft,draftStorageWarning - actions:
readDraftBootstrap,replaceDraft,resetDraft,updateDraftField,parseImportedDraftText,clearStorageWarning
Persist: localStorage ключ ab-test:draft:v1. При quota exceeded — ставить draftStorageWarning вместо throw.
3. Миграция тестов
Section titled “3. Миграция тестов”Переименовать:
src/hooks/useAnalysis.test.tsx→src/stores/analysisStore.test.tssrc/hooks/useDraftPersistence.test.tsx→src/stores/draftStore.test.ts
Адаптировать: вместо renderIntoDocument и act — прямые вызовы useAnalysisStore.getState().runAnalysis(...) и проверки через useAnalysisStore.getState(). beforeEach сбрасывает состояние.
Все сценарии из T1 должны пройти.
4. Удалить старые файлы
Section titled “4. Удалить старые файлы”git rm app/frontend/src/hooks/useAnalysis.ts app/frontend/src/hooks/useDraftPersistence.tsУбедиться, что НИКТО в codebase не импортирует эти файлы (rg "from ['\"].*useAnalysis['\"]" src → пусто).
5. Обновить импорты
Section titled “5. Обновить импорты”В App.tsx (и везде, где использовались хуки):
// былоconst analysis = useAnalysis(draft);// сталоconst analysis = useAnalysisStore();Если API store-а идентичен хуку — замена механическая. Если разошлось (например, хук принимал draft параметром, а store читает из useDraftStore) — описать в отчёте.
6. Verify
Section titled “6. Verify”cd app/frontendnpx vitest run src/stores src/componentsnpx tsc --noEmitnpm run buildРучная проверка: npm run dev → заполнить wizard → Run Analysis → результаты отображаются → draft сохраняется при reload.
Done When
Section titled “Done When”-
src/stores/analysisStore.ts+.test.ts(≥ 5 тестов, все зелёные) -
src/stores/draftStore.ts+.test.ts(≥ 6 тестов, все зелёные) -
src/hooks/useAnalysis.ts,src/hooks/useDraftPersistence.tsудалены - Публичный контракт совпадает (те же имена методов и полей)
-
npx tsc --noEmit= 0 ошибок -
npm run buildпроходит - Ручной e2e flow работает
Constraints
Section titled “Constraints”- НЕ менять
useProjectManager— это T4 - Семантика status/error взаимоисключения сохраняется
- Все существующие тесты из T1 должны пройти после миграции (возможно с минимальной переработкой вызовов)