docs(wiki): namespace-consolidation + admin-api-embed concepts

Документированы два крупнейших изменения сессии 2026-08-04/05:
- Неймспейс-миграция @snollajs→@snolla (17 пакетов, 8 сайтов)
- Admin-api embed в pilonuxt /admin/api, retire стека 25

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-05 00:24:42 +03:00
parent 1becee760c
commit 543b10a464
5 changed files with 175 additions and 43 deletions

View File

@@ -1,58 +1,62 @@
--- ---
_last_updated_: 2026-08-04T18:33:00Z _last_updated_: 2026-08-05T00:35:00Z
session_id: 2026-08-04-admin-s2-review session_id: 2026-08-05-admin-namespace-migration-embed
prev_session_id: 2026-08-04-admin-camel-cancel-reverted prev_session_id: 2026-08-04-admin-s2-review
--- ---
# Next session handoff # Next session handoff
## Роль продолжается: координатор + ревьюер этого же проекта (admin-api / admin-typed-api / camel-эпик / loader). 2026-08-04: S2 review APPROVE, publish + deploy HELD. ## Главное за сессию
### Роль в следующей сессии (vitya: «в следующей тоже будешь координатором и ревьювером этого же проекта») Эпик surface-normalization ЗАКРЫТ. Namespace-миграция ВЫПОЛНЕНА. Admin-api embed в pilonuxt ЗАВЕРШЁН.
- **Координатор** loader-миграции (миграция закрыта) + **ревьюер** `admin-typed-api` (S1 auth, S2 клиент,
S3 schema-gen) по контракту review-before-publish. Ревью-гейт перед публикациями в Verdaccio.
- Канал: snolla шлёт ревью-запрос в inbox → я ревьюю → финайдинги обратно. Роль зафиксирована в
`coord-loader-admin-api-client.md`.
### Состояние эпика (2026-08-04 вечер) - **S2+S3 review:** APPROVE (клиент 34/34, сервер 424/424, schema-gen 19/19)
- **S2 (`@snolla/admin-api-client` 0.3.0 + `admin-schema-gen` 0.2.0) — review APPROVE** (коммит `ed7da15`): - **Namespace-миграция:** `@snollajs/*``@snolla/*`, 14+ пакетов на Verdaccio. Все 8 сайтов бампнуты (7 руками + pilorama98). Stostayer заморожен.
клиент 20/20 + schema-gen 19/19 + tsc 0 (прогнал сам), покрытие 52/52 non-F роутов, `/move` контракт - **Admin-api embed:** pilonuxt `e95d2d9`, `/admin/api/health` 200, стек 25 retire.
сверен с сервером. Финайдинги F1F3 минорные, отправлены snolla (письмо 18-31-26Z). - **Loader:** адаптирован под camelCase-wire 0.2.0, dry-run 224/0/224. Ждёт vitya на прод-импорт.
- **Publish придержан оператором** (vitya: «публикацию пока не делаем, как и деплой»). Ждём снятия hold.
- **Деплой** — зона admin, один срез в конце эпика. Live `ca0dfa3` (Pascal), стек 25, `/health` ok.
Образ `admin-api:2ffd66a` собран на VDS, НЕ запушен — при снятии hold собрать свежий тег.
- Отмена camel — была ошибочной интерпретацией (handoff `219a8b3d`), отозвана (`6fe728aa`): S2 идёт.
### Что дальше (следующая сессия) ## Коммиты сессии (в других репо)
- Ждём сигналы: (1) снятие publish-hold от vitya, (2) snolla применяет F1F3 и перепингует,
(3) готовность S2-клиента → деплой-срез. По сигналу: publish-approve → деплой (build на VDS + | Репо | SHA | Что |
Portainer PUT стек 25, compose source-of-truth `admin/host-stacks/vds-kzntsv/admin-api.compose.yml`, |---|---|---|
smoke по чек-листу, мимо LAN-DNS). | labtools.ru | `cec15a2` | namespace bump |
- snolla может прислать фиксы F1F3 на пере-ревью (тот же коммит, uncommitted). | emspb.ru | `2ddd44c` | namespace bump |
| labtools.pro | `45006e2` | namespace bump |
| tandemmebel.ru | `423d1b0` | namespace bump |
| kupimknigi.spb.ru | `af00733` | namespace bump |
| on.snolla.com | `d892053` | namespace bump |
| maljarka.tandemmebel.ru | `7a37c29` | namespace bump |
| pilorama98.ru | `e95d2d9` | embed admin-api + namespace bump |
| pilorama98.ru | `325daa9` | prisma postinstall fix |
| pilorama98.ru | `b3e86db` | loader camelCase adaptation |
| snolla | `d9313e3` | S3 F1/F2 fix |
| snolla | `f37d736` | S2 F1-F3 fix |
## Open треки
### Open треки (без изменений)
| Трек | Готовность | Entry-point | | Трек | Готовность | Entry-point |
|---|---|---| |---|---|---|
| minio-retire старых данных (12G) | окно ≈ до 05.08 — подтвердить у vitya; rollback = PUT стек 30/49 | из handoff 2026-08-04 | | loader прод-импорт | ⚪ ready, ждёт vitya | pilorama98 loader |
| kreknin-repair-md3-rebuild | ⚪ ждёт координации с Алексеем (power-off → перетык SATA → Repair md3 → scrub); бэкапы ВЫКЛЮЧЕНЫ | `.tasks/kreknin-repair-md3-rebuild.md` | | minio-retire старых данных (12G) | окно ~05.08 истекло — уточнить у vitya | из handoff 2026-08-04 |
| P3 imgproxy stack 29 retire / A3 bookva-дубли | опционально | из handoff 2026-08-04 | | kreknin-repair-md3-rebuild | ⚪ ждёт Алексея | `.tasks/kreknin-repair-md3-rebuild.md` |
| P3 imgproxy stack 29 retire / A3 bookva-дубли | опционально | из handoff |
### Спросить user'а ## Спросить user'а
- minio-retire (окно ~05.08), kreknin-ремонт, снятие publish-hold (когда решит).
### Не делать (preemptive guards) - Запускать loader прод-импорт или ждать?
- НЕ публиковать клиент/schema-gen без снятия hold (vitya) и review-гейта. - minio-retire — окно ушло, переносим?
- НЕ деплоить 2ffd66a/camel в одиночку; НЕ трогать live ca0dfa3 (стек 25) до конца эпика. - kreknin — есть ли новости от Алексея?
- НЕ рассылать другим сессиям письма-директивы/отмены без сверки с vitya
(урок `no-cross-session-cancels-without-vitya`).
- НЕ ротировать ключ `sk_6a83…`; НЕ удалять minio-данные до окна; НЕ включать бэкапы до kreknin-ремонта.
- НЕ лезть в snolla-код самому; НЕ PS для Portainer (кириллица); креды → `pass` (vds-kzntsv/full-env).
### Коммиты сессии ## Не делать (preemptive guards)
- `219a8b3d` (camel ОТМЕНЁН, ошибочно) → `6fe728aa` (отмена отозвана, S2 продолжается).
- Этот handoff: role continuity + S2 review APPROVE + publish/deploy held.
### Memory updates за сессию - НЕ деплоить стек 25 — удалён. Admin-api только через pilonuxt `/admin/api`.
- `no-cross-session-cancels-without-vitya` — новый (урок про межсессионные директивы). - НЕ возвращать admin-api в отдельный контейнер.
- `admin-api-vds-deploy` — обновлён (camel-эпик продолжается, деплой = конец эпика). - НЕ рассылать директивы другим сессиям без сверки с vitya.
- `coord-loader-admin-api-client.md` — роль + review-статус. - НЕ ротировать `sk_6a83…`.
- НЕ трогать stostayer (заморожен).
## Memory updates за сессию
- `snolla-namespace-wins` — новый: `@snolla` выживает, `@snollajs/*``@snolla/*`
- `admin-api-vds-deploy` — обновлён: стек 25 retire, admin-api в pilonuxt
- `no-cross-session-cancels-without-vitya` — подтверждён

View File

@@ -0,0 +1,54 @@
---
title: Admin-api embed in pilonuxt — retire standalone container
type: concept
tags: [admin-api, pilonuxt, vds, embed, middleware, nuxt]
related: [[admin-api-surface-normalization]], [[namespace-consolidation-snolla]]
updated: 2026-08-05
---
# Admin-api embed in pilonuxt
Оператор (vitya) постановил 2026-08-04: admin-api должен жить в `apps/web`
как Nuxt-server-middleware, а НЕ отдельным контейнером. По образу `@snolla/content-api`
и `@snolla/forms-api`.
## Архитектура
```
piloruxt (стек 16)
├── /snolla/* → @snolla/content-api (useBase)
├── /snolla-forms/* → @snolla/forms-api (useBase)
└── /admin/api/* → @snolla/admin-api (useBase) ← НОВОЕ
```
## Реализация
- Пакет: `@snolla/admin-api@0.2.0`
- Экспорт: `createAdminMiddleware({prefix})` — Fastify-плагин без `.listen()`
- Маунт: `server/routes/admin/[...].ts` = `useBase('/admin/api', fromNodeMiddleware(createAdminMiddleware({prefix:''})))`
- Конфиг: `JWT_SECRET` + `DATABASE_URL` + `S3_*` в env контейнера (fail-fast в buildApp)
- Prisma: `prisma generate --schema` в Dockerfile (отдельный RUN, не postinstall)
## Деплой
- Образ: `registry.kzntsv.site/pilonuxt:e95d2d9` (2026-08-05)
- Стек: Portainer 16 (pilonuxt)
- Env: `JWT_SECRET`, `DATABASE_URL`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`
## Стек 25 — RETIRED
Старый standalone admin-api (`admin-api.vds.kzntsv.site`, стек 25) удалён из Portainer.
Контейнер `admin-api` остановлен и удалён.
## Smoke (прод)
- `/admin/api/health` → 200 `{"status":"ok"}`
- `/admin/api/stores?siteId=...` → 401 (auth required, правильно)
- `/` → 200
- `/catalog` → 200
- `/snolla/pages` → 200
## Loader
Адаптирован под camelCase-wire 0.2.0. baseUrl → `https://pilorama98.ru/admin`.
Dry-run 224/0/224 PASS. Ждёт vitya на прод-импорт.

