Files
anotherreflections-website-v2/CLAUDE.md
striker 7f85f34b6a
All checks were successful
Deploy to web.hhivp.com / deploy (push) Successful in 33s
docs(CLAUDE.md) + fix(nginx): application/rss+xml для feed.xml
- CLAUDE.md проекта: сервер, cutover-инструкция, откат за минуту,
  бэкап-пути, стек, структура, RSS-конфигурация под IPB, аналитика+consent,
  CI/CD, локальная разработка
- nginx.conf: types{} default_type application/rss+xml — теперь Content-Type
  правильный для RSS Importer (раньше отдавалось text/xml из дефолтного MIME)
2026-05-21 02:47:39 +03:00

163 lines
9.8 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.
# anotherreflections.ru — v2 (Astro)
## Проект
Главный сайт-портал ролевой группы «Иные Отражения». Переделан со старого WordPress 6.9 (тема `darkness-10`, 23 активных плагина) на статический **Astro 5 + Content Collections + markdown**.
## Сервер
| Параметр | Значение |
|---|---|
| Хост | `web.hhivp.com` (45.10.53.206 / 45.10.53.242) |
| Deploy path | `/opt/docker/sites/anotherreflections-ru-v2/` (git clone) |
| Git remote | `git.striker.su/striker/anotherreflections-website-v2` (ветка `main`) |
| Контейнер | `anotherreflections-ru-v2` (nginx:1.29-alpine) |
| Внутренний порт | 80 |
| Внешний порт | 127.0.0.1:**4084** (nginx-хост → proxy_pass) |
| nginx vhost | `/etc/nginx/conf.d/anotherreflections.ru` |
| OG-image / лого | `public/og-image.png`, `public/logo*.svg` |
## Cutover (2026-05-20)
Со старого WordPress (контейнер `anotherreflections-ru` на :4080) — на новый Astro-контейнер (:4084). Старый контейнер и БД оставлены для отката на 1-2 недели.
**Откат за 1 минуту:**
```bash
ssh striker@web.hhivp.com
sudo sed -i 's|127.0.0.1:4084|127.0.0.1:4080|g' /etc/nginx/conf.d/anotherreflections.ru
sudo nginx -t && sudo systemctl reload nginx
```
**Бэкап перед cutover** в `/opt/backup/anotherreflections-pre-v2-cutover-20260521-024027/`:
- `wp-site-tree.tgz` (349 МБ) — весь `/opt/docker/sites/anotherreflections-ru/`
- `wp-db-anotherreflctions_ru.sql.gz` (5.6 МБ) — mysqldump БД (на `db.hhivp.com` MySQL)
- `anotherreflections.ru.nginx` — старый vhost (proxy 4080)
Также резерв-копия vhost в `/opt/backup/nginx-bak/20260521-024433/anotherreflections.ru.bak.20260520-wp`.
## Стек
- **Astro 5** (6.3.6) + Content Collections — каждая `.astro` страница рендерится в `dist/.../index.html` при `npm run build` (SSG, без runtime JS-фреймворка).
- **@astrojs/rss** — RSS-фиды (общий + per-category) под IPB RSS Importer.
- **@astrojs/sitemap** — `sitemap-index.xml` автоматически.
- **sanitize-html** — очистка HTML тела поста для `<content:encoded>` в RSS.
- **sharp** (devDep) — генерация OG-image PNG из SVG.
## Структура
```
src/
├── content/
│ ├── posts/*.md (50 постов 2009-2015, мигрированы из WP)
│ ├── pages/*.md (6 страниц: O нас, Наши друзья, страницы про игры)
│ └── _categories.json (10 категорий-справочник)
├── components/
│ ├── BrandMark.astro (SVG-знак в шапке)
│ ├── SocialLinks.astro (плавающая правая колонка: Telegram, ВК, ↑)
│ ├── Analytics.astro (Яндекс.Метрика + GA, скрипты с type=text/plain
│ │ активируются после consent)
│ └── CookieConsent.astro (152-ФЗ-баннер, ar-consent в localStorage+cookie)
├── layouts/BaseLayout.astro
├── pages/
│ ├── index.astro (hero + лента всех постов)
│ ├── [slug].astro (один пост или одна страница, slug совпадает с WP)
│ ├── 404.astro
│ ├── miry.astro (8 игровых вселенных карточками)
│ ├── kontakty.astro (email + Telegram + ВК)
│ ├── privacy.astro (политика + кнопка «Отозвать согласие»)
│ ├── feed.xml.ts (общий RSS, фильтр по RSS_CUTOFF)
│ ├── sitemap.txt.ts (plain-text список всех URL)
│ └── category/
│ ├── [slug].astro
│ └── [slug]/feed.xml.ts (per-category RSS)
├── lib/rss-helpers.ts (рендер md→HTML для <content:encoded>)
├── styles/global.css (тёмная тема, decorative ::before/::after звёзды)
└── consts.ts (SITE_TITLE, WORLDS, ANALYTICS, CATEGORY_COLORS, plural())
public/
├── favicon.svg
├── logo.svg, logo-mark.svg
├── og-image.png (1200×630 для расшаривания в TG/VK/Twitter)
├── og-image.svg (исходник)
├── robots.txt (allow all, Host для Yandex, AI-crawlers)
├── ai.txt (Train/Cite/Quote: yes)
├── llms.txt (формат llmstxt.org)
└── wp-content/uploads/ (4 файла, перенесены со старого WP: header_bg + NY-baner)
scripts/
├── migrate-wp.mjs (одноразовый: _wp-export.json → src/content/*.md)
└── build-og-image.mjs (sharp → public/og-image.png из SVG)
Dockerfile (multi-stage: node:22-alpine builds → nginx:1.29-alpine serves)
nginx.conf (gzip, кэш _astro/ 1y, MIME application/rss+xml для feed)
docker-compose.yml (контейнер на 127.0.0.1:4084)
.gitea/workflows/deploy.yml (push в main → SSH-деплой на web)
```
## RSS под IPB Importer
`RSS_CUTOFF` в `src/consts.ts` (по умолчанию `2026-05-20`) — фид отдаёт **только посты с pubDate ≥ cutoff**. Архив 2009-2015 на сайте остаётся, в форумы через RSS Importer не вбрасывается. Чтобы добавить пост в фид — публикуем с датой ≥ cutoff и пересобираем.
RSS 2.0 strict: `<pubDate>` в RFC-822, `<guid isPermaLink="true">` = URL поста (IPB дедуплицирует), `<content:encoded>` с CDATA + полным HTML тела, `<lastBuildDate>` обновляется при каждом build.
URLs:
- `/feed.xml` — общий
- `/category/<slug>/feed.xml` — по категории
## Аналитика и cookie consent
- **Яндекс.Метрика** 13938862 (с webvisor) и **Google gtag** GT-PH39R3X. ID-шки в `src/consts.ts:ANALYTICS`.
- Оба скрипта в `Analytics.astro` имеют `type="text/plain" data-cookieconsent="statistics"` — браузер их **не выполняет**, пока пользователь не нажмёт «Принять» в баннере.
- `CookieConsent.astro` активирует скрипты при согласии, сохраняет выбор в `localStorage` + `cookie ar-consent=accept|deny` (12 мес).
- На `/privacy/` кнопка «Отозвать согласие» — ставит `ar-consent=deny` одним кликом.
## Деплой
**Через CI/CD (Gitea Actions)** — push в `main`:
1. Workflow `.gitea/workflows/deploy.yml` стартует.
2. SSH на `web.hhivp.com` с ключом из секрета `SSH_PRIVATE_KEY` (base64).
3. `git fetch` + `git reset --hard origin/main``docker compose build --pull``docker compose up -d``docker image prune -af --filter "until=168h"`.
4. Verify-шаг: `curl -sf -H "Host: anotherreflections.ru" http://127.0.0.1:4084/`.
Секреты в Gitea (`/repos/striker/anotherreflections-website-v2/actions/secrets`): `SSH_PRIVATE_KEY`, `SSH_HOST=web.hhivp.com`, `SSH_USER=striker`, `SSH_PORT=22`. Deploy-ключ — `~/.ssh/anotherreflections-v2-deploy{,.pub}` локально, `.pub` в `~striker/.ssh/authorized_keys` на web.
**Вручную** (с локалки):
```bash
cd /opt/docker/sites/anotherreflections-ru-v2
git pull
docker compose build && docker compose up -d
```
## База данных
В новой версии БД нет. Старый WP оставлен с БД `anotherreflctions_ru` (`sic`, с опечаткой) на `db.hhivp.com` (45.10.53.205, MySQL), user `u_anotherreflections`, prefix `anm_`. После 1-2 недель наблюдения за новой версией — старый WP-контейнер можно удалить, БД и snapshot тоже.
## SEO/AI файлы
- `public/robots.txt` — статика, разрешено всё; явно перечислены GPTBot/ClaudeBot/Google-Extended/CCBot/PerplexityBot/anthropic-ai; ссылки на sitemap-index.xml и sitemap.txt
- `public/ai.txt` — Train/Cite/Quote: yes (по спецификации spawning.ai)
- `public/llms.txt` — формат llmstxt.org с описанием проекта, ключевыми страницами, форумами, RSS-фидами, контактами
- `src/pages/sitemap.txt.ts` — генерирует plain-text список 68 URL при каждом билде
- `@astrojs/sitemap``sitemap-index.xml` + `sitemap-0.xml` XML-формат
## Скриншоты-источники
В `E:/Projects/` лежат финальные:
- `anotherreflections-logo.svg` / `.png` — знак + надпись
- `anotherreflections-logo-mark.svg` / `.png` — только знак
## Локальная разработка
```bash
npm install
npm run dev # → http://localhost:4321
npm run build # → dist/ (статика)
npm run preview # просмотр build
npm run migrate # одноразовая миграция _wp-export.json → md (уже сделана)
```
## История
- **2026-05-20**: v1 (WordPress 6.9 + darkness-10 + 23 плагина, контейнер на :4080) переделан на Astro 5. Новый репо `git.striker.su/striker/anotherreflections-website-v2`. Cutover в production через nginx proxy_pass swap. См. также `memory/project_anotherreflections_main_site.md`.
- **2026-05-07**: 6 IPB-форумов проекта мигрированы со str-u-01 на web.hhivp.com (порты 4091-4096). См. `memory/project_anotherreflections_forums.md`.