From 92df7346c7acb2b3d045caf5696e6c55fc5c7934 Mon Sep 17 00:00:00 2001 From: ochenstarik-ui <267932263+ochenstarik-ui@users.noreply.github.com> Date: Mon, 19 Oct 2026 11:59:16 +0700 Subject: [PATCH 1/3] docs(agents): add Codex stage-1 completion task Task from Claude (orchestrator), forwarded by the owner on 2026-10-19: dependency security fix, real-PostgreSQL integration run, live VK smoke preparation, single-host deployment and domain access. Co-Authored-By: Claude Opus 5.5 --- .../inbox/2026-10-19-stage1-completion.md | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 agents/codex/inbox/2026-10-19-stage1-completion.md diff --git a/agents/codex/inbox/2026-10-19-stage1-completion.md b/agents/codex/inbox/2026-10-19-stage1-completion.md new file mode 100644 index 0000000..10950c2 --- /dev/null +++ b/agents/codex/inbox/2026-10-19-stage1-completion.md @@ -0,0 +1,104 @@ +# Codex — Randomayzer: завершение первого этапа + +Дата: 2026-10-19. От: Claude, передаёт владелец. +Репозиторий `github.com/ochenstarik-ui/randomayzer`, ветка `main` (`b625d70`). +Одна задача — одна ветка — один PR в `main`. В `main` сам не вливаешь — сливает владелец или Claude. + +**Где что выполняется.** Ты работаешь на своём ПК. Сервер развёртывания — отдельная машина +владельца (сведения о ней ниже, в R4/R5). Ты готовишь и проверяешь у себя конфигурацию, скрипты +и runbook. Запуск на сервере по твоему runbook выполняет Claude, результат он записывает +в `agents/claude/done/`. Runbook должен быть исполнимым без тебя: команды, ожидаемый вывод, +откат. +Проект некоммерческий: платежи, биллинг и юридические тексты не нужны. + +## Состояние на 19.10 (проверено Claude) +- `vitest run` — 346 из 346, 59 файлов; `tsc --noEmit` — без ошибок; `eslint` — 0 ошибок, 6 предупреждений; + `next build` — проходит. +- `npm audit --omit=dev` — **3 уязвимости:** next 16.0.0–16.3.7 (**критическая**), sharp ≤0.35.5-rc.1 (высокая), + source-map-js 1.0.0–1.2.1 (высокая); для всех есть обновления. +- Интеграционные тесты (`npm run test:integration`, реальная PostgreSQL) не запускались. +- Чек-лист `docs/VK_REAL_SMOKE_TEST.md`, пункты A–H, не отмечен ни один. В `docs/VK_INTEGRATION_PLAN.md` + и `docs/VK_ID_LIVE_CONTRACT.md` часть поведения VK API помечена UNVERIFIED. + +## Как работаешь +Дешёвые модели: кодер 1 → кодер 2 → два независимых аудитора сверяют результат с этим заданием, +цикл до зелёного. Затем ты сам проверяешь и исправляешь, потом PR и отчёт в `agents/codex/done/`. +Существующие тесты не менять, проверки не ослаблять. Секреты VK — только из 0600-файла, не в Git и не в логи. + +## Задания по порядку + +### R1. Безопасность зависимостей (первым) +Обновить next, sharp и source-map-js до версий без уязвимостей, минимально необходимым шагом, +без смены мажорных версий без нужды. Если Next требует правок кода, сделать их. +**Приёмка:** `npm audit --omit=dev` без critical и high; тесты, tsc, lint и build зелёные. +В отчёте указать старые и новые версии и лицензии. + +### R2. Интеграционные тесты на реальной PostgreSQL +Поднять PostgreSQL 16 (docker-compose проекта, порт только на 127.0.0.1) и прогнать +`npm run test:integration`. Найденные падения исправить в коде, не в тестах. +**Приёмка:** вывод прогона, 0 падений; миграции Prisma применяются на чистой базе. + +### R3. Подготовка к проверке на живом VK +Без реальных ключей: +1. Для каждого UNVERIFIED-поведения (список руководителей сообщества, репосты закрытых профилей, + лимиты пагинации, лимит `execute`) — безопасное поведение при отказе VK. Понятная причина + в UI и в статусе участника, без падения розыгрыша и без молчаливой потери участников. + Тесты на мок-провайдере для каждого отказа. +2. Скрипт `tools/vk-smoke.(ts|sh)`, который владелец запустит с реальными ключами: проходит пункты + A–H чек-листа там, где их можно автоматизировать, и печатает PASS или FAIL по каждому. + Ручные пункты (экран согласия VK) — пошаговая инструкция. + +### R4. Развёртывание +**Целевой хост — этот же сервер (решение владельца 19.10), не отдельный VPS.** На нём уже +работают другие сервисы, ничего из них не трогать: +- порт 80 занят Apache из snap Nextcloud; +- 3000 занят Express-приложением (слушает 0.0.0.0); +- 127.0.0.1:5432 и 127.0.0.1:8080 тоже заняты; +- диск заполнен на 82%. + +Поэтому: +- приложение — на свободном порту, только `127.0.0.1` (например, 3100; перед выбором проверить через `ss -ltn`); +- своя PostgreSQL — в отдельной сети Docker, без публикации порта на хост; +- имена контейнеров, сетей и томов — с префиксом `randomayzer-`; +- лимиты памяти и CPU. + +**Доступ — только у владельца (решение 19.10).** Наружу ничего не публикуется: ни домена, +ни публичного TLS, ни правил firewall. Приложение слушает только `127.0.0.1`. Владелец открывает его +в браузере на самом сервере или через SSH-туннель (`ssh -L <порт>:127.0.0.1:<порт>`) — команду +записать в runbook. + +Важно для VK ID и проверок production: +- redirect URI приложения VK — `http://localhost:<порт>/api/auth/vk/callback`; так и записать его + в настройках VK ID-приложения; +- если `docs/PRODUCTION_GUARDS.md` или код требуют HTTPS, флаг `Secure` у cookie или публичный + origin в production-режиме — добавить явный профиль «local single-user», где это допустимо только + для loopback-адреса. Проверки не ослаблять глобально: для не-loopback origin они должны работать + как прежде, это покрыть тестом. + +Production-конфигурация на этот хост: +- приложение и PostgreSQL, без внешнего прокси и без публичного HTTPS; +- порты БД только на loopback, непривилегированные контейнеры; +- `AUTH_SECRET` и ключи VK из 0600-файла; +- ежедневный бэкап БД с проверкой восстановления; +- runbook запуска, обновления и отката в `docs/`. + +**Приёмка:** локальный прогон стека в production-режиме, восстановление из бэкапа на чистую базу. + +### R5. Доступ по домену `random.ochenstarik.ru` +Шаг 1 (loopback) делается сразу. Домен добавляется вторым шагом, без переделки шага 1: +- Порт 80 занят Apache из snap Nextcloud, его не трогать. Порт 443 свободен. TLS — через + reverse proxy на 443 (например, Caddy в контейнере `randomayzer-proxy`) с выпуском сертификата + по TLS-ALPN-01 на 443 или DNS-01. HTTP-01 на 80 недоступен. +- Пользователь один — владелец. Поэтому перед приложением дополнительный слой доступа: + basic auth или allowlist IP на прокси, плюс собственный вход через VK. +- Redirect URI VK ID — `https://<домен>/api/auth/vk/callback`. Production-проверки (HTTPS, + Secure-cookie, origin) — в обычном строгом режиме, профиль «local» для домена не использовать. +- Открыть 443 в firewall хоста только для прокси. Приложение и БД по-прежнему на loopback + и во внутренней сети. + +**Приёмка:** сертификат выпущен; без авторизации на прокси — 401; вход через VK ID работает +по домену; приложение напрямую извне недоступно. + +## После R1–R4 от владельца нужно +Приложение VK ID и сервисный токен в 0600-файле. Тогда — живая проверка по R3 +и исправление найденного. Для R5 домен уже есть: `random.ochenstarik.ru`, A → 185.26.122.80. Сервер стоит за NAT (192.168.1.81), поэтому нужен проброс TCP 443 с роутера или внешнего адреса на 192.168.1.81 — подтверждает владелец. Исходящий трафик сервера идёт через прозрачный прокси xray: на выпуск сертификата это не влияет, но внешний IP по запросам «изнутри» определять нельзя. -- 2.45.2 From 5598d2f38e94f91beb39ad2e717b8a339e16257a Mon Sep 17 00:00:00 2001 From: ochenstarik-ui <267932263+ochenstarik-ui@users.noreply.github.com> Date: Mon, 19 Oct 2026 12:01:16 +0700 Subject: [PATCH 2/3] docs(agents): route domain access through the owner's VPS over WireGuard Co-Authored-By: Claude Opus 5.5 --- .../inbox/2026-10-19-stage1-completion.md | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/agents/codex/inbox/2026-10-19-stage1-completion.md b/agents/codex/inbox/2026-10-19-stage1-completion.md index 10950c2..1aa5d8d 100644 --- a/agents/codex/inbox/2026-10-19-stage1-completion.md +++ b/agents/codex/inbox/2026-10-19-stage1-completion.md @@ -84,21 +84,36 @@ Production-конфигурация на этот хост: **Приёмка:** локальный прогон стека в production-режиме, восстановление из бэкапа на чистую базу. -### R5. Доступ по домену `random.ochenstarik.ru` -Шаг 1 (loopback) делается сразу. Домен добавляется вторым шагом, без переделки шага 1: -- Порт 80 занят Apache из snap Nextcloud, его не трогать. Порт 443 свободен. TLS — через - reverse proxy на 443 (например, Caddy в контейнере `randomayzer-proxy`) с выпуском сертификата - по TLS-ALPN-01 на 443 или DNS-01. HTTP-01 на 80 недоступен. -- Пользователь один — владелец. Поэтому перед приложением дополнительный слой доступа: - basic auth или allowlist IP на прокси, плюс собственный вход через VK. -- Redirect URI VK ID — `https://<домен>/api/auth/vk/callback`. Production-проверки (HTTPS, - Secure-cookie, origin) — в обычном строгом режиме, профиль «local» для домена не использовать. -- Открыть 443 в firewall хоста только для прокси. Приложение и БД по-прежнему на loopback - и во внутренней сети. +### R5. Доступ по домену `random.ochenstarik.ru` через VPS владельца +Схема (решение владельца 19.10): **интернет → VPS (185.26.122.80, на нём A-запись домена) → +WireGuard → домашний сервер → приложение.** Проброса портов на домашнем роутере нет и не нужно. -**Приёмка:** сертификат выпущен; без авторизации на прокси — 401; вход через VK ID работает -по домену; приложение напрямую извне недоступно. +Что известно о сети: на домашнем сервере есть WireGuard-интерфейс `krona-wg` с адресом +`10.77.0.3/24`, peer `10.77.0.1` отвечает (около 58 мс). VPS — предположительно `10.77.0.1`, +владелец подтверждает. Туннель уже используется другим проектом (krona): его конфигурацию +не менять, только использовать. + +Сделать: +1. **Домашний сервер.** Приложение дополнительно слушает `10.77.0.3:<порт>` (не `0.0.0.0`). + На хосте firewall разрешает этот порт только с `10.77.0.1`. БД по-прежнему не публикуется. +2. **VPS.** Фрагмент конфигурации reverse proxy под существующий на VPS веб-сервер + (nginx или Caddy — определить по runbook, не ставить второй на 443): + - TLS для `random.ochenstarik.ru` (Let's Encrypt, HTTP-01 на VPS); + - `proxy_pass http://10.77.0.3:<порт>`, заголовки `X-Forwarded-*` и `Host`; + - basic auth или allowlist IP владельца — пользователь один; + - лимиты тела запроса и таймауты. +3. **Приложение.** Доверять `X-Forwarded-*` только от `10.77.0.1`, через существующую в проекте + настройку trusted proxy, если она есть; production-проверки (HTTPS, Secure-cookie, origin) + в строгом режиме. Redirect URI VK ID — `https://random.ochenstarik.ru/api/auth/vk/callback`. +4. **Runbook** для двух машин: что выполнять на VPS и что на домашнем сервере, проверки, откат. + Выполняет Claude или владелец. + +**Приёмка:** локально — тест, что `X-Forwarded-*` от чужого адреса не принимается. На стенде (Claude): +- сертификат выпущен; +- без авторизации на прокси — 401; +- вход через VK ID работает по домену; +- порт приложения не виден ни из интернета, ни из локальной сети — только из туннеля. ## После R1–R4 от владельца нужно Приложение VK ID и сервисный токен в 0600-файле. Тогда — живая проверка по R3 -и исправление найденного. Для R5 домен уже есть: `random.ochenstarik.ru`, A → 185.26.122.80. Сервер стоит за NAT (192.168.1.81), поэтому нужен проброс TCP 443 с роутера или внешнего адреса на 192.168.1.81 — подтверждает владелец. Исходящий трафик сервера идёт через прозрачный прокси xray: на выпуск сертификата это не влияет, но внешний IP по запросам «изнутри» определять нельзя. +и исправление найденного. Для R5 — подтвердить, что `10.77.0.1` в WireGuard — это VPS 185.26.122.80, и какой веб-сервер на нём стоит. -- 2.45.2 From 1a532465b00443a11ee71416fb7a9c8fc99a188b Mon Sep 17 00:00:00 2001 From: ochenstarik-ui <267932263+ochenstarik-ui@users.noreply.github.com> Date: Mon, 19 Oct 2026 12:01:50 +0700 Subject: [PATCH 3/3] docs(agents): VPS is 178.212.13.102 (shared with Forgejo) Co-Authored-By: Claude Opus 5.5 --- agents/codex/inbox/2026-10-19-stage1-completion.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/agents/codex/inbox/2026-10-19-stage1-completion.md b/agents/codex/inbox/2026-10-19-stage1-completion.md index 1aa5d8d..8a9e6e0 100644 --- a/agents/codex/inbox/2026-10-19-stage1-completion.md +++ b/agents/codex/inbox/2026-10-19-stage1-completion.md @@ -85,12 +85,11 @@ Production-конфигурация на этот хост: **Приёмка:** локальный прогон стека в production-режиме, восстановление из бэкапа на чистую базу. ### R5. Доступ по домену `random.ochenstarik.ru` через VPS владельца -Схема (решение владельца 19.10): **интернет → VPS (185.26.122.80, на нём A-запись домена) → +Схема (решение владельца 19.10): **интернет → VPS владельца 178.212.13.102 → WireGuard → домашний сервер → приложение.** Проброса портов на домашнем роутере нет и не нужно. Что известно о сети: на домашнем сервере есть WireGuard-интерфейс `krona-wg` с адресом -`10.77.0.3/24`, peer `10.77.0.1` отвечает (около 58 мс). VPS — предположительно `10.77.0.1`, -владелец подтверждает. Туннель уже используется другим проектом (krona): его конфигурацию +`10.77.0.3/24`, peer `10.77.0.1` отвечает (около 58 мс). Является ли `10.77.0.1` этим VPS (178.212.13.102) — владелец подтверждает. На этом же VPS работает Forgejo `git.ochenstarik.ru`: его веб-сервер и порты не трогать, добавлять только отдельный виртуальный хост. Туннель уже используется другим проектом (krona): его конфигурацию не менять, только использовать. Сделать: @@ -116,4 +115,4 @@ WireGuard → домашний сервер → приложение.** Проб ## После R1–R4 от владельца нужно Приложение VK ID и сервисный токен в 0600-файле. Тогда — живая проверка по R3 -и исправление найденного. Для R5 — подтвердить, что `10.77.0.1` в WireGuard — это VPS 185.26.122.80, и какой веб-сервер на нём стоит. +и исправление найденного. Для R5 — A-запись `random.ochenstarik.ru` → 178.212.13.102 (на 19.10 DNS ещё отдаёт 185.26.122.80); подтвердить, что `10.77.0.1` в WireGuard — это этот VPS, и какой веб-сервер на нём стоит. -- 2.45.2