Skip to content

feat(phase-17): P2 hardening (redis auth, metadata, upload, transcoder) - #80

Merged
SlavaKuntsov merged 9 commits into
mainfrom
feat/phase-17-p2
Sep 20, 2026
Merged

SlavaKuntsov merged 9 commits into
mainfrom
feat/phase-17-p2

Conversation

@SlavaKuntsov

Copy link
Copy Markdown
Owner

Closes #55
Closes #57
Closes #58
Closes #59
Closes #62

Phase 17 P2 — hardening: redis auth & port exposure, metadata consistency, structured upload errors, transcoder cleanup

Завершает открытые P2-задачи фазы 17 (P1 закрыты в PR #79).

Implemented

  • P2 infra: password protect redis and unpublish internal service ports #55 infra — Redis запускается с --requirepass (пароль обязателен в compose через :?, пробрасывается в REDIS_URL auth/gateway), порт только на loopback. Порты auth/metadata/upload/transcoder-metrics больше не публикуются (клиенты только через gateway; Prometheus скрейпит по внутренней сети). postgres/pgbouncer/rabbitmq/prometheus/grafana/loki переведены на loopback-only. Дефолтные креды minioadmin/admin:admin запрещены в compose (:?) и заменены на change-me в .env.example. e2e-скрипт переведён на gateway (AUTH/UPLOAD/METADATA по умолчанию = GATEWAY).
  • P2 metadata: replace repo Update with single atomic UPDATE #57 metadata — PATCH видео: один атомарный UPDATE ... WHERE id=$ AND owner_id=$ RETURNING (email подзапросом в RETURNING) вместо read-check-write из 6 запросов (TOCTOU + до 3 отдельных UPDATE + повторный GetByID). COALESCE сохраняет поля, не переданные в запросе — конкурентные PATCH не теряют изменения. Лишний синхронный SELECT email в Create удалён.
  • P2 metadata: validate before insert and use sentinel errors #58 metadata — visibility валидируется до вставки (один INSERT с visibility, COALESCE($5::video_visibility,'public')); sentinel-ошибки ErrNotFound/ErrForbidden/ErrInvalidVisibility + errors.Is вместо сравнения строк err.Error(); ошибки БД → 500, а не 404 (getVideo/GetVODMapping/Update/Delete/Create).
  • P2 upload: return structured JSON errors without err.Error() interpolation #59 upload — общий writeJSON/writeError через pkg/httputil (как в metadata): ни одного err.Error() в теле ответа, детали инфры только в лог; исправлен ошибочный Content-Type: text/plain от http.Error.
  • P2 transcoder: unify ffmpeg argv builder and drop dead celery stubs #62 transcoder — единый build_ffmpeg_argv() вместо двух разъехавшихся копий (~60% дублей, pipe игнорировал ENCODE_MODE=crf); pipe-режим удалён (качал файл для probe/audio и добавлял сетевое чтение на каждую рендишну); Celery-стабы (celery_app.py, tasks.py) и мёртвые зависимости (celery, redis, boto3, pydantic) удалены; необслуживаемые fan-out очереди удалены из топологии; MagicMock-проверка вынесена из рантайма. Доки (spec, services-pipeline, README, AGENTS/CLAUDE) синхронизированы.

Acceptance criteria

Verification

  • make lint-go — 0 issues (pkg, metadata, gateway, upload)
  • make test-go — все пакеты ok
  • make lint-py (black/flake8/mypy) — чисто; make test-py — 22 + 31 passed
  • make lint-front — no ESLint warnings or errors; make fmt-go/fmt-py — без изменений
  • bash scripts/e2e.sh через gateway — PASS на финальном HEAD (register/login → upload → presign → transcode → HLS → private HLS → resumable 308→200)
  • docker compose config (база + prod override) — валидно

Remaining risks

  • Не-uuid id в GET/PATCH metadata теперь 500 вместо 404 — прямое следствие «ошибки БД → 500»; клиенты (gateway/frontend/e2e) не-uuid не шлют.
  • Дефолтные креды Postgres/RabbitMQ (flowix:flowix) сохранены (issue называет только MinIO/Grafana; порты теперь loopback-only).
  • WARN в e2e: private HLS отвечает 200 до истечения 10s-кеша HLSAuth — предсуществующее поведение кеша, не из этой фазы.

@SlavaKuntsov SlavaKuntsov self-assigned this Sep 20, 2026
@SlavaKuntsov
SlavaKuntsov merged commit 2a75061 into main Sep 20, 2026
4 checks passed
@SlavaKuntsov
SlavaKuntsov deleted the feat/phase-17-p2 branch September 20, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment