From 635f84a48ef2f65f336a01548654e6853329d911 Mon Sep 17 00:00:00 2001 From: artem Date: Fri, 18 Sep 2026 23:19:43 +0300 Subject: [PATCH] ssr --- .roo/memory-bank/activeContext.md | 64 +- .roo/memory-bank/progress.md | 33 + Dockerfile | 40 +- nginx.conf | 58 +- package.json | 8 +- run.sh | 3 +- .../AppLayoutNavigation.vue | 2 +- src/components/sidebar/NavigationRoutes.ts | 4 +- src/layouts/AppLayout.vue | 2 +- src/main.ts | 2 +- src/pages/auth/CheckTheEmail.vue | 2 +- src/pages/auth/Login.vue | 4 +- src/pages/auth/Signup.vue | 4 +- src/router/index.ts | 12 +- src/stores/user-store.ts | 12 + yarn.lock | 579 +++++++++++++++++- 16 files changed, 771 insertions(+), 58 deletions(-) diff --git a/.roo/memory-bank/activeContext.md b/.roo/memory-bank/activeContext.md index 14f2c06..fc0b982 100644 --- a/.roo/memory-bank/activeContext.md +++ b/.roo/memory-bank/activeContext.md @@ -2,11 +2,67 @@ ## Task State -- task_id: TASK-ROUTE-FIX +- task_id: TASK-SSR-3 - status: success -- parent_task: — -- summary: **FIX: Route.vue — багфикс GPX-генератора (for...in, дубликаты, фейковый ele) + фильтр близлежащих точек 5м. Snap to road убран (GraphHopper 401, риск блокировки OSM в РФ).** -- next task: — +- parent_task: TASK-SSR-2 +- summary: **FEATURE: SEO SSR — Sitemap endpoint, robots.txt, nginx proxy config, Dockerfile update, client localStorage guards, final verification.** +- next task: — (FEATURE complete after this) + +## ✅ CODER SUCCESS REPORT — TASK-SSR-3 + +- Изменённые файлы: + - `server/index.ts` — добавлены `GET /sitemap.xml` (XML с 3 статическими URL + workouts из `getPublicWorkouts()`, `Content-Type: application/xml`) и `GET /robots.txt` (Disallow `/auth/`, `/workouts/`, `/preferences/`, `/admin/`, Sitemap ссылка, `Content-Type: text/plain`). + - `nginx.conf` — полная замена: SSR proxy для `/explore`, `/routes`, `/sitemap.xml`, `/robots.txt`, `/public/workouts/`; `location = /` с `hascookie token` → proxy без cookie / static с cookie; `/assets/` → 30d immutable; `try_files $uri /index.html` для SPA fallback. + - `Dockerfile` — multi-stage: build (node:20-alpine, yarn install, yarn build) → runtime (node:20-alpine + nginx, copy dist/, server/, node_modules/, package.json; CMD `npx tsx server/index.ts & nginx -g 'daemon off;'`). + - `run.sh` — `cd /app && npx tsx server/index.ts & nginx -g 'daemon off;'`. + - `package.json` — `tsx` перемещён из `devDependencies` в `dependencies` (нужен в runtime container). + - `src/stores/user-store.ts` — `typeof window === "undefined"` guard в `state()` (возврат пустого state для SSR). + - `src/main.ts` — `typeof window !== "undefined" &&` guard перед `localStorage.getItem("token")` (line 110). +- `yarn lint`: exit 0 (prettier: все файлы unchanged, eslint 0 ошибок). +- `yarn build`: exit 0 (vue-tsc --noEmit 0 ошибок, vite build ✓ 6.68s; warning о chunk >500kB — предсуществующий). +- Curl: `/robots.txt` → 200 + `Sitemap: https://cycle-rider.ru/sitemap.xml`; `/sitemap.xml` → 200 + валидный XML (3 static + 2 workout URLs с ``); `/health` → ok. + +## ✅ CODER SUCCESS REPORT — TASK-SSR-2 + +- Изменён файл (единственный): `server/index.ts` — добавлены 4 SSR route handler + `app.disable("x-powered-by")`: + - `GET /` — если cookie `token` → 302 → `/explore`; иначе SEO-лендинг: `

Cycle Rider — анализ велотренировок

`, топ-5 публичных тренировок из `getPublicWorkouts()` (при ошибке API — «Загрузка…», не 500), секция «Возможности»; JSON-LD `WebApplication`. + - `GET /explore` — полный список публичных тренировок (ссылка, дата, км, км/ч, пульс); JSON-LD `WebPage`; при ошибке API → 500. + - `GET /public/workouts/:id` — детали тренировки из `getPublicWorkout(id)`; API 404 → `404 Not found`; другие ошибки → 500; JSON-LD `SportsActivity`. + - `GET /routes` — статический SEO-текст (без API). +- Хелперы в том же файле: `getAssetTagsSafe()` (try/catch вокруг `getAssetTags()` → fallback `