Qadam Roadmap
проектdocs/project/execution-checkpoints.md

Execution checkpoints проекта

Обновлён 14 апр. 2026 г., 17:16 · 0 комментариев

Execution checkpoints проекта

Паспорт документа

  • Статус документа: living document
  • Актуально на: 2 апреля 2026 года
  • Владелец: backend/platform-команда
  • Пересмотр: при изменении статуса этапов, завершении change package или пересборке delivery-плана
  • Область применения: операционный контроль поэтапной реализации проекта с фиксацией факта исполнения
  • Связанные документы:

Цель документа

Roadmap отвечает на вопрос “куда идём”. Этот документ отвечает на вопрос “что уже закрыто по факту, что в работе и что ещё не начато”.

Каждый checkpoint должен обновляться только по факту исполнения, а не по обещанию.

Этот документ в детальном виде покрывает активные и ближайшие execution-пакеты фаз A и B, а также delivery maturity. Фазы C, D и E из roadmap пока остаются стратегическими и не дробятся на checkpoint'ы до закрытия MVP hardening, чтобы не создавать ложную детализацию.

Статусы

  • [x] completed — выполнено и подтверждено кодом, runtime или документально
  • [~] in progress — активная работа идёт, но exit criteria ещё не закрыты
  • [ ] planned — запланировано, но не начато
  • [!] blocked — работа упёрлась во внешний или внутренний blocker

1. Foundation и transferability

CP-001 — Split-репозитории и production cutover

CP-002 — Roadmap вынесен в отдельный сервис

CP-003 — Канонический docs-layer и стандарт документации

CP-004 — Ops/governance baseline для handover

  • Статус: [x] completed
  • Суть: закрыты базовые runbook и governance-пробелы по эксплуатации, ownership и change package
  • Факт исполнения:
    • добавлены backup/restore, incident response, environment matrix, post-deploy checklist
    • зафиксированы ownership model и change package standard
  • Доказательства:

CP-005 — Docs quality gate

  • Статус: [x] completed
  • Суть: у документационного слоя есть исполнимая машинная проверка
  • Факт исполнения:
    • в qadam-core существует команда pnpm check:docs
    • она проверяет паспорт документа и относительные markdown-ссылки
  • Доказательства:
    • package.json и scripts/check-docs.mjs в qadam-core

CP-006 — Backend test и quality gate stabilization

  • Статус: [x] completed
  • Суть: довести backend test contour и merge gates до предсказуемо зелёного состояния после auth/registration/openapi drift
  • Факт исполнения:
    • pnpm -C /data/qadam-core test проходит штатно
    • контрактно-чувствительные spec'и jwt-auth.guard и OpenAPI schemas синхронизированы с текущей реализацией
    • backend change packages больше не стартуют из состояния с красным test gate
  • Exit criteria:
    • pnpm -C /data/qadam-core test проходит штатно
    • контрактно-чувствительные spec'и auth/profile/guards синхронизированы с текущей реализацией
    • backend change packages закрываются без ручных оговорок по test gate
  • Доказательства:

CP-007 — Repo-side CI gate и PR review discipline

  • Статус: [x] completed
  • Суть: перевести quality gate из только локального процесса в обязательный репозиторный workflow и зафиксировать PR review/security gate как формальный контур
  • Факт исполнения:
    • в qadam-core добавлен .gitea/workflows/quality-gate.yml
    • в qadam-core добавлен .gitea/PULL_REQUEST_TEMPLATE.md
    • governance и CI rules синхронизированы с обязательным repo-side quality gate и security review checklist
    • на сервере поднят act_runner как systemd-сервис qadam-core-runner
    • repo runner qadam-core-runner-01 зарегистрирован в Gitea и находится в статусе online
    • первый workflow run Quality Gate для qadam-core завершился в Gitea со статусом success
  • Exit criteria:
    • существует обязательный workflow, который гоняет check-types, test, build, export:openapi и check:docs
    • первый успешный run этого workflow подтверждён в Gitea
    • PR review/security checklist используется как обязательный слой для нетривиальных change packages
  • Доказательства:

