From b7696aacb3eb20c5ae55420aac1d703c765e8cda Mon Sep 17 00:00:00 2001 From: vitya Date: Tue, 26 May 2026 10:59:45 +0300 Subject: [PATCH] tasks(NEXT_SESSION): refresh after bookva-tenant-cutover-prep closed 6/7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forward-looking: bookva-tenant-cutover next (when user скажет), books-api shutdown micro-task (24-48h soak ends ~2026-05-27/28), bookva-ozon-mcp image build, slovo-overlay parity audit. Memory updates: Portainer per-stack model + depends_on issue, POST+stop pattern, Mongo WT format compat 4→5/6/7, bookva plaintext passwords + auth code TODO, Gitea GITEA_* prefix reserved, Portainer Env Vars format. Co-Authored-By: Claude Opus 4.7 (1M context) --- .tasks/NEXT_SESSION.md | 73 +++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/.tasks/NEXT_SESSION.md b/.tasks/NEXT_SESSION.md index de3433c..6e01a7b 100644 --- a/.tasks/NEXT_SESSION.md +++ b/.tasks/NEXT_SESSION.md @@ -1,52 +1,65 @@ --- -_last_updated_: 2026-05-26T17:00:00+03:00 -session_id: 2026-05-26-bookva-tenant-cutover-prep-4of7 +_last_updated_: 2026-05-26T22:00:00+03:00 +session_id: 2026-05-26-bookva-tenant-cutover-prep-closed-6of7 --- # Next session handoff ## Recent commits -- `.admin ce8bf8a6` — tasks(bookva-tenant-cutover-prep): 🟡 progress 4/7 — Steps 1+3-partial+5+7 (this commit; close-of-session update) -- `.admin 4f1a4cf4` — tasks(bookva-tenant-cutover-prep): create — 7-step VDS prep (start of session, was already there from prior morning user-driven create) -- `victor/books 75ea320` — feat(deploy): web.compose.yml embed-api env switch (pushed; Portainer stack 24 PUT'нут atomic, container live, smoke green) -- `victor/books 2f7b539` — fix(ci): rename secrets.GITEA_TOKEN → BOOKVA_OVERLAY_TOKEN (Gitea reserved prefix) -- `victor/bookva-overlay 5b173de` — config-templates align to prod shape + design v3 hostname (api/scheduler templates rewritten, task-runner template NEW, README hostname table → bookseller.kzntsv.site) +- `.admin f91e51d9` — tasks(bookva-tenant-cutover-prep): 🟢 closed 6/7 (Step 6 delayed by design) +- `.admin b430bce1` — tasks(NEXT_SESSION): refresh after 4/7 progress +- `.admin ce8bf8a6` — tasks(bookva-tenant-cutover-prep): 🟡 progress 4/7 +- `victor/books 75ea320` — feat(deploy): web.compose.yml embed-api env switch (pushed; Portainer stack 24 already PUT, smoke green) +- `victor/books 2f7b539` — fix(ci): rename secrets.GITEA_TOKEN → BOOKVA_OVERLAY_TOKEN +- `victor/bookva-overlay 8bffd68` — *.compose.yml: drop depends_on (per-stack Portainer model) +- `victor/bookva-overlay 2b20a3e` — api.compose.yml: remove traefik (internal-only per design v3) +- `victor/bookva-overlay 93c2ea2` — mongo.compose.yml: pin mongo:4.2 (WiredTiger format compat) +- `victor/bookva-overlay 23eb374` — db.compose.yml: pin mariadb:10.6 (cp -a parity с books-db) +- `victor/bookva-overlay 264373d` — .env.example: design v3 hostnames +- `victor/bookva-overlay 5b173de` — config-templates align to prod shape + design v3 hostname ## Open треки | Трек | Готовность | Entry-point | |---|---|---| -| `bookva-tenant-cutover-prep` 🟡 | 4/7 done — Maintenance-window items pending | `.tasks/bookva-tenant-cutover-prep.md` § Remaining | -| `stateful-split-volume-copy` ⚪ | not started; lean playbook готов; **блокирует Step 2 + Step 4** в bookva-tenant-cutover-prep | `.tasks/stateful-split-volume-copy.md` | -| `infra-inventory` ⚪ | ready, books VDS factsheet ещё свежее (бы. 12 Portainer stacks now после migration) | `.tasks/infra-inventory.md` | -| `books-bookva-user-whitelist-gathering` ⚪ | ready, long-lead gathering (email-based) | `.tasks/books-bookva-user-whitelist-gathering.md` | -| `books-vds-bookva-bootstrap` 🔵 | blocked on tenant-split Phase 4 | `.tasks/books-vds-bookva-bootstrap.md` | +| `bookva-tenant-cutover` (NEW, not yet created) | ready после user signal — re-start 6 stopped Portainer stacks + MinIO `mc cp books bookva` + ES snapshot/restore Phase 2 + smoke с двух сетей | TBD `.tasks/bookva-tenant-cutover.md` | +| `books-api-shutdown` (NEW micro-task) | 24-48h soak window ends ≈2026-05-27/28 — `docker stop books-api` через Portainer | TBD `.tasks/books-api-shutdown.md` | +| `bookva-ozon-mcp-image-build` (NEW micro-task) | image `registry.kzntsv.site/books-ozon-mcp:master` отсутствует — нужен build в victor/books CI | TBD `.tasks/bookva-ozon-mcp-image-build.md` | +| `stateful-split-volume-copy` ⚪ | bookva-side done (db+mongo cp в bookva-tenant-cutover-prep); slovo-side ещё ⚪ (отдельный slovo-cutover-prep когда понадобится) | `.tasks/stateful-split-volume-copy.md` (нужен scope update) | +| `infra-inventory` ⚪ | ready, books VDS factsheet более свежий (теперь 9 bookva stacks дополнительно) | `.tasks/infra-inventory.md` | +| `books-bookva-user-whitelist-gathering` ⚪ | long-lead — list для bookva-db login-gate уже applied (id 1+2 only) | `.tasks/books-bookva-user-whitelist-gathering.md` | +| `books-vds-bookva-bootstrap` 🔵 | blocked on Phase 4 (новый VDS для Bookva billing) — long-term | `.tasks/books-vds-bookva-bootstrap.md` | | `books-dns-cutover-bookva` 🔵 | blocked on books-vds-bookva-bootstrap | `.tasks/books-dns-cutover-bookva.md` | -| `books-stateful-split-execution` 🔵 | blocked on dev-prep + per-tenant-backup-and-observability в victor/books | `.tasks/STATUS.md` | ## Спроси user'а -- **Maintenance window slot для `stateful-split-volume-copy` + Step 2/4 в bookva-tenant-cutover-prep.** 1-2h на books VDS — `docker stop books-db` + `cp -a` (MariaDB+Mongo) + Portainer stacks create + login-gate SQL. Когда удобно? -- **books-api shutdown micro-task** — 24-48ч soak с embed-api на books-web уже идёт. Когда соответствующий 24-48ч окно истечёт (≈2026-05-27 вечер–2026-05-28), создавать `books-api-shutdown` micro-task или просто `docker stop books-api && rm` через Portainer ad-hoc? -- **Step 6 PWA redirect timing.** Per spec — 1-2 нед до cutover. После maintenance window mwхочешь сразу выставить, чтобы users id=1 готовиться к redirect, или дождаться актуальной cutover date? -- **iis-migration descoped items** (carried over from prev session) — нет tracker tasks для 14 plan-to-migrate hostnames, source IIS decommission, LE renewal 2026-07-22, cleanup, wiki concept updates. Создать ⚪ или оставить в Closure note? (Prev session user отверг 3-way split.) +- **`bookva-tenant-cutover` — когда «поднимаем Bookva»?** Этот заход стартует cutover task: re-start 6 stopped Portainer stacks (api/web/scheduler/task-runner/ops-mcp/ntfy), `mc cp --recursive m/books m/bookva` для MinIO, ES snapshot from shared kzntsv → bookva-es restore (Phase 2 spec), smoke с двух сетей. Bookva goes LIVE на `bookseller.kzntsv.site` с login-gate (id=1+2 only). +- **`books-api-shutdown` micro-task** — soak start ≈07:00 MSK 2026-05-26, 24h ends ≈2026-05-27, 48h ≈2026-05-28. `docker stop books-api` + `docker rm` через Portainer ad-hoc, или создать tracker task'у? +- **`bookva-ozon-mcp-image-build`** — image не существует в registry. Нужно build для bookva-ozon-mcp stack. Service ещё не настроен в `victor/books` build pipeline? Создать tracker task'у с context'ом? +- **Slovo-overlay parity (out-of-scope finding)** — `.env.example` имеет `slovo.kzntsv.site` host (ещё не существует), config-templates вероятно similarly stale, README ntfy volumes naming inconsistent с bookva. Защитить slovo-overlay перед slovo-cutover task'ой? Или wait — поправим когда понадобится. +- **iis-migration descoped items** (carried over 2 sessions) — нет tracker tasks для 14 plan-to-migrate hostnames + source decommission + LE renewal 2026-07-22 + cleanup. Создать ⚪ или оставить в Closure note? Решение от прошлой сессии — отказался от 3-way split. ## Не делать (preemptive guards) -- **Не trigger `compose up bookva-*` stacks** — это scope of separate `bookva-tenant-cutover` task, не текущей prep. Stack acceptance — только "созданы + ID записан", не "запущены". -- **Не stop books-api** пока 24-48ч soak с embed-api не closed. Стек продолжает работать как fallback (любой external caller на `https://books.kzntsv.site` всё ещё идёт через books-api напрямую). -- **Не trigger Bookva deploy через deploy.yml workflow** до создания Portainer bookva stacks + записи их IDs в Gitea secrets. Workflow gracefully skip'ает (deploy.yml line 187), но shorter rollout path = avoid лишний run. -- **Не touch templates через volume edit прямо** — `bookva-overlay/config-templates/` теперь авторитетный source. Любой edit конфига = commit + push + re-populate volume. -- **Не редактировать bind-mount config файлы на VDS** (`/opt/books//config/default.json`) напрямую без `cp .bak-` — bind-mounted, change live для приложения. -- **Не trust `https://elasticsearch.kzntsv.site/`** без basicAuth — endpoint behind traefik middleware. Pwd живёт в `/opt/books/api/config/default.json` (не в pass). +- **Не trigger workflow_dispatch tenant=bookva svc=all** — PUT восстановит stopped bookva stacks через deploy.yml. bookva-web на bookseller.kzntsv.site опять станет LIVE. Только в рамках реального `bookva-tenant-cutover` решения. +- **Не stop bookva-db / bookva-mongo / bookva-es** — они running internal, no exposure, useful для testing connectivity и pre-cutover validation. +- **Не редактировать config volumes напрямую через alpine + edit** — source of truth = `bookva-overlay/config-templates/`. Любой config change = commit + push + re-populate volume через alpine cp. +- **Не стартовать books-api shutdown** до явного 24-48ч soak end + user sign-off. Stack продолжает обслуживать `https://books.kzntsv.site/*` для external callers (если есть). +- **Не push без grant в next session** — auto-push grant был session-only (Rule 4). В этой сессии user grant'нул на «делай авто-push» — следующая session требует нового grant. +- **Не restore books-db backup `/backups/books-db-pre-split-20260526-1036.tar.gz`** unless rollback — это pre-cp snapshot, текущий books-db живёт, не нужен restore. Cleanup tar после 7 дней (manual). +- **Не trust `https://elasticsearch.kzntsv.site/`** без basicAuth — endpoint behind traefik middleware. Pwd в `/opt/books/api/config/default.json`. ## Memory updates за сессию -- **Учить — Gitea secrets reserved prefix.** Repo secrets с именем начинающимся на `GITEA_*` (или `GITHUB_*`) returns 400 "invalid variable or secret name". Workaround: переименовать secret + соответствующий `secrets.X` reference в workflow. Env var name внутри shell-script может оставаться любым (мы оставили `GITEA_TOKEN` в shell, а secret назвали `BOOKVA_OVERLAY_TOKEN`). -- **Учить — Gitea token creation требует basic auth.** `POST /api/v1/users/{name}/tokens` returns "auth required" даже с admin token — endpoint специально требует username+password basic auth. Workaround: user генерит PAT через UI (Settings → Applications → Tokens). Admin token недостаточен. -- **Учить — Portainer PUT /api/stacks/ atomic.** Может одним вызовом обновить stackFileContent + Env, container recreates на diff. Pattern: GET текущий стек → modify → PUT с `{stackFileContent, env, pullImage:true, prune:false}`. Использовали для Step 7 embed-api switch. -- **Учить — embed-api auth gate в books-web matches books-api exactly.** `/api/healthz`=200 (public), любой protected endpoint без token = 401 "No token provided", с invalid token = 401 "Invalid JWT token". Identical behavior — embed = port-of-books-api, не parallel impl. -- **Pass entry added:** `gitea/victor-books-ci-bookva-overlay` — PAT scope=read:repository для clone bookva-overlay в CI. Value захардкожен в Gitea secret `BOOKVA_OVERLAY_TOKEN` в victor/books, pass = backup. -- **Reference:** [[bookva-tenant-cutover-prep]] § Decisions log — full session trace для 4 closed steps. -- **Reference:** [[../.wiki/concepts/portainer-stack-management-books-vds]] — books VDS Portainer endpoint 1 = primary, 12 stacks managed (legacy SSH-compose for elasticsearch/mongo/minio/books-db/traefik/portainer ушли — `books-vds-stacks-to-portainer` task closed 2026-05-25). При проверках `books-job-scheduler-mongoconfig`/`-mongodb` volumes остаются именами от legacy migration; новые bookva-* следуют new convention. +- **Учить — Portainer stack = own compose project.** Cross-stack `depends_on` references вызывают "undefined service" при deploy. Either remove depends_on, или deploy всё одним мега-stack'ом через docker-compose.yml `include`. +- **Учить — Portainer POST + immediate stop pattern.** `POST /api/stacks/create/standalone/string?endpointId=N` deploys+starts. Чтобы получить stack ID без running container — POST + `POST /api/stacks//stop?endpointId=N` сразу. Stack record persist (Status=2), deploy.yml workflow restarts at PUT. +- **Учить — MariaDB / MongoDB versions нужно match для cp -a parity.** WiredTiger format меняется между Mongo major versions (4.x → 5/6/7 incompatible, crash exit 62). MariaDB minor patches transparent внутри 10.x. Upgrade — отдельная chain task, не во время data copy. +- **Учить — Mongo data в books-job-scheduler bind-mount.** Volume `books-job-scheduler-mongodb` существует но empty (4K) — real data в `/opt/books/job-scheduler/mongo/db` host bind path. Same pattern с books-db (`/usr/docker/books-db/data`). Always inspect mounts, не trust volume name listing. +- **Учить — bookva passwords plaintext в DB.** `users.password` это plaintext (не bcrypt), validate via `user.password !== password` в `packages/web/server/api/auth/login.post.js`. TODO comment в коде "replace with proper bcrypt comparison". Security debt. varchar(45) limit — login-gate UUID() (36 chars) fits. +- **Учить — Gitea CI clone via PAT.** `git clone https://oauth2:${PAT}@git.kzntsv.site/...` pattern. PAT scope=`read:repository` достаточно. Secret name НЕ должен начинаться с `GITEA_*` или `GITHUB_*` (reserved). +- **Учить — Portainer Env Vars в Stack.** При POST/PUT передаются как `[{"name":..., "value":...}]` массив. Compose может substitute через `${VAR_NAME}`. Persist в stack record (`/api/stacks/` → Env field). +- **Учить — embed-api auth gate в books-web identical к books-api.** `/api/healthz`=200 public, любой protected endpoint без auth = 401 "No token provided", invalid token = 401 "Invalid JWT token". Identical behavior — embed = port-of-books-api. +- **Reference:** [[bookva-tenant-cutover-prep]] § Closure note — full session trace для 6 closed steps + 8 cross-repo commits. +- **Reference:** Pass entries — `books-vds/full-env` (BOOKS_PORTAINER_URL + BOOKS_PORTAINER_API_KEY + BOOKS_DB_ROOT_PASSWORD + MINIO_ACCESS_KEY), `gitea/admin-token`, `gitea/victor-books-ci-bookva-overlay` (PAT scope=read:repository). +- **Reference:** Backup artefacts — `/backups/books-db-pre-split-20260526-1036.tar.gz` (483MB) + `/backups/books-mongo-pre-split-20260526-1040.tar.gz` (234MB) on books VDS. Manual cleanup после 7+ дней.