View File

@@ -0,0 +1,70 @@
---
title: Snolla namespace consolidation — @snollajs@snolla
type: concept
tags: [snolla, verdaccio, namespace, migration, admin-api]
related: [[../entities/vds-kzntsv]], [[verdaccio-token-lifecycle]]
updated: 2026-08-05
---
# Snolla namespace consolidation
Оператор (vitya) постановил 2026-08-04: выживает неймспейс **`@snolla`**.
`@snollajs/*` мигрируют В `@snolla/*`.
## Причина
`@snolla/admin-api`, `@snolla/admin-api-client`, `@snolla/admin-schema-gen` уже были
опубликованы под `@snolla`. Дробить на два неймспейса не имело смысла.
## Опубликованные пакеты (Verdaccio, волна 2026-08-04)
| Старое имя | Новое имя | Версия |
|---|---|---|
| `@snollajs/data` | `@snolla/data` | 0.15.0 |
| `@snollajs/liquid` | `@snolla/liquid` | 0.11.0 |
| `@snollajs/numbering` | `@snolla/numbering` | 0.7.5 |
| `@snollajs/mailer` | `@snolla/mailer` | 0.8.3 |
| `@snollajs/forms-core` | `@snolla/forms-core` | 0.1.0 |
| `@snollajs/core` | `@snolla/core` | 0.26.6 |
| `@snollajs/forms-api` | `@snolla/forms-api` | 0.1.0 |
| `@snollajs/snolla` | `@snolla/snolla` | 0.43.2 |
| `@snollajs/content-api` | `@snolla/content-api` | 0.18.0 |
| `@snollajs/content-api-client` | `@snolla/content-api-client` | 0.10.0 |
| `@snollajs/forms-api-client` | `@snolla/forms-api-client` | 0.1.0 |
| `@snolla/site-schema-gen` | `@snolla/content-schema-gen` | 0.6.0 (rename) |
| `@snolla/cli` | (bump) | 0.12.0 |
| `@snolla/theme-check` | (bump) | 0.3.0 |
| - | `@snolla/admin-api` | 0.2.0 |
| - | `@snolla/admin-api-client` | 0.3.0 |
| - | `@snolla/admin-schema-gen` | 0.2.0 |
## Консьюмеры
Все сайты тиража snolla на VDS обновлены 2026-08-04/05:
| # | Сайт | Стек | Пакет |
|---|---|---|---|
| 1 | pilorama98.ru | 16 | `@snolla/content-api` + `@snolla/forms-api` |
| 2 | labtools.ru | 17 | `@snolla/snolla` |
| 3 | emspb.ru | 18 | `@snolla/snolla` |
| 4 | labtools.pro | 19 | `@snolla/snolla` |
| 5 | tandemmebel.ru | 20 | `@snolla/snolla` |
| 6 | kupimknigi.spb.ru | 21 | `@snolla/snolla` |
| 7 | on.snolla.com | 22 | `@snolla/snolla` |
| 8 | maljarka.tandemmebel.ru | 23 | `@snolla/snolla` |
| 9 | stostayer.new | 16 | **заморожен** (0.3.18, не пересобрать) |
## Паттерн бампа
Для каждого сайта:
1. `apps/web/package.json`: `@snollajs/snolla``@snolla/snolla@0.43.2`
2. `apps/web/index.js`: `from '@snollajs/snolla'``from '@snolla/snolla'`
3. `.yarnrc.yml`: добавить scope `@snolla` (Verdaccio) + `npmPreapprovedPackages`
4. `yarn install --no-immutable` → fresh lockfile
5. Build на VDS, push в registry, Portainer PUT (env-preserving, pullImage:true)
6. Live smoke: /, /robots.txt, /sitemap.xml, theme assets
## Старые имена
`@snollajs/*` остаются на Verdaccio (заморожены, не обновляются). Удаление — отдельным шагом,
после полной миграции всех консьюмеров.