2. Contract и API foundation

CP-101 — OpenAPI и contract workflow

  • Статус: [x] completed
  • Суть: backend публикует OpenAPI и Swagger, frontend может синхронизировать generated types
  • Факт исполнения:
    • живой OpenAPI на https://qadam.2fab.app/api/openapi.json
    • versioned artifact в qadam-core/apps/api/openapi/openapi.json
    • frontend handoff и frontend changelog работают как обязательный процесс
  • Доказательства:

CP-102 — Registration API и профильные контракты buyer/seller

  • Статус: [x] completed
  • Суть: backend закрывает новый registration flow и профили buyer/seller
  • Факт исполнения:
    • новые auth routes опубликованы и описаны
    • buyer/seller profile flows переведены на канонические write-contracts
  • Доказательства:

CP-103 — Frontend adoption нового registration/profile контракта

  • Статус: [~] in progress
  • Суть: отдельная frontend-команда должна довести qadam-web до нового backend-контракта
  • Текущее положение:
    • backend и OpenAPI готовы
    • handoff и frontend changelog подготовлены
    • текущие красные зоны qadam-web разложены в отдельный remediation backlog для frontend-команды
    • buyer/seller profile response schemas уже закрыты и больше не считаются blocker'ом по OpenAPI coverage
    • auth auxiliary, staff, reference, seller items и admin response schemas уже закрыты и доступны frontend-команде через OpenAPI artifact
    • активных backend-blocker'ов по OpenAPI response coverage больше нет; оставшаяся работа лежит на внедрении этого контракта во frontend
    • финальное UI-принятие зависит от внешней frontend-команды
  • Exit criteria:
    • buyer/seller registration UI не использует legacy /auth/register
    • buyer profile flow использует POST/PATCH /me/profile
    • seller profile flow использует канонический PATCH
    • profile screens не держат ручные transport-типы там, где backend уже публикует response schemas
  • Доказательства:

CP-104 — Закрытие OpenAPI response gaps для remaining core/admin endpoints

  • Статус: [x] completed
  • Суть: довести OpenAPI coverage до уровня, где web перестаёт держать ручные transport types на оставшихся buyer/seller/admin flows
  • Факт исполнения:
    • базовый OpenAPI и versioned artifact работают как единый contract layer
    • buyer/seller profile, Auth auxiliary flows, Staff, Reference data, Seller Items, Admin Dashboard и Admin Moderation публикуют response content в OpenAPI
    • pnpm -C /data/qadam-core export:openapi подтверждает, что активный frontend-значимый response-gap backlog составляет 0
    • 204 No Content delete-маршруты остаются техническим хвостом, но не считаются blocker'ом для generated contract layer
  • Exit criteria:
    • все endpoint'ы из openapi-gaps.md публикуют response content в OpenAPI там, где frontend ожидает response body
    • после pnpm export:openapi web может перегенерировать типы без ручных response-заглушек для этих flows
    • Seller Items, Admin Dashboard и Admin Moderation больше не считаются manual-contract зоной
  • Доказательства:

3. MVP hardening

CP-201 — Buyer profile flow end-to-end

  • Статус: [ ] planned
  • Exit criteria:
    • корректный UI для отсутствующего buyer profile
    • children/interests flow без legacy assumptions
    • regression checks на уровне backend и web

CP-202 — Seller item и moderation flow

  • Статус: [x] completed
  • Суть: seller item lifecycle и базовый admin moderation flow доведены до предсказуемой status-модели без скрытых переходов
  • Факт исполнения:
    • у item status-модели появился явный DRAFT, поэтому create/update больше не отправляют айтем на модерацию молча
    • seller теперь явно управляет переходом DRAFT -> PENDING через submit и может вернуть PENDING -> DRAFT через withdraw
    • seller не может редактировать айтем в статусе PENDING; backend требует сначала отозвать его с модерации
    • seller item responses публикуют latestModerationRecord, чтобы UI видел последнюю причину/комментарий модерации
    • admin approve/reject работают только для PENDING айтемов и режут повторную модерацию как статусный конфликт, а не как неявное поведение
  • Exit criteria:
    • seller item workflow предсказуем от создания до модерации
    • admin moderation не ломает seller UX
    • статусы и причины отклонения доведены до рабочего сценария
  • Доказательства:

