Перейти к основному содержимому

Historical /new Handoff (superseded)

Historical snapshot: 2026-06-13. Do not use this file to start an agent, deploy, change cron, or copy any command from it without current verification. It contains obsolete master and S3 deployment instructions.

Current agent entrypoint: AI-CONTINUATION-HANDOFF-2026-07-29.md (выведен в архив: docs/_archive/docs-archive-2026-08-history.zip) (предыдущий, от 2026-07-20, описывает уже прошедший этап). Start with for-ai-agents/START-HERE.md, AGENTS.md, CLAUDE.md, MCP Vestige/RAG searches, and then that continuation handoff. The current local worktree is /Volumes/2TB-64/NEW_MP/gwptd-analytics on next/spec-platform.

The material below is retained only as historical context for the June /new rollout. It is not an operational runbook.

2. АРХИТЕКТУРА «ПАРАЛЛЕЛЬНЫЕ СИСТЕМЫ» (решение владельца)

  • Старый интерфейс: mp.hyp.ru/admin (янтарная шапка) — прод s2, данные legacy. ЗАМОРОЖЕН (только критфиксы).
  • Новый интерфейс (КЛОН): mp.hyp.ru/new (изумрудная шапка, «· NEW») — контейнер gwptd-app-new на s3, проксируется прод-nginx s2 (/data/hypertime/app/docker/nginx/conf.d/50-gwptd.conf location ^~ /new → 10.0.1.7:8009; бэкап .bak-20260611).
  • SSO-переключение: InterfaceSsoController (HMAC 60с, секрет INTERFACE_SSO_SECRET одинаков в s2 .env.production и s3 /opt/gwptd-new-ui/.env).
  • Принципы: автоматика бежит ровно в одном мире (выключатель); ручные кнопки можно в обоих; страницы клона переводятся на Data API ПО ОДНОЙ.
  • Data API: контейнер gwptd-data-api на s3 (образ из data_api/ ЭТОГО репо; деплой = rsync data_api/ s3:/opt/gwptd-data-api/ + docker build), сеть gwptd-v3-net, хост-публикация 127.0.0.1:8010 (контейнер слушает 8088), токен DATA_API_TOKEN в env клона. Живое (read-only сверка 2026-07-19 на runtime 3dff005): /health=200, /facts/stocks-daily, /control/endpoints GET, /reports/sales/{wb,ozon,ym,lamoda}-products; /status/freshness=404 (не смонтирован в этом runtime). Остальное 501 — достраивать по мере перевода страниц.

Клон: пересборка (стандартная процедура)

ssh s3 "cd /opt/gwptd-new-ui && git pull && docker build -q -t gwptd-app-new . \
&& docker rm -f gwptd-app-new && docker run -d --name gwptd-app-new \
--restart unless-stopped --network repo_gwptd-dev-net -p 0.0.0.0:8009:8000 \
-v /opt/gwptd-new-ui/.env:/var/www/html/.env:ro gwptd-app-new \
&& docker network connect gwptd-v3-net gwptd-app-new"

Клон бежит с master (вариантность через env: INTERFACE_VARIANT=new, SESSION_PATH=/new, DB_INTAKE_HOST=gwptd-v3-mysql). Прод-деплой: push master → GHA → gh run watch + health 200.

⚠️ (2026-07-12) После пересоздания контейнера ОБЯЗАТЕЛЬНО перекэшировать конфиг — иначе весь /new/* отдаёт 404:

docker exec gwptd-app-new sh -c "php artisan config:cache && php artisan route:cache && php artisan view:cache && php artisan filament:optimize"

.env клона = симлинк /opt/gwptd-new-ui/.env/etc/gwptd/secrets/app-new.env (с 2026-07-12). История: консолидация секретов 2026-07-11 завела симлинк на общий app.env БЕЗ interface-ключей (INTERFACE_VARIANT, DATA_API_BASE_URL/TOKEN, DB_KERNEL_/DB_INTAKE_) — /new молча лежал сутки. Теперь ключи живут в app-new.env; при ротации секретов НЕ терять этот блок.

Клон-специфика в коде (всё в master)

  • AdminPanelProvider: variant=new → path('new'), Emerald+Inter+«· NEW», цветные шапки во всю ширину (renderHook head.end: .fi-topbar nav + .fi-sidebar-header); переключатель (user-menu.before).
  • AppServiceProvider: Livewire setUpdateRoute/setScriptRoute под /new/*.
  • SalesApiPage (slug sales-api) — ОБРАЗЕЦ страницы на Data API: фильтры/итоги/таблица, DataApiClient напрямую, canAccess только variant=new.
  • routes/web.php: interface-sso/redirect|consume (префикс new/ для варианта new).

3. СДЕЛАНО (хронология задач 11–13 июня) + ОТКРЫТО

Всё ниже ✅ сделано и задеплоено на 2026-06-13. Что ещё не сделано — в конце §3 блок «ОТКРЫТО».

  1. «Остатки (API)» в клоне — СДЕЛАНО 2026-06-12: StocksApiPage (slug stocks-api) на новом /reports/stocks/{mp}-products; ETL получил Ozon-шаг (stocks_json→JSON_TABLE, mp 3/4/5, бэкфил +105K строк); все 4 МП проверены в браузере (WB 810/4 076, Ozon 1 871/12 352, YM 3 215/8 770, Lamoda 1 378/3 019).
  2. «Рейтинг (API)», «Оборачиваемость (API)» (read-only) — СДЕЛАНО 2026-06-12: зеркало s2→s2_ref (rating_history, mp_turnover_daily, model_dict; scripts/refresh_s2_calc_mirror.py, крон 14:30, журнал s2_ref.mirror_sync) → Data API /compat/rating + /compat/turnover → страницы клона (slug rating-api, turnover-api), браузер-проверены на прод-данных (рейтинг май: 1 592 модели / 72,9 млн ₽; оборачиваемость 11.06: 8 370 позиций).
  3. WB FBS (mp 2) остатки — СДЕЛАНО 2026-06-12: коллектор wb.stocks_fbs (склады → баркоды content-api → /api/v3/stocks чанками) + ETL-шаг; 717 строк / 4 190 шт vs legacy 4 193.
  4. Пробелы коллектора ЗАКРЫТЫ 2026-06-12: prices WB (РУБЛИ! legacy делил на 100 → мусор 220 ₽) + YM; storage WB (wb.paid_storage, async 3-step, use_cache=False обязателен; ETL build_fact_storage; в legacy мертво с 13.02); promotions wb.adverts (fullstats ТОЛЬКО статусы 9/11 с dates=[вчера], маппинг по advertId; 404 = нет статистики за дату — норма) + ozon.actions + ym.promos (intake-only, kernel-ETL промо позже). Ozon-storage = дневной агрегат в ozon_finance_transactions (items=[]) — в fact_storage_costs не кладётся (решение в docstring build_fact_storage). Аналитика WB/YM течёт в kernel ежедневно через forward-ETL из legacy mp_analytics_daily (build_fact_analytics) — V3-native коллекторы воронки = предпосылка Phase 8, не дыра в данных. Все новые эндпоинты подхватываются кроном автоматически (--mp префикс).
  5. «Отгрузка» read-only — СДЕЛАНО 2026-06-12 (восстановлено после обрыва питания: codex-задачи в analytics были тихо отклонены sandbox'ом — writable workspace был collector; следить за -C/корнем при codex exec в другой репо): зеркало shipments s2→s2_ref (4-я таблица refresh_s2_calc_mirror.py, окно 30 дней; 40 534 строки / 36 батчей) → Data API /compat/shipment-batches + /compat/shipment-lines → ShipmentApiPage (slug shipment-api, sort 8). Браузер-проверено: WB FBO 825 поз. / 39 шт / 176 915 ₽ / 52 дефицит, live-переключение на Lamoda 1 186 поз. / 116 шт / 397 952 ₽. Коммиты: 301267c analytics (запушен, GHA OK), c491ff5 collector. Известная мелочь: в селекте встречаются визуально одинаковые лейблы (разные batch_id с одной датой/составом — legacy пересчёты), ключи уникальны. 5а. ТРЕК D — D1–D3 СДЕЛАНЫ 2026-06-12: зеркало превью S20→s3 (refresh_s20_preview_mirror.py: PG preview.card через psql из контейнера gwptd-v3-postgres, COPY-формат, thumb base64→MEDIUMBLOB; → s20_ref.product_preview, 15 551 строка, крон 05:00, журнал s20_ref.mirror_sync) → Data API /reports/bestsellers (kernel fact_orders топ-N, превью скалярными подзапросами по article_upper, include_thumbs отдаёт base64; мягкая деградация без зеркала) + /dims/product-preview/{article} (image/jpeg) → BestsellersApiPage (slug bestsellers-api, сетка карточек data-URI, фильтры период/МП/топ-N), браузер-проверено (28 дней: 1 045 поз. / 5 652 шт / 82,98 млн ₽). Канал s3→S20: напрямую 10.8.0.20:5432 (VPN wg, агенты→S20 односторонний; «двойной ssh» НЕ нужен и s3→s10 закрыт файрволом); pg_hba на S20 дополнен строкой host mp_preview deliveries_access 10.8.0.7/32 md5 (бэкап pg_hba.conf.bak-20260612). Ограничение фото: покрытие топ-50 продаж превью = 5/50 — фото заморожены на 2024-03, новинок Guess (текущий топ) нет; нормализация артикулов НЕ помогает (3 056 vs 3 054 матчей из 15 551). Лечится этапом 2 (свежие фото с FTP, MP-PREVIEW-CATALOG §5). Страница показывает «—»-заглушки. D4–D6 СДЕЛАНЫ 2026-06-12 (вечер): D4 — refresh_s20_attributes_mirror.py (EAV data1c.supplies 145.8K + store.deliveries 27.4K → staging s20_ref.product_attribute_raw → kernel dim_product_attribute по artikul_upper; 71 773 строки / 4 528 моделей; UNIQUE(model,source,code) → мультизначные GROUP_CONCAT; SET group_concat_max_len обязателен — строгий режим валит 1260; крон 05:20; pg_hba S20 расширен на data1c+store для 10.8.0.7). D5 — Data API /reports/sales-structure (доли продаж по значениям атрибута vs доли ассортимента, бакет «(без атрибута)») + /reports/sales-structure/attrs; reports.py разбит на пакет routers/reports/{common,sales,stocks,bestsellers,structure} (was 598 строк). D6 — SalesStructureApiPage (slug sales-structure-api, sort 10): динамический селект разреза, бары выручка-vs-ассортимент, индекс представленности; браузер-проверено (28 дней, разрез «Тип»: жен. 62.7% выручки / 21.1% ассортимента / индекс 2.98; муж. 1.30; без атрибута 0.30). Осталось: D7 (опц.) — LLM-обогащение описаний для атрибутов вне EAV (план в docs/BIG-PLAN-2026-06-11.md).
  6. ✅ Мелочь «Финансы WB»/«Детальный отчёт» — СДЕЛАНО 2026-06-12: скрыт нав-пункт WbFinancesResource ($shouldRegisterNavigation=false), остался кликабельный «Финансы WB» из AdminPanelProvider.
  7. Консолидация репозиториев — СДЕЛАНО 2026-06-12 (решение владельца): отдельный gwptd-collector упразднён, влит в этот репо (data_api/, data_api/db-migrations/, docs/data-api/); правило ручной синхронизации канон-копии V3 УПРАЗДНЕНО; старый репо с историей → NEW_MP/ARCHIVE/gwptd-collector-repo-2026-06-12; GitHub-репо gwptd-collector НЕ создавался.
  8. mcp-gwptd — полный реиндекс — СДЕЛАНО 2026-06-13: впервые с редизайна full дошёл до конца (790 файлов → 4 932 чанка, alias gwptd_codebase..._20260612_192911, blue-green); вылечен корень провалов (06.06 и 12.06): лимит усечения чанка считал 4 симв./токен, плотный код ≈2 → выход за ctx 8192 bge-m3 + батч не успевал за таймаут. Фикс в rag-tools/reindex_job.py (пирамида устойчивости: батч→половинки→поштучно с лестницей 12000/6000/3000). Индекс покрывает консолидированную базу (data_api/, docs/data-api/).
  9. Фоном (кроны s3): гейт ADR-0006 14:00; справочники 1С 04:30; зеркало расчётов s2 14:30; зеркало превью S20 05:00; зеркало EAV-атрибутов S20 05:20.

ОТКРЫТО (что НЕ сделано — отсюда продолжать)

  • D7 (опц.) — LLM-обогащение описаний для атрибутов вне EAV (источник _fld6109 на S10, 19 038 описаний). План: docs/BIG-PLAN-2026-06-11.md трек D, строка D7.
  • Этап 2 фото — ЗАВЕРШЁН 2026-06-13 (index-driven): топ-50 бестселлеров фото 5→50/50, бренд 19→50/50; 3721 фото в 300px, все с брендом. build_dav_index.py рекурсивно индексирует весь WebDAV dav.gwptd.com (логин marketing строчными!; 42 800 jpg → dav_index.tsv). s20_ftp_photo_sync.py читает индекс: модель = имя папки/flat-файла (любая вложенность — NESTEROV/Watches/Категория/арт; Casio добрался сам), бренд = 1-й сегмент пути (промо-папки 1000х1000/2000х2000/КРЕАТИВЫ/Ozon/Wildberries игнор), thumbnail 300px q82. preview.card.brand → s20_ref.product_preview.brand. API бренд = COALESCE(kernel, brand_catalog [каталог остатков gwptd, поле Марка], product_preview.brand [из папки]). Крон: S20 run.sh (build_dav_index→mp_sync→ftp_sync 03:30), s3 зеркала превью 05:00 + марок 05:40. Мини-фото на «Рейтинг (API)»: прокси-роут new/preview/{article} (PreviewImageController + DataApiClient::image, токен на сервере) + <img loading=lazy> 52px, источник 300px. ГРАБЛИ в vestige (тег stage2-photos): чистить src_md5 перед форс-ре-thumbnail; SQL через -f не -c "$$"; ALTER s20_ref ADD brand. Опц. осталось: photos1c thumbnails тоже 150px; мини-фото на др. страницы клона по образцу рейтинга.
  • Трек A (cutover V3) — гейт ADR-0006 копит зелёные дни (крон 14:00 s3); A3/A4 hard-blockers см. план.
  • Треки B/C — split-инфраструктура и гигиена legacy (план); раскладка по репо упрощена консолидацией.
  • Инфра-заметка (не задача): Fable 5 / Mythos 5 общесистемно приостановлены Anthropic с 2026-06-13 00:50 UTC (не связано с аккаунтом); работаем на Opus 4.8 до восстановления.

4. Свежие грабли/корни (НЕ забыть)

  • Legacy mp_stocks_daily ЗАВЫШЕН ДУБЛЯМИ (доказано 11.06): два писателя пишут один offer под разными warehouse_name → Lamoda 2× («Быково / Софьино» + «Lamoda»), YM mp6 2×, YM mp8 (FBY) — мусор (реально ~15 шт, V3 intake подтверждает). WB/Ozon сходятся с kernel (~0.2%). При сверках клон-vs-старый по остаткам YM/Lamoda расхождение 2× — НЕ баг клона.
  • UI после Codex — обязательное ревью по docs/UI-GUIDE.md (анатомия секций, человеческие лейблы, 3 состояния, чек-лист). Tailwind-классы вне собранного бандла Filament молча не работают — новые сетки только inline style.
  • gwptd-data-api контейнер: слушает 8088 ВНУТРИ; env сохранён в /root/.gwptd-data-api.env (0600, извлечён из старого контейнера). Запуск (с 2026-07-13 ОБЯЗАТЕЛЕН mount спеков — ReportExecutor читает /app/specs/reports): docker run -d --name gwptd-data-api --restart unless-stopped --network gwptd-v3-net -p 127.0.0.1:8010:8088 --env-file /root/.gwptd-data-api.env -v /opt/gwptd-analytics/repo/specs:/app/specs:ro gwptd-data-api. Деплой = git pull в repo → rsync data_api/ → docker build → rm -f + run (правки YAML-спеков подхватываются БЕЗ rebuild — рестарта хватает). Указатель отчётов: gwptd_monitoring.report_runtime_pointer (next=executor; флип/откат = один UPDATE, кэш 30с; parity-гейт: docker exec gwptd-data-api python tools/report_parity.py <code>).
  • /opt/gwptd-analytics/repo на s3 теперь чистый (reset --hard origin/master 2026-06-12; до этого был грязный rsync-наследием).
  • wb_finance_reports legacy ЖИВАЯ — питает V3 dual-write (mappings/wb/finance_reports.yaml). Свежесть мерить по rr_dt, НЕ по created_at.
  • «Финансы WB» был задуманным разделителем (e86d2ad) — теперь ссылка на /wb-finances (e33d95f).
  • После смены кадентности сбора (1×/день с 2026-06-11): freshness SLA=27ч + анти-спам (тот же состав ≤1 раза в 6ч, state /tmp/gwptd_v3_freshness_alert.state), System Status порог 26ч. При смене расписания проверять ВСЕ пороги.
  • Lamoda revenue в legacy = СМЕСЬ полей (гонка PHP-нового и python-V2-старого) → в гейте rev n/a до one-writer; kernel = partnerAgreedPrice (сверен с живым API до копейки).
  • Amazon: /var/www/html/amz = bind mount /data/AMZ (вне репо) — не трогать.
  • overrides/ ЛИКВИДИРОВАН (Stage C, edf0df3) — один источник истины.

5. Доступы/команды

  • Прод: Basic Auth (см. .env.production); Filament-юзер для проверок: lizaveta@gwptd.com.
  • s3 kernel MySQL: ssh s3 "docker exec -i gwptd-v3-mysql mysql -uroot -proot ..." (gwptd_intake/kernel/monitoring, lamoda_reports, s2_ref).
  • s3 dev MySQL (клон): docker exec -i gwptd-mysql-dev mysql -uroot -pGwptdDev2026Root gwptd_dev.
  • Data API смоук: ssh s3 "curl -s -H 'Authorization: Bearer <DATA_API_TOKEN из /opt/gwptd-new-ui/.env>' 'http://127.0.0.1:8010/api/v1/...'".
  • Браузер владельца: chrome MCP, вход https://mp.hyp.ru/new (Basic Auth из .env.production).
  • V3 на s3: /opt/gwptd-analytics/repo/marketplace-collector-v3 (+scripts/run_*.sh). РЕПО ОДИН (с 2026-06-12): gwptd-collector влит сюда (data_api/, docs/data-api/), правило синхронизации канон-копии УПРАЗДНЕНО; старый репо с историей — в NEW_MP/ARCHIVE/gwptd-collector-repo-2026-06-12.

6. Документы

  • AGENTS.md — правила. docs/BIG-PLAN-2026-06-11.md — план треков A/B/C/D (трек B заменён «Параллельными системами»; трек D: D1–D6 сделаны, D7 опц.). docs/system-map/ — карта блоков, владение интерфейсами, матрица таблиц (читай при вопросах «кто пишет в таблицу X» и «чья страница Y»). vestige — живое состояние. (Перенесено из корня NEW_MP в репо 2026-06-12 — корень чист, доки версионируются и индексируются mcp-gwptd.)