strava-frontend/.roo/memory-bank/activeContext.md

79 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Active Context — Strava Frontend
## Task State
- task_id: TASK-MCP-SETUP
- status: success
- parent_task: —
- summary: **Настроить Playwright MCP для UI-верификации через браузер. Конфиг Zoo Code обновлён (Node 22), Chromium установлен.**
- next task: —
## TASK-MCP-SETUP: Playwright MCP configuration
**Что сделано:**
- MCP-конфиг Zoo Code (`mcp_settings.json`): server `web-browser` → `@playwright/mcp@latest`, Node 22 via nvm absolute path, `--headless`
- Chromium `1234` уже установлен в `~/.cache/ms-playwright/`
- `.mcp.json` создан в проекте (project-level, для совместимости)
- `techContext.md` обновлён: секция "UI Verification (MCP Browser)"
**Как использовать (workflow):**
1. `yarn dev` — запустить dev server (порт 5173)
2. `browser_navigate` → `http://localhost:5173/explore` — проверить публичную страницу
3. `browser_evaluate` → `() => { localStorage.setItem('token', 'test'); localStorage.setItem('user', JSON.stringify({id:1,name:'Test'})); location.reload(); }` — сымитировать auth
4. `browser_navigate` → проверить auth-страницы (`/workouts`, `/workouts/:id`)
5. `browser_snapshot` — проверить DOM-структуру
6. `browser_take_screenshot` — визуальная проверка
7. `browser_network_requests` — проверить API-запросы
### Баг (контекст)
Сайдбар показывает `publicRoutes` (Лента + Маршрут) после логина до F5. Корень: [`NavigationRoutes.ts:70`](src/components/sidebar/NavigationRoutes.ts:70) — `routes` вычисляется один раз при module evaluation и кэшируется. TASK-AUTH-NAV-1 уже добавил реактивный `isAuthenticated` в `useGlobalStore` (инициализация из localStorage + `setAuthenticated` в Login/Logout). Эта задача переключает UI на computed.
### TASK-AUTH-NAV-2: реактивные маршруты (3 файла)
**1. `src/components/sidebar/NavigationRoutes.ts`**
- Сделать named exports: `export const authRoutes: INavigationRoute[]` и `export const publicRoutes: INavigationRoute[]` (сейчас это локальные `const`, не экспортированные).
- Убрать статическое поле `routes` из default export (или оставить default без `routes`, т.к. оба потребителя перейдут на computed). `INavigationRoute` интерфейс — не трогать.
- Важно: массивы `authRoutes`/`publicRoutes` остаются теми же по структуре/содержимому — только экспортируются.
**2. `src/components/sidebar/AppSidebar.vue`** (Options API, `setup()`)
- `import { useGlobalStore } from "../../stores/global-store";` + `import { authRoutes, publicRoutes } from "./NavigationRoutes";` (импорт `navigationRoutes` по default можно оставить/убрать — но все обращения `navigationRoutes.routes` заменить).
- В `setup()`: `const globalStore = useGlobalStore();`
- computed: `const routes = computed(() => globalStore.isAuthenticated ? authRoutes : publicRoutes);`
- В `return` заменить `navigationRoutes` на `routes` (тепловой шаблон уже использует `navigationRoutes.routes` → поправить на `routes.value`? НЕТ — в Options API computed из setup доступно в шаблоне как `routes` без `.value`, т.е. в шаблоне `navigationRoutes.routes` → `routes`).
- `setActiveExpand`: `navigationRoutes.routes.map(...)` → `routes.value.map(...)` (в setup `.value` нужен).
- Шаблоны: `v-for="(route, index) in navigationRoutes.routes"` → `in routes`.
**3. `src/components/app-layout-navigation/AppLayoutNavigation.vue`** (script setup)
- `import { authRoutes, publicRoutes } from "../sidebar/NavigationRoutes";` + `import { useGlobalStore } from "../../stores/global-store";`
- `const globalStore = useGlobalStore();`
- `findRouteName` (строка ~64): `traverse(NavigationRoutes.routes)` → `traverse(globalStore.isAuthenticated ? authRoutes : publicRoutes)`.
- Убедиться, что `items` computed (зависит от `route.matched` и `findRouteName`) остаётся реактивным — т.к. `findRouteName` читает `globalStore.isAuthenticated` внутри `items` computed, реactivity сохранится.
### Acceptance Criteria (TASK-AUTH-NAV-2)
1. `yarn lint` → 0 ошибок.
2. `yarn build` → 0 ошибок (vue-tsc --noEmit).
3. `NavigationRoutes.ts`: `authRoutes` и `publicRoutes` экспортируются; статического `routes` с localStorage-тернарником больше нет.
4. `AppSidebar.vue`: routes = computed от `globalStore.isAuthenticated`; `setActiveExpand` использует `routes.value`.
5. `AppLayoutNavigation.vue`: `traverse` использует выбор по `globalStore.isAuthenticated`.
6. **Ручной сценарий (ключевой)**: без F5 — выход из профиля → `/explore` → логин → сайдбар **сразу** показывает «Мои тренировки» (authRoutes). Аут → сайдбар сразу `publicRoutes`.
## ✅ CODER SUCCESS REPORT — TASK-AUTH-NAV-2
- `src/components/sidebar/NavigationRoutes.ts`: `export const authRoutes` / `export const publicRoutes`; удалён статический `routes: localStorage.getItem("token") ? ...` из default export (оставлен только `root`).
- `src/components/sidebar/AppSidebar.vue`: импорт `authRoutes, publicRoutes` + `useGlobalStore`; `computed(() => globalStore.isAuthenticated ? authRoutes : publicRoutes)`; `setActiveExpand` использует `routes.value.map`; шаблон `v-for="(route, index) in routes"`.
- `src/components/app-layout-navigation/AppLayoutNavigation.vue`: `const globalStore = useGlobalStore()`; `traverse(globalStore.isAuthenticated ? authRoutes : publicRoutes)` внутри `findRouteName` (вызывается в `items` computed → реactivity сохранена).
- Verified: `yarn lint` exit 0, `yarn build` exit 0 (vue-tsc --noEmit 0 ошибок, vite ✓ 7.07s).
## История (закрытые задачи)
- **TASK-AUTH-NAV-1**: success — `isAuthenticated` + `setAuthenticated` в `useGlobalStore`; Login `setAuthenticated(true)`, Logout `setAuthenticated(false)`. Verified lint/build 0.
- TASK-SSR-DETAIL: success — SSR /public/workouts/:id под DOM WorkoutItem.vue.
- TASK-404: success — HTTP 404 для неизвестных страниц.
- TASK-PUBLIC-ROUTE-FIX: success — workout_public_item в top-level router.
- TASK-F11/F12/F13/F14: success — SEO + фиксы карты тренировки.