CP-203 — Admin operational surface

  • Статус: [x] completed
  • Суть: admin operational surface доведён до реального рабочего контура вокруг seller status management и moderation
  • Факт исполнения:
    • backend публикует GET /admin/sellers с фильтрами search, status, sellerType, page, limit
    • admin seller summary теперь отдаёт displayName, contact fields, telegramConnected и item counters, поэтому status management больше не держится на ручном знании sellerId
    • PATCH /admin/sellers/:sellerId/status подтверждён runtime smoke-сценарием ACTIVE -> UNDER_REVIEW на временном seller-аккаунте
    • после admin status change seller-facing защищённые маршруты теперь возвращают явные ACCOUNT_UNDER_REVIEW / ACCOUNT_BLOCKED, а не generic Invalid or expired token
    • admin API остаётся полностью покрыт contract-layer, а GET /admin/sellers добавлен в OpenAPI и карту API
  • Exit criteria:
    • базовые admin сценарии предсказуемы
    • account status management и moderation работают end-to-end
    • admin API покрыт contract-layer и smoke checks
  • Доказательства:

CP-204 — Web smoke/e2e baseline

  • Статус: [~] in progress
  • Факт исполнения:
    • в qadam-web добавлен минимальный stage-oriented smoke baseline pnpm smoke:web:flows без отдельного browser runner
    • baseline уже проверяет runtime health, публичные страницы /, /login, /register, /forgot-password и role-based web flows buyer/seller/admin через реальный login и cookies
    • public item и public seller profile включены как stage-driven слой через env, без правок кода
    • живой stage-прогон уже подтверждён: 10 из 10 проверок (runtime health, public pages, public item, public seller profile, buyer dashboard, seller dashboard, admin dashboard) завершились успешно
  • Exit criteria:
    • есть automated smoke/e2e для ключевых buyer/seller/admin flows
    • regressions ловятся до production
  • Открытый хвост:
    • baseline ещё нужно встроить во внешний stage release-контур, чтобы он выполнялся автоматически после deploy на проверочный сервер
    • это пока smoke layer, а не полноценный browser-level e2e с пользовательскими интеракциями

CP-205 — Reviews и status model

  • Статус: [~] in progress
  • Факт исполнения:
    • в qadam-core введена backend status-модель Review: новые отзывы создаются в PENDING, исторические существующие отзывы мигрированы в PUBLISHED
    • публичный GET /catalog/items/:slug/reviews и rating/reviews aggregates в catalog/public seller profile теперь учитывают только PUBLISHED
    • buyer cabinet GET /me/reviews теперь публикует status и moderationNote, чтобы frontend не держал скрытое допущение "любой отзыв сразу опубликован"
    • backend публикует admin review moderation endpoints GET /admin/moderation/reviews, GET /admin/moderation/reviews/:id, PATCH /admin/moderation/reviews/:id
    • seller review surface доведён на backend: GET /seller/reviews, PATCH /seller/reviews/:id/reply, POST /seller/reviews/:id/complaint
    • complaint-driven moderation уже замкнута end-to-end: seller complaint переводит отзыв в PENDING_MODERATION, скрывает его из public aggregates, а admin moderation принимает финальное решение с фиксацией complaint resolution
  • Exit criteria:
    • reviews submission, moderation и public display следуют явной status-модели
    • buyer cabinet и публичные страницы показывают согласованное review-состояние без скрытых допущений
    • review API и UI покрыты contract-layer и smoke/e2e по уровню риска
  • Открытый хвост:
    • frontend-команда должна внедрить buyer/public/admin/seller review UI под новый контракт
    • review-сценарии пока не включены в автоматизированный web smoke/e2e baseline