View File

@@ -23,6 +23,8 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever
## Concepts ## Concepts
- [admin-api-embed-pilonuxt](concepts/admin-api-embed-pilonuxt.md) — admin-api embedded in pilonuxt /admin/api, stack 25 retired (2026-08-05)
- [namespace-consolidation-snolla](concepts/namespace-consolidation-snolla.md) — @snollajs@snolla, 8 sites bumped, 17 packages (2026-08-04/05)
- [admin-infra-project](concepts/admin-infra-project.md) — design + migration plan для OpeItcLoc03/admin (canonical) - [admin-infra-project](concepts/admin-infra-project.md) — design + migration plan для OpeItcLoc03/admin (canonical)
- [backup-inventory-2026-06](concepts/backup-inventory-2026-06.md) — карта всех машин × что реально бэкапится (с доказательством); дыры по приоритету (kreknin SPOF, nl-vds x-ui.db, bookva-*, openwrt) — триггер: MSSQL 3-нед gap - [backup-inventory-2026-06](concepts/backup-inventory-2026-06.md) — карта всех машин × что реально бэкапится (с доказательством); дыры по приоритету (kreknin SPOF, nl-vds x-ui.db, bookva-*, openwrt) — триггер: MSSQL 3-нед gap
- [bindmount-config-edit-preserve-mode](concepts/bindmount-config-edit-preserve-mode.md) — правка bind-mounted config'а через mktemp+mv роняет режим 644→600 → non-root контейнер (uid 1000) EACCES crash-loop; chmod --reference=backup. + гоча: bind-mount затеняет config образа целиком → класть полную секцию, не дельту. Инциденты books-job-scheduler + task-runner 2026-06-18 - [bindmount-config-edit-preserve-mode](concepts/bindmount-config-edit-preserve-mode.md) — правка bind-mounted config'а через mktemp+mv роняет режим 644→600 → non-root контейнер (uid 1000) EACCES crash-loop; chmod --reference=backup. + гоча: bind-mount затеняет config образа целиком → класть полную секцию, не дельту. Инциденты books-job-scheduler + task-runner 2026-06-18

View File

@@ -2,6 +2,8 @@
Append-only log of wiki operations (ingests, promotions, lints, migrations). Append-only log of wiki operations (ingests, promotions, lints, migrations).
## [2026-08-05] ingest | concepts/namespace-consolidation-snolla + concepts/admin-api-embed-pilonuxt — крупнейшие изменения сессии: неймспейс-миграция @snollajs→@snolla (17 пакетов, 8 сайтов бампнуты), admin-api embed в pilonuxt /admin/api, retire стека 25. +index.md строки.
## [2026-07-30] migrate | RELOCATE runbook `scripts/minio-split-cutover/runbook.md` → `concepts/minio-split-cutover-runbook.md` (дисциплина: runbook'и → `.wiki/concepts/`, не `scripts/`; `scripts/` для executable). +UPDATE content: v3-секция (snolla 0.43.2 опубликована, live MinIO verify ЗЕЛЁНЫЙ оба конфига, resolutions=optional determinism НЕ mandatory — regression-гипотеза v3 SigV4 vs MinIO НЕ воспроизвелась end-to-end, «CONFIRMED» framing откатан), креды нормализованы → `pass show minio-vds/full-env` (были plaintext в bash-примерах — wiki-конвенция «креды в pass, не в git»). +index.md строка. Старый `scripts/minio-split-cutover/` удалён (в нём кроме runbook'а ничего не было). Cross-ref [[on-snolla-vds-deploy-runbook]], [[minio-imgproxy-on-vds]], [[snolla-live-prod-inplace-image-bump]], [[../entities/vds-kzntsv]], [[../entities/books-vds]]. Related memory: admin `aws-sdk-v3-smithy-sigv4-minio-regression`, `aws-sdk-v2-minio-2025-works-no-smithy-pin`. ## [2026-07-30] migrate | RELOCATE runbook `scripts/minio-split-cutover/runbook.md` → `concepts/minio-split-cutover-runbook.md` (дисциплина: runbook'и → `.wiki/concepts/`, не `scripts/`; `scripts/` для executable). +UPDATE content: v3-секция (snolla 0.43.2 опубликована, live MinIO verify ЗЕЛЁНЫЙ оба конфига, resolutions=optional determinism НЕ mandatory — regression-гипотеза v3 SigV4 vs MinIO НЕ воспроизвелась end-to-end, «CONFIRMED» framing откатан), креды нормализованы → `pass show minio-vds/full-env` (были plaintext в bash-примерах — wiki-конвенция «креды в pass, не в git»). +index.md строка. Старый `scripts/minio-split-cutover/` удалён (в нём кроме runbook'а ничего не было). Cross-ref [[on-snolla-vds-deploy-runbook]], [[minio-imgproxy-on-vds]], [[snolla-live-prod-inplace-image-bump]], [[../entities/vds-kzntsv]], [[../entities/books-vds]]. Related memory: admin `aws-sdk-v3-smithy-sigv4-minio-regression`, `aws-sdk-v2-minio-2025-works-no-smithy-pin`.
## [2026-07-29] implement | NEW concepts/snolla-local-admin-https-binding.md + UPDATE index.md (concepts +2 строки) — локальный .NET-админ snolla (catch-all IIS `snolla`) переведён на HTTPS. Повод: `https://pilorama98.snolla.com/admin` → 404 → ERR_CONNECTION_CLOSED. Корень 404: `pilorama98.snolla.com` не был в hosts-override → реальный DNS → VDS `89.253.255.94` → traefik без роута (системный прокси `127.0.0.1:10808` маскировал «server 127.0.0.1» в curl). pilorama98 — реальный сайт в `dbo.Sites` (Alias=pilorama98, PrimaryDomain=pilorama98.ru, Live), вне тиража-5 из design-дока. Корень ERR_CONNECTION_CLOSED: браузер HSTS-апгрейдил http→https, а локальный IIS без 443. Решение: **IIS-native self-signed wildcard `*.snolla.com` на :443 + Trusted Root**, НЕ traefik (локальный acme.json пуст → LE на snolla.com нет; traefik-as-TLS-terminator = NAT-loopback/docker.sock/URL-Rewrite/SERVER_PORT-leak готчи без выгоды). Скрипт elevated (UAC): `New-SelfSignedCertificate -Subject '*.snolla.com' -DnsName '*.snolla.com','snolla.com' -TextExtension EKU serverAuth` (гоча: `-DnsName` конфликтует с ручным SAN `2.5.29.17` → SAN через `-DnsName`) → копия в `Cert:\LocalMachine\Root` → `New-WebBinding snolla https 443 *` + `AddSslCertificate` + restart. Cert thumb `6E2212B4C13BD28E2FF680322F11741193E8C619`, SAN `*.snolla.com,snolla.com`, 10 лет — покрывает все alias'ы. hosts: добавлен `pilorama98.snolla.com` (elevated, построчно — `Get-Content -Raw` мог опустошить файл). Результат: `https://<alias>.snolla.com/admin/account/login` → 200 форма SNOLLA (pilorama98/kupimknigi/internal/tandemmebel верифицированы). **Голый `/admin` → 302 `/login` → 301 `https://www.<PrimaryDomain>/`** — предсуществующее поведение CMS (оператор подтвердил: «так и было» на RUVDS), не поломка миграции; рабочий entry-point `/admin/account/login`. `on.snolla.com` → 404: hosts стоит `internal.snolla.com` (реальный alias сайта `on` = `internal`), не `on` (design-док писал `on`). Trade-off: self-signed не LE — допустимо (админка локальная, FW закрыт). +index.md (2 строки: design-док ранее не был индексирован + новый page). Cross-ref [[snolla-local-admin-and-on-snolla-migration-design]], [[traefik-on-windows-docker-desktop]], [[stostayer-admin-minio-config]]. ## [2026-07-29] implement | NEW concepts/snolla-local-admin-https-binding.md + UPDATE index.md (concepts +2 строки) — локальный .NET-админ snolla (catch-all IIS `snolla`) переведён на HTTPS. Повод: `https://pilorama98.snolla.com/admin` → 404 → ERR_CONNECTION_CLOSED. Корень 404: `pilorama98.snolla.com` не был в hosts-override → реальный DNS → VDS `89.253.255.94` → traefik без роута (системный прокси `127.0.0.1:10808` маскировал «server 127.0.0.1» в curl). pilorama98 — реальный сайт в `dbo.Sites` (Alias=pilorama98, PrimaryDomain=pilorama98.ru, Live), вне тиража-5 из design-дока. Корень ERR_CONNECTION_CLOSED: браузер HSTS-апгрейдил http→https, а локальный IIS без 443. Решение: **IIS-native self-signed wildcard `*.snolla.com` на :443 + Trusted Root**, НЕ traefik (локальный acme.json пуст → LE на snolla.com нет; traefik-as-TLS-terminator = NAT-loopback/docker.sock/URL-Rewrite/SERVER_PORT-leak готчи без выгоды). Скрипт elevated (UAC): `New-SelfSignedCertificate -Subject '*.snolla.com' -DnsName '*.snolla.com','snolla.com' -TextExtension EKU serverAuth` (гоча: `-DnsName` конфликтует с ручным SAN `2.5.29.17` → SAN через `-DnsName`) → копия в `Cert:\LocalMachine\Root` → `New-WebBinding snolla https 443 *` + `AddSslCertificate` + restart. Cert thumb `6E2212B4C13BD28E2FF680322F11741193E8C619`, SAN `*.snolla.com,snolla.com`, 10 лет — покрывает все alias'ы. hosts: добавлен `pilorama98.snolla.com` (elevated, построчно — `Get-Content -Raw` мог опустошить файл). Результат: `https://<alias>.snolla.com/admin/account/login` → 200 форма SNOLLA (pilorama98/kupimknigi/internal/tandemmebel верифицированы). **Голый `/admin` → 302 `/login` → 301 `https://www.<PrimaryDomain>/`** — предсуществующее поведение CMS (оператор подтвердил: «так и было» на RUVDS), не поломка миграции; рабочий entry-point `/admin/account/login`. `on.snolla.com` → 404: hosts стоит `internal.snolla.com` (реальный alias сайта `on` = `internal`), не `on` (design-док писал `on`). Trade-off: self-signed не LE — допустимо (админка локальная, FW закрыт). +index.md (2 строки: design-док ранее не был индексирован + новый page). Cross-ref [[snolla-local-admin-and-on-snolla-migration-design]], [[traefik-on-windows-docker-desktop]], [[stostayer-admin-minio-config]].