Files
admin/.tasks/STATUS.md
vitya fe41ee4422 backup(books-vds): daily 06:00 MSK pipeline to kreknin live 🟢
- scripts/books-vds-backup-daily-kreknin/ — run.sh + .env.example + README
- ES path.repo bootstrap (one-time stack edit, snapshot repo 'kreknin' registered)
- curl smtps://yandex:465 email (CRLF + Date headers, no msmtp dep on CentOS 7)
- StrictHostKeyChecking=yes + pre-populated known_hosts (CentOS 7 no accept-new)
- cron /etc/cron.d/books-vds-backup live, initial sync 4.87 GB in 13m28s, ntfy push sent
- wiki: entities/books-vds.md + sources/books-vds-backup-daily-kreknin-2026-05-25.md created
- wiki: concepts/books-ssh-access → vds-kzntsv-ssh-access (was lying about books on vds-kzntsv)
- .tasks/books-vds-backup-daily-kreknin.md closed 🟢 pending phone-side verify

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 09:37:16 +03:00

196 lines
21 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.
# Admin Task Board
_Updated: 2026-05-25 (`books-vds-backup-daily-kreknin` 🟢 closed — 4-я daily backup pipeline на kreknin, теперь покрыта `books VDS` 89.253.255.133 (host4g.ru). Pattern mirror VDS-infra (rsync+--link-dest), ES snapshot via REST API (новый repo `kreknin`, потребовал one-time stack edit + recreate ES), email через `curl smtps://yandex:465` без msmtp. Initial sync 4.87 GB in 13m28s, cron 06:00 MSK live. Также fix вики: `concepts/books-ssh-access.md``vds-kzntsv-ssh-access.md` (был misnamed — врал что books живёт на vds-kzntsv), `entities/books-vds.md` создан с factsheet'ом. **Phone-side ntfy + email — pending user confirmation на следующем раунде.**)_
## 🟢 [books-vds-backup-daily-kreknin] — closed 2026-05-25 — daily backup books VDS (89.253.255.133, host4g.ru, CentOS 7) → kreknin в 06:00 MSK. DB dumps (mariadb/mongo×2) + ES snapshot via REST → rsync 4.87GB → ntfy/email. ES path.repo bootstrap + snapshot repo `kreknin` registered. См. [books-vds-backup-daily-kreknin.md](books-vds-backup-daily-kreknin.md).
## 🟢 [unify-backup-notifications] — closed 2026-05-25 — единый формат push + email для VDS/RUVDS/windows-host (3 scripts), VDS run.sh импортирован в repo. См. [unify-backup-notifications.md](unify-backup-notifications.md) § Closed. windows-host self-deploy остаётся на user'е (elevated PS).
---
## ⚪ [stateful-split-volume-copy] — поднять `bookva-db` + `slovo-db` на VDS как копии `books-db` через `cp -a` volume
Ops-таска для Фазы 1 дизайна `tenant-split` из victor/books. Scope сужен 2026-05-25 (user: «просто поднимем 2 БД»): только MariaDB volume copy + up 2 контейнеров. Mongo / MinIO / DELETE / app-стеки — отдельными ops-тасками потом.
**Контекст dev-source:** дизайн в victor/books `.wiki/concepts/tenant-split.md` § «Фаза 1». Compose-файлы готовы в `bookva-overlay` / `slovo-overlay` (commit d0eb210 в books).
**Acceptance:** `docker ps` показывает живые `bookva-db` + `slovo-db`, оба отвечают `SELECT 1`. Текущий `books-db` стек снова в строю после maintenance window.
**Status:** ready
**Where I stopped:** (not started — lean playbook готов в [stateful-split-volume-copy.md](stateful-split-volume-copy.md))
**Next action:** под maintenance window 5-10 мин на VDS — execute 5 команд из task-файла. Backup → stop books-db → cp -a в 2 volume'а → up 2 новых контейнера через Portainer → start books-db.
**Blocker:**
**Branch:** master
<!-- created-by: vitya / 2026-05-25 / moved from victor/books .tasks/ (scope is ops/VDS, not books-code) -->
---
<!--
Status legend:
🔴 Active — only one at a time
🟡 Paused — in progress, resumable
⚪ Ready — defined, not started
🟢 Done — moved to ARCHIVE.md once committed
🔵 Blocked — waiting on external input
-->
## 🟡 [iis-migration-to-ruvds] — RUVDS IIS live для 2 prod hostnames (kupimknigi + emspb flipped); 22 в очереди. tandemmebel.ru остаётся на windows-IIS отдельно. Source held для rollback.
**Status:** in_progress (DNS partial cutover — soak window 2026-05-24)
**Where I stopped:** 2026-05-24 — `kupimknigi.spb.ru` + `emspb.ru` (+ `www.emspb.ru`) DNS A flipped на `80.64.31.36`, authoritative `ns1.reg.ru` правильный, public resolver caches expire'ятся (8.8.8.8=~6h, 1.1.1.1=~24h max). RUVDS state: snolla site (8.66 GB / 44725 files) transferred + IIS recreated + 25 HTTPS SNI bindings c LE certs (R13, valid до 2026-07-22), 7 prod hostnames live-smoke через VDS (третья сеть) → 200 OK / correct content. Source IIS:8089 + traefik routes ALIVE — rollback ready.
**Findings зафиксированы в** [iis-migration-to-ruvds.md](iis-migration-to-ruvds.md) Decisions log: (1) outbound 445 блокирует home ISP, не RUVDS-FW → SSH/scp = canonical transfer-метод; (2) home network HTTP-middlebox mangles Host header for direct external HTTP — real end-users не пострадают, тестировать через VDS; (3) traefik acme.json → IIS PFX recipe работает (extract + openssl pkcs12 -export + Import-PfxCertificate + AddSslCertificate by thumbprint); (4) IIS 10 HTTP/2 default; (5) `maljarka.tandemmebel.ru` + 3 rimiz hostnames → 502/404 — pre-existing CMS-tenant config gap, не migration defect.
**Scope exception (2026-05-24 user decision):** `tandemmebel.ru` + `www.tandemmebel.ru` ОСТАЮТСЯ на windows-IIS на неопределённый срок (отдельное решение user'а — site не готов к cutover ровно сейчас). DNS НЕ свапать. Cert на RUVDS уже импортирован, binding existing — может оставаться idle, traffic не пойдёт.
**Next action:**
1. **Снизить DNS TTL** в reg.ru на оставшиеся **22 hostnames** до 300s — `pilorama98.ru`, `labtools.{ru,pro}`, `snolla.com` + 11 snolla subdomains + `rimiz.{ru,snolla.com}` + `maljarka.tandemmebel.ru` (но не `tandemmebel.ru` — см. Scope exception). Сократит cache-tail с 24h до 5 мин.
2. **24h soak kupimknigi + emspb** — verify через cache-clean resolver (потом curl без `--resolve`).
3. **Bulk DNS swap** оставшихся 22 hostnames на 80.64.31.36 (single sitting). **tandemmebel.ru / www.tandemmebel.ru — пропустить.**
4. **1-week prod soak** с RUVDS как live source для migrated hostnames.
5. **Decommission source IIS:8089** только для migrated hostnames (snolla catch-all site нельзя decommission'ить пока tandemmebel.ru на нём же). Решение defer до tandemmebel migration.
6. **LE renewal pipeline** — win-acme + HTTP-01 на RUVDS после full cutover (LE certs expire 2026-07-22, soak window до ~07-15).
7. **Cleanup migration-temp:** `Remove-NetFirewallRule 'smb-from-source','ssh-from-source'` на RUVDS, удалить `~/.ssh/ruvds-iis-migration*` на source, очистить `C:\ProgramData\ssh\administrators_authorized_keys` на RUVDS.
Полный план + Completed + Open questions + Remaining steps — в [iis-migration-to-ruvds.md](iis-migration-to-ruvds.md).
**Branch:** master
<!-- created-by: user-decision / 2026-05-22 / trigger: RUVDS purchased -->
<!-- partial-cutover-by: vitya / 2026-05-24 / kupimknigi + emspb DNS flipped, 22 hostnames pending, tandemmebel.ru excluded -->
<!-- scope-narrowed: vitya / 2026-05-24 / tandemmebel.ru stays on windows-IIS indefinitely -->
**Branch:** master
---
## ⚪ [infra-inventory] — two-tier инвентаризация: public-карта в global wiki + admin-detailed runbook локально
**Status:** ready
**Where I stopped:** (not started — создана 2026-05-22 из инцидента `gitea.` vs `git.` + перепутанный source/dest IP в traefik access-логах; scope расширена в тот же день — single-page → two-tier per user «у все общее представление, у админа полное»)
**Next action:** см. полный план в `infra-inventory.md`. Шаги: (1) probing-фаза одна для обоих — `nslookup` известных subdomain'ов + `vds-ops`/`synology-ops` `ops_docker_ps`/`inspect` + `knowledge_search` по существующим bootstrap-concept'ам + `rg "kzntsv.site"` по `~/projects/`. (2) Write A — light public в `projects-wiki/concepts/infrastructure-inventory.md` (машины, canonical hostnames, anti-aliases) → `knowledge_ingest`. (3) Write B — heavy admin в `.admin/.wiki/concepts/infrastructure-stack.md` (per-stack: версии, internal IPs, volumes, depends-on, backup paths, DR pointers) → commit + push. (4) Cross-refs A↔B + pointer в `.admin/.wiki/CLAUDE.md` Domain conventions.
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / trigger: gitea-hostname-confusion-incident -->
<!-- scope-expanded: 2026-05-22 — single-page → two-tier (public + admin-detailed) -->
---
## 🔵 [books-vds-bookva-bootstrap] — Ops-таска для Фазы 4 дизайна `tenant-split` из victor/books (см. `mcp__projects-meta__knowledge_get slug=concepts/tenant-split`). Поднять новый VDS для Bookva — billing на юрлицо Bookva (учредители развелись, каждое юрлицо платит инфру напрямую провайдеру).
**Контекст dev-source:** дизайн в victor/books `.wiki/concepts/tenant-split.md`; brainstorm trace `~/projects/.workshop/.archive/2026-05-24-books-tenant-split.md`.
**Direction:** Slovo остаётся на текущем VDS, Bookva переезжает на новый.
**Acceptance:**
- Новый VDS у провайдера (Rusonyx или другой по предпочтению Bookva), billing-account оформлен на юрлицо Bookva.
- Docker + traefik + certbot развёрнуты.
- DNS `*.bookva.<tld>` готов резолвиться на новый IP (фактический switch — в `books-dns-cutover-bookva`).
- SSH-ключи: только инженерные (core-разраб + админ Bookva, если есть). Аналитики Bookva — НЕ имеют SSH к новому VDS.
**Status:** blocked
**Where I stopped:** (not started)
**Next action:** **Pre-step:** прочитать `concepts/tenant-split.md` § «Фаза 4» в victor/books (через `mcp__projects-meta__knowledge_get slug=concepts/tenant-split` или git clone victor/books → `.wiki/concepts/tenant-split.md`).
1. Согласовать с учредителем Bookva: provider, configuration (CPU/RAM/disk), регистрация billing'а на юрлицо Bookva.
2. Provision VDS, базовая настройка (firewall, fail2ban, SSH ключи).
3. Установить Docker + docker-compose.
4. Развернуть traefik + certbot из overlay-репо `victor/books-bookva/deploy/traefik.compose.yml`.
5. Подготовить DNS-зону `bookva.<tld>` (создать A-records, TTL=300 для возможности быстрого switch'а).
6. Smoke: `curl https://placeholder.bookva.<tld>` → 200 от nginx-placeholder или из traefik.
7. Документировать в `victor/books-bookva/README.md`: hostname, IP, как ssh, runbook smoke-теста.
8. Закрыть с note: «VDS поднят, IP=<...>, готов к stack deploy».
**Blocker:** `OpeItcLoc03/admin books-stateful-split-execution` (Фаза 1 — physical split на shared VDS, bookva-* контейнеры живут) + `victor/books per-tenant-backup-and-observability` (Фаза 2 — per-tenant backups настроены до физического переезда)
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-24T12:02:19.507Z -->
---
## 🔵 [books-dns-cutover-bookva] — Ops-таска для Фазы 4, шаг 5 дизайна `tenant-split` из victor/books. DNS switch `*.bookva.<tld>` → новый VDS IP, с parallel-run старого bookva-стека на shared VDS 7 дней без публичного hostname.
**Контекст dev-source:** дизайн в victor/books `.wiki/concepts/tenant-split.md` § «Фаза 4».
**Acceptance:**
- DNS `*.bookva.<tld>` (или конкретный hostname Bookva — определяется учредителем) указывает на новый VDS IP.
- Старый bookva-стек на shared VDS остаётся запущенным, **без публичного hostname** (traefik labels убраны или disabled), доступен только по docker-сети для возможного отката.
- Smoke с двух разных сетей (mobile + офисный wifi) — `https://<bookva-hostname>` отвечает с нового VDS.
- Per-VDS backup'ы на новом VDS подтверждены — есть snapshot спустя 24ч после DNS-switch'а.
- Через 7 дней parallel-run без откатов — decommission старого bookva-стека (см. Фаза 4, шаг 7 в spec).
**Status:** blocked
**Where I stopped:** (not started)
**Next action:** **Pre-step:** прочитать `concepts/tenant-split.md` § «Фаза 4, шаги 47» в victor/books.
1. Maintenance window 12ч (объявить за 7 дней).
2. Финальная синхронизация: `mysqldump mariadb-bookva` на текущем VDS → `mysql` на новом VDS (если schema/data разошлись с момента Фазы 2).
3. Smoke на новом VDS до DNS-switch'а: hosts-файл override → проверить login + base flow.
4. DNS-switch: меняем A-record(s) для bookva-hostname на new IP. TTL=300 уже стоял (Phase 4 step 1).
5. Через 1ч (TTL expiry + propagation): smoke с двух сетей.
6. На старом VDS — отключить traefik labels для bookva-стека (контейнеры продолжают работать, но не доступны снаружи).
7. **Parallel-run 7 дней.** Каждый день — smoke. Per-VDS backup на новом VDS — проверить хотя бы 1 успешный snapshot.
8. Если за 7 дней проблем нет → закрыть с note «cutover stable». Если есть — DNS rollback на старый IP, follow-up debug task в victor/books.
9. **Decommission** старого bookva-стека на shared VDS (отдельный шаг, не в этой таске — финальный backup в архив + `docker compose down` + volume drop).
**Blocker:** `books-vds-bookva-bootstrap` + victor/books `pwa-redirect-handoff` (SW bump выкачен в shared API за 12 недели до этой таски).
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-24T12:02:41.503Z -->
---
## ⚪ [books-bookva-user-whitelist-gathering] — **Процессная** ops-таска для Фазы 3, шаг 1 дизайна `tenant-split` из victor/books. Получить от учредителя Bookva письменный список пользователей, которые допущены к Bookva-инсталляции. Без этого списка cutover не возможен — иначе утечка доступа: либо лишние юзеры получат доступ к Bookva (через копирование «всех users»), либо легитимные юзеры заблокированы (через пустой whitelist).
**Direction:** Bookva — новая инсталляция, начинается с whitelist'а (закрытый список). Slovo — остаётся на текущем стеке, получает копию всех текущих users (статус-кво).
**Контекст dev-source:** дизайн в victor/books `.wiki/concepts/tenant-split.md` § «Двухуровневая изоляция пользователей → App-level» и § «Фаза 3, шаг 1».
**Не блокируется ничем** — можно начинать gathering сразу, лаг до cutover'а может быть значительным.
**Acceptance:**
- Письменный список от учредителя Bookva (email или подписанный документ): ФИО + role (если знают).
- Список зафиксирован в `OpeItcLoc03/admin/.wiki/concepts/books-bookva-whitelist.md` или в отдельной таблице.
- Для каждой строки списка сверка с текущей `users`-таблицей shared БД: user существует / роль соответствует / email актуален.
- Любые расхождения (запрошенный user не существует в shared / роль другая) — обработаны: создать новый user в Bookva-БД post-cutover ИЛИ скорректировать список с учредителем.
**Status:** ready
**Where I stopped:** (not started)
**Next action:** 1. Отправить учредителю Bookva формальный запрос (email/мессенджер): «Для tenant-split нужен список пользователей, которые останутся в Bookva после разделения. Формат: ФИО + роль + email/login. Список будет применён на cutover'е как whitelist».
2. Дождаться ответа (это может занять дни/недели — нормально).
3. Получив список — сверить с `users`-таблицей shared БД:
```sql
SELECT id, login, email, role FROM users WHERE email IN (<list>) AND deleted_at IS NULL;
```
4. Разобрать расхождения с учредителем (missing / role mismatch / inactive).
5. Зафиксировать финальный список в `OpeItcLoc03/admin/.wiki/concepts/books-bookva-whitelist.md` (или в local-only encrypted file если NDA-чувствительно).
6. Финальный список становится input'ом для Фазы 3, шаг 1: при настройке Bookva-БД в неё попадают **только** эти users.
7. Закрыть с note: «whitelist (N users) подтверждён учредителем, готов к применению на cutover'е».
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-24T12:03:18.548Z -->
## 🔵 [books-stateful-split-execution] — Ops-таска для **Фазы 1** дизайна `tenant-split` из victor/books. Выполнить playbook на shared VDS в maintenance window — docker volume copy для MariaDB + Mongo + MinIO bucket rename + DELETE cleanup. Identical bit-for-bit копии через `cp -a` alpine helper. Никаких mysqldump/mongodump/mc cp.
**Playbook (dev-source, читать целиком до начала):** `victor/books/.tasks/stateful-split-volume-copy.md`.
**Контекст дизайна:** `mcp__projects-meta__knowledge_get slug=concepts/tenant-split` § «Фаза 1 — Physical stateful split + overlay-repos». Brainstorm trace: `~/projects/.workshop/.archive/2026-05-24-books-tenant-split.md`.
**Container naming:** drop `books-` prefix → `bookva-<svc>` / `slovo-<svc>`.
**TDD-режим:** `[skip-tdd: one-off migration on maintenance window]` — verify через post-cleanup audit.
**Acceptance:**
- `bookva-db` + `slovo-db` контейнеры живые, audit `SELECT DISTINCT idSeller` = `{1}` / `{2}` соответственно.
- `bookva-mongo` + `slovo-mongo` контейнеры живые, agenda-история preserved, jobs чужого tenant'а cleanup'нуты.
- MinIO (один shared) имеет bucket'ы `bookva` + `slovo` вместо `books`; объекты чужого tenant'а удалены.
- Shared catalog tables (`books`, `editions`, `epz`, `epz_pages`, `warehouses`, `products`) — полные копии в обеих БД.
- Smoke с двух сетей: login через `bookva.<tld>` → Bookva-данные; текущий URL → Slovo.
- Через 7-14 дней parallel-run без откатов → cleanup старых `books-*` контейнеров и volumes (отдельный заход).
**Status:** blocked
**Where I stopped:** (not started)
**Next action:** **Pre-step:** прочитать `victor/books/.tasks/stateful-split-volume-copy.md` целиком. Убедиться что 7 open questions resolved (закрыто dev-prep таской `victor/books stateful-split-volume-copy`): FK CASCADE, units/receipts strategy, MinIO key structure, users whitelist, task_runs handling, chrome/traefik shared.
1. Подтвердить overlay-репо `victor/bookva-overlay` + `victor/slovo-overlay` готовы — compose-файлы для `bookva-*` / `slovo-*` стеков на месте.
2. Подтвердить per-tenant backups настроены (`victor/books per-tenant-backup-and-observability`) — иначе нет точки rollback.
3. Объявить maintenance window 1-2ч (без записи).
4. Execute Steps 0-11 из playbook на shared VDS.
5. Post-execution audit: `SELECT DISTINCT idSeller FROM <each>`, `db.agendaJobs.distinct('data.idSeller')`, `mc ls` on MinIO.
6. Smoke с двух сетей.
7. Через 7-14 дней parallel-run без откатов → cleanup старых `books-*` контейнеров+volumes (отдельный заход).
8. Closing note: «Physical split done, bookva-* + slovo-* контейнеры живут на shared VDS, audit clean, parallel-run start <date>».
**Blocker:** `victor/books stateful-split-volume-copy` (dev-prep — 7 open questions resolved + dev-DB test passed) + `victor/books per-tenant-backup-and-observability` (Фаза 2 — per-tenant backups настроены)
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-25T04:46:48.271Z -->
---