diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index a0c243e..6919be5 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -1,4 +1,5 @@ # Admin Task Board +_Updated: 2026-06-13 — 🟢 **[migrate-assets-originals-to-s3] closed.** assets-оригиналы (весь `App_Data\assets`: 4750 obj / 215.5 MiB, 145 owner-папок) залиты в новый MinIO bucket `assets` (books-vds) rclone'ом с RUVDS IIS, ключи `/` verbatim. Verify count+size == source. Smoke (мимо LAN-DNS): brevno.jpg → 200 image/webp 64556 B (был 404), валидно-подписанный несуществующий объект → 404 (негатив-контроль). Код snolla не менялся (path A); scope намеренно шире pilorama98 — закрывает класс-404 для всех тенантов snolla, регрессии нет (shared bucket, как galleries). ⚠️ snolla-side остаётся `content-api/routes/assets.js` (пустой stub) — без него картинки не рендерятся на сайте. Inbox victor/snolla отправлен._ _Updated: 2026-06-12 (4) — 🟢 **[migrate-gallery-originals-to-s3] closed (scope pilorama98).** Галереи snolla не отдавались (imgproxy 404) т.к. в legacy `storageClient="galleries"` = тип **Local** (диск `App_Data\galleries\`), НЕ S3 — оригиналы никогда туда не заливались (продукты — заливались, bucket `pilorama98`). Развилка A/B закрыта фактами MinIO → **A**: создан bucket `galleries`, залиты 301 файл (77 MiB) pilorama98 (siteId `37e67fc4…`) с RUVDS IIS через rclone → `s3://galleries//.jpg` verbatim (== ровно то, что строит `middleware/galleries.js:47`). Код snolla НЕ менялся. Verify: count+size == source. Smoke с books-vds: реальный объект imgproxy → 200 webp, fake → 404. Уточнение инфра: `imgproxy.kzntsv.site` с 08.06 на **books-vds** (стек 29/30), не на windows-host — `minio-imgproxy-on-vds.md` был stale. Inbox victor/snolla отправлен._ _Updated: 2026-06-12 (3) — 🟢 **bookva-es snapshot done** (не отложен). Portainer stack 37 пересоздан с `path.repo=/snapshots`+bind (PUT API, том цел, epz/products уцелели), repo `kreknin` зарегистрирован, snapshot-блок в `run.sh`. Поймана коллизия basename `snapshots` (оба ES-каталога одноимённы → сливались в один dest-репо, порча обоих) → источник bookva-es = родительский `/usr/docker/bookva-es`. Verified: `BOOKS-VDS backup OK 10m28s`, на kreknin раздельно `snapshots/`(slovo index-41) + `bookva-es/snapshots/`(index-4). Таска `bookva-es-snapshot-repo` 🟢 closed._ _Updated: 2026-06-12 (2) — 🟢 **bookva-* backup gap закрыт.** bookva tenant (db/mongo/es/minio, поднят 26.05) не бэкапился — books-скрипт написан 25.05 до bookva, покрытие не расширили (висело wiki-follow-up #2). Добавлены bookva-db (тот же root pw), bookva-mongo (no-auth), bookva-minio (raw volume) в `books-vds-backup-daily-kreknin/run.sh`; деплой == репо (`.bak-pre-bookva`). Verified green: `BOOKS-VDS backup OK 10m42s`, артефакты на kreknin (bookva-mariadb 257M, bookva-mongo 3.2M, bookva-minio 1.4G). bookva-es отложен → `bookva-es-snapshot-repo` (покрыт slovo-снапшотом, индексы идентичны). Правило в память: новый stateful → бэкап в том же коммите._ @@ -432,7 +433,10 @@ vehicles-loader (stostayer) деплоится в Docker у клиента (lite --- -## ⚪ [migrate-assets-originals-to-s3] — Залить Local-storage assets-оригиналы сайта pilorama98 в S3 — латентная дыра того же класса, что галереи (закрыта миграцией `migrate-gallery-originals-to-s3`). snolla отдаёт inline-картинки контента (``) через imgproxy с источником `s3://assets//`, но объектов в S3 нет — imgproxy 404 "Source image is unreachable". БД-записи есть, файлы только на legacy-IIS диске. Тип `StorageClient="assets"` — это `MoreThenCms.FileStorage.Local.*`, в S3 никогда не мигрировали. +## 🟢 [migrate-assets-originals-to-s3] — closed 2026-06-13 — assets-оригиналы залиты в S3, imgproxy 200 verified (scope расширен: весь assets-дерево, не только pilorama98). Создан bucket `assets` (отсутствовал) на MinIO books-vds; rclone RUVDS IIS `App_Data\assets` → `s3://assets//` verbatim. **Verify:** dest == source точь-в-точь — 4750 объектов / 225 935 853 B (215.5 MiB), 145 owner-папок. **Smoke (через books-vds, мимо LAN-DNS):** brevno.jpg (предподписанный URL из задачи) → 200 image/webp 64556 B (был 404); валидно-подписанный несуществующий объект → 404 (негативный контроль). Код snolla НЕ менялся (path A). Inbox victor/snolla отправлен. ⚠️ Остаётся snolla-side: `content-api/routes/assets.js` пустой stub — картинки не поедут на сайт пока роут не реализован (код-таска snolla, не блокер миграции). + +### (исходное описание ниже сохранено до prune) +Залить Local-storage assets-оригиналы сайта pilorama98 в S3 — латентная дыра того же класса, что галереи (закрыта миграцией `migrate-gallery-originals-to-s3`). snolla отдаёт inline-картинки контента (``) через imgproxy с источником `s3://assets//`, но объектов в S3 нет — imgproxy 404 "Source image is unreachable". БД-записи есть, файлы только на legacy-IIS диске. Тип `StorageClient="assets"` — это `MoreThenCms.FileStorage.Local.*`, в S3 никогда не мигрировали. ## Acceptance criteria 1. Legacy assets-оригиналы pilorama98 залиты в S3 bucket `assets` ключами `/` (path A, как с галереями: storageClient = имя бакета). @@ -469,11 +473,19 @@ vehicles-loader (stostayer) деплоится в Docker у клиента (lite **weight:** needs-human **notify:** victor/snolla -**Status:** ready -**Where I stopped:** (not started) -**Next action:** Найти legacy-диск assets-оригиналов pilorama98, залить в S3 bucket `assets` ключами `/`, прозвонить контрольный imgproxy-URL → ждём 200. -**Branch:** n/a -**Notify:** victor/snolla +**Status:** done (closed 2026-06-13) +**Where I stopped:** мигрировано всё дерево assets. rclone size min:assets == источник (4750 / 225935853). Smoke 200/404 OK. +**Next action:** — (хвост на стороне snolla: реализовать `content-api/routes/assets.js`; остальные Local-классы images/scripts/stylesheets/watermarks — отдельный аудит snolla, если поднимутся через imgproxy). +**Branch:** master +**Notify:** victor/snolla — ✅ inbox `.claude-inbox/2026-06-13T20-14-16Z-admin.md` + +**Closure note (2026-06-13):** +- **Диск (RUVDS IIS `C:\sites\snolla\App_Data\assets`):** Local storage class, 145 owner-папок (32-hex), плоские файлы. brevno owner `83150d77…` = 6 файлов, `brevno.jpg`=580667 B == DB `Files.Size`. Ключ-форма `/` подтверждена на диске. +- **MinIO (books-vds, minio.kzntsv.site):** bucket `assets` отсутствовал → создан. Залив rclone v1.74.2 (env-var s3-remote, без записи cred), `App_Data\assets` → `min:assets` verbatim. Verify `rclone size` == source: 4750 объектов / 225935853 B. +- **Smoke (мимо LAN-DNS воркстейшна, `--resolve …:89.253.255.133`):** предподписанный imgproxy-URL brevno.jpg → 200 image/webp 64556 B; валидно-подписанный (IMGPROXY_KEY/SALT с books-vds) несуществующий объект → 404 text/plain. 200 не ложный — imgproxy реально ходит в S3. +- **Scope расширен намеренно:** задача про pilorama98, залито всё (215 MiB — мизер). owner→сайт маппинг неочевиден (риск пропустить owner pilorama98), заливка всего гарантирует покрытие + закрывает класс-404 для всех тенантов. Регрессии нет (shared bucket, как galleries). +- **Wiki:** concept `galleries-storage-class-local-not-s3` обновлён (assets done). + --- diff --git a/.wiki/concepts/galleries-storage-class-local-not-s3.md b/.wiki/concepts/galleries-storage-class-local-not-s3.md index 2cb2f64..b7354d6 100644 --- a/.wiki/concepts/galleries-storage-class-local-not-s3.md +++ b/.wiki/concepts/galleries-storage-class-local-not-s3.md @@ -53,6 +53,12 @@ curl -sk --resolve imgproxy.kzntsv.site:443:127.0.0.1 'https://imgproxy.kzntsv.s - **pilorama98** (siteId `37e67fc44b9e4c06a522a26a73bac9b0`): мигрирован 2026-06-12 — 301 файл / 77 MiB, imgproxy 200 verified. - **Остальные ~40 siteId-папок** в `App_Data\galleries` — НЕ мигрированы (часть пустые). Bucket `galleries` shared; заполнен только префикс pilorama98. Другие сайты в snolla → 404 пока не зальёшь (регрессии нет). -- Если поднимаются другие Local-классы (`assets`/`images`/…) в snolla через imgproxy — их ждёт та же дыра, тот же рецепт. +- Если поднимаются другие Local-классы (`images`/`scripts`/`stylesheets`/`watermarks`) в snolla через imgproxy — их ждёт та же дыра, тот же рецепт. -См. задачу `.tasks/STATUS.md` → `[migrate-gallery-originals-to-s3]`. +### `assets` класс — мигрирован 2026-06-13 + +Тот же Local-класс, тот же путь A. **Отличие ключа:** prefix = `OwnerId` медиа-папки (из таблицы `Folders`), **НЕ siteId**; snolla строит `s3://assets//` (`middleware/assets.js:98`), storageFilename плоский. Залит **весь** `C:\sites\snolla\App_Data\assets` (145 owner-папок, 4750 файлов / 215.5 MiB) в новый bucket `assets` rclone'ом с RUVDS — scope шире pilorama98 (owner→сайт маппинг неочевиден; заливка всего гарантирует покрытие + закрывает класс для всех тенантов). Verify count+size == source. Smoke: brevno.jpg → 200, валидно-подписанный фейк → 404. + +⚠️ На стороне snolla `content-api/routes/assets.js` — пустой stub: объекты в S3 есть и отдаются через imgproxy, но inline-картинки контента не отрендерятся, пока роут не реализован (код-таска snolla). + +См. задачи `.tasks/STATUS.md` → `[migrate-gallery-originals-to-s3]`, `[migrate-assets-originals-to-s3]`.