# sched-pipelines — локальный стенд sched daemon + 2 HTTP-воркера (Yandex Market, Ozon Seller) + CDP-browser + локальный ntfy + alert-bridge. ## Расписание (sched daemon) | Задача | Cron | URL | |---|---|---| | `ozon-seller-pipeline` | `0 2 * * *` (02:00) | http://ozon-seller-builder:8080/run | | `yandex-market-pipeline` | `30 2 * * *` (02:30) | http://ym-client-builder:8080/run | Воркеры в **DRY-RUN**: реальные npm publish / GitHub push не выполняются (озон — `DRY_RUN=1` + publish-стадии нет на sched-пути; яндекс — stages без publish/githubDistro). После отмашки оператора — снять DRY_RUN и добавить стадии. ## Состав | Сервис | Порт на хосте | Заметки | |---|---|---| | `schedd` | 127.0.0.1:18080 | admin API, ключ `SCHED_ADMIN_KEY` | | `ym-client-builder` | 127.0.0.1:18090 | воркер Yandex (envelope-контракт ✅) | | `ozon-seller-builder` | 127.0.0.1:18091 | воркер Ozon (sched-путь без publish/notify — ТЗ отправлено) | | `browser` | — | Chrome headless + CDP :9222 (антибот-стадии ozon) | | `ntfy` | 127.0.0.1:8096 | локальный ntfy на период локального теста | | `alert-bridge` | 127.0.0.1:19090 | sched webhook → ntfy + email (unisender go2) | ## Секреты - `.env` — gitignored; источник правды — `pass sched-pipelines/local/*`: `sched-api-key`, `admin-key`, `webhook-secret`, `unisender-go-api-key`. - `SCHED_API_KEY` — общий токен sched→воркеры (x-sched-api-key). Сгенерирован, в pass. - `WEBHOOK_SECRET` — HMAC-подпись sched-алертов (X-Sched-Signature-256). ## Команды ```bash # рендер tasks.generated.json из tasks.json + .env (после смены секретов/расписания) node render-tasks.cjs # сборка + запуск docker compose up -d --build # логи docker compose logs -f schedd # health sched curl -H "Authorization: Bearer $(pass show sched-pipelines/local/admin-key)" http://127.0.0.1:18080/api/health # ручной триггер (dry-run безопасен: воркеры в DRY-RUN) # через sched admin API: POST /api/tasks/:name/run — см. sched docs 09.admin-api.md ``` ## Миграция на VDS 1. Запушить образы в registry.kzntsv.site, compose → Portainer-стек. 2. Сеть: `proxy` (traefik), ntfy → `https://ntfy.vds.kzntsv.site` (+ auth-топик), порты → traefik-правила. 3. Секреты → stack.env на Portainer (или pass, как принято). 4. `CRON_SCHEDULE` ozon остаётся выключенным (рулит sched). 5. Проверить IP-доступность: VDS IP для docs.ozon.ru / антибот — не заблокировать. ## Известные дыры (ТЗ отправлены командам apilki) - **ozon**: sched-путь не отдаёт sched-envelope (всегда 200 + `{runId, verdict}`) → sched видит «succeeded» на фейле; нет notify на sched-пути; нет publish-стадии на sched-пути (publish только в внутреннем кроне, который тут выключен). - **yandex**: email-эндпоинт unisender `go2.unisender.ru/api/v1/sendEmail` → 404; правильный — `go2.unisender.ru/ru/transactional/api/v1/email/send.json` (JSON body). - **ozon**: email-эндпоинт `go.unisender.ru/...` (старый домен) + массив `to` → go2 + одиночный получатель. - **unisender go2**: аккаунт требует настроенный backend/tracking domain («Custom backend domain or tracking domain required») — конфигурация в аккаунте go2.unisender.ru (руками оператора).