CP-206 — Public seller profile и SEO baseline

  • Статус: [~] in progress
  • Факт исполнения:
    • public seller profile backend очищен от внутренних seller-only полей и теперь публикует отдельный public contract вместо прямого reuse приватного seller profile shape
    • GET /sellers/:id теперь отдаёт explicit seo block: title, description, canonicalUrl, openGraph, jsonLd
    • canonical/SEO URLs могут браться из PUBLIC_WEB_BASE_URL, а при его отсутствии backend выводит базовый public URL из NEXT_PUBLIC_API_URL
    • non-active seller profile режется как 404, а hidden seller addresses не включаются в публичный payload
  • Exit criteria:
    • public seller profile работает как стабильная SSR entry point
    • meta/SEO baseline описан явно и не держится на скрытых предположениях
    • public seller profile включён в smoke/e2e baseline там, где это оправдано риском
  • Открытый хвост:
    • frontend-команда должна внедрить backend-generated seo block в SSR metadata/public seller page
    • browser-level e2e для public seller profile и metadata всё ещё не закрыт, даже несмотря на успешный stage smoke baseline

4. Delivery и operations maturity

CP-301 — Image-based delivery и docker contour

  • Статус: [~] in progress
  • Факт исполнения:
    • на production-сервер установлен Docker Engine с compose plugin, но container runtime ещё не заменил канонический systemd-контур приложений
    • Docker data-root вынесен на отдельный диск /mnt/qadam100gb/docker, поэтому image build больше не конкурирует с production runtime за корневой раздел
    • в qadam-core канонизирован apps/api/Dockerfile: runtime user, dumb-init, healthcheck, отдельные helper scripts для migrations/seed и отказ от legacy entrypoint
    • в qadam-core добавлен первый канонический deployment manifest deploy/compose/docker-compose.api-runtime.yml для api, migrate и seed
    • для api добавлен канонический image build script deploy/scripts/build-api-image.sh, который собирает образ с OCI labels и результативным тегом qadam-core-api:git-<commit>
    • для api добавлен publish script deploy/scripts/publish-api-image.sh, который публикует versioned image tag в Gitea Container Registry git.2fab.app/eldar/qadam-core-api
    • для api добавлен compose-based shadow smoke deploy/scripts/smoke-api-runtime-compose.sh, который поднимает runtime-manifest на 127.0.0.1:5002 с production env и подтверждает health/ready + metrics без cutover host-level qadam-api
    • API image qadam-core-api:cp301-smoke собран на сервере, контейнерный smoke подтверждён: /app/bin/run-migrations.sh проходит, а GET http://127.0.0.1:5002/api/v1/health отвечает 200
    • registry path подтверждён по факту: git.2fab.app/eldar/qadam-core-api:registry-smoke-4805b86 успешно опубликован и может использоваться как source image для shadow smoke
    • для api добавлены source-controlled cutover/rollback-скрипты deploy/scripts/cutover-api-to-container.sh, deploy/scripts/rollback-api-to-systemd.sh и nginx upstream switcher deploy/scripts/set-api-upstream.sh
    • на сервере поднят qadam-api-container.service, а /etc/qadam/qadam-api-runtime.env зафиксировал канонический registry image tag для container runtime
    • public /api/* трафик реально переведён на qadam-api-container.service: host nginx использует qadam_api_backend -> 127.0.0.1:5002, legacy qadam-api.service остановлен и оставлен как rollback path
    • для qadam-web добавлены Dockerfile, build/publish/smoke scripts и runtime manifest deploy/compose/docker-compose.web-runtime.yml
    • registry namespace git.2fab.app/eldar/qadam-web-app подтверждён по факту: product web image опубликован, затем независимо вытянут через docker pull и поднят как shadow runtime
    • qadam-web shadow smoke уже проходит от registry image на 127.0.0.1:3002 без локального next build на production-сервере
    • backend bootstrap больше не требует writable локальный uploads path при OBJECT_STORAGE_DRIVER=s3: static /uploads и создание каталогов включаются только для local driver
    • self-hosted runner qadam-core-runner теперь имеет доступ к Docker daemon, а repo-side workflow дополнен отдельным job API Container Smoke
    • repo-side workflow дополнен job Publish API Image, который после зелёного smoke публикует versioned image tag в Gitea Container Registry на push в main
    • container smoke стал self-contained: workflow поднимает временные PostgreSQL и Redis контейнеры, прогоняет migrations внутри image и проверяет health/ready и metrics без зависимости от production БД
  • Exit criteria:
    • есть управляемый app-level image-based delivery
    • host-based deploy перестаёт быть единственным рабочим контуром
    • qadam-web и qadam-roadmap получают такой же канонический image-based runtime или documented mixed-runtime status перестаёт быть временной промежуточной фазой

CP-302 — Backup automation и off-host retention

  • Статус: [x] completed
  • Факт исполнения:
    • в qadam-core добавлен исполняемый backup runtime scripts/backup-runtime.mjs и root-команда pnpm backup:run
    • на сервере подняты qadam-backup.service и qadam-backup.timer; timer ежедневно запускает backup baseline без ручного вмешательства
    • backup-сценарий снимает pg_dump, архивы API/roadmap storage, roadmap feedback overlay и runtime config (env, systemd, nginx)
    • backup локально верифицируется через pg_restore --list и SHA256SUMS, а результат последнего прогона фиксируется в /var/lib/qadam-backup/state.json
    • off-host archive реально выгружается в S3-compatible storage по префиксу backups/runtime/<STAMP>.tar.gz
    • retention policy уже применяется автоматически: 7 дней локально и 30 дней off-host
  • Exit criteria:
    • backup перестаёт быть только ручной процедурой
    • есть off-host copy и retention policy
  • Доказательства:

CP-303 — Monitoring и alerting baseline

  • Статус: [x] completed
  • Факт исполнения:
    • backend уже публикует отдельный monitoring baseline: GET /health, GET /health/live, GET /health/ready
    • readiness probe на production реально проверяет primary PostgreSQL и Redis и отдаёт machine-readable component status с latency
    • backend публикует Prometheus-compatible GET /metrics, но сознательно режет его на 403 для не-loopback запросов и оставляет доступным только с сервера
    • в API появился базовый HTTP/runtime metrics contour на prom-client: default process metrics, http_requests_total и http_request_duration_seconds
    • для operational alerts подготовлен delivery channel: в production зафиксирован TELEGRAM_ALERT_CHAT_ID, а в qadam-core появился reusable sender pnpm telegram:alert
    • на сервере подняты qadam-monitor.service и qadam-monitor.timer: они внешне проверяют qadam.2fab.app, api/v1/health/ready, qadam-roadmap.2fab.app и TLS обоих доменов
    • runtime monitor сохраняет state в /var/lib/qadam-monitor/state.json и шлёт алерты в Telegram только на изменение статуса или recovery, без постоянного спама
  • Exit criteria:
    • есть uptime/TLS monitoring
    • есть operational visibility по API, web и roadmap runtime

CP-304 — Product media object storage

  • Статус: [x] completed
  • Факт исполнения:
    • в qadam-core реализован storage adapter local | s3 для POST /api/v1/upload/image
    • production runtime qadam-api переведён на OBJECT_STORAGE_DRIVER=s3 с S3-compatible backend DigitalOcean Spaces
    • upload contract сохранён: backend по-прежнему возвращает { url }, а frontend должен считать url opaque public URL
    • живой smoke upload подтвердил публично читаемый объект по absolute Spaces URL и успешное удаление тестового объекта после проверки
  • Exit criteria:
    • POST /api/v1/upload/image работает через storage adapter и S3-совместимый backend
    • seller logo/photo и item image больше не зависят от локального /var/lib/qadam-core/uploads
    • внешний API-контракт upload endpoint остаётся стабильным: backend по-прежнему возвращает { url }
    • S3 credentials не зашиваются в Dockerfile или образ, а поставляются только через runtime env/secrets
    • storage qadam-roadmap осознанно остаётся отдельным контуром и не мигрируется в этот пакет по умолчанию

5. Правило обновления этого документа

Этот документ обновляется:

  • после завершения change package, который реально закрыл этап;
  • после появления блокера, который переводит checkpoint в [!] blocked;
  • после rollback, если фактический статус этапа ухудшился;
  • одновременно с обновлением project-change-log.md.