Текущее состояние проекта Qadam
Обновлён 14 апр. 2026 г., 17:16 · 0 комментариев
Текущее состояние проекта Qadam
Паспорт документа
- Статус документа: living document
- Актуально на: 2 апреля 2026 года
- Владелец: backend/platform-команда
- Пересмотр: при изменении production runtime, доменов, сервисов или deploy-контура
- Область применения: фактическое состояние production, инфраструктуры и активных репозиториев
- Связанные документы:
1. Краткий вывод
Qadam уже находится не в стадии заготовки, а в стадии управляемого MVP-каркаса с живым production, закрытым security-hardening пакетом, работающим OpenAPI-контуром и физически выделенными рабочими репозиториями qadam-core и qadam-web.
Главный технический разрыв проекта сейчас не в отсутствии фич, а в двух местах:
- buyer/seller/admin потоки ещё не доведены до полностью предсказуемого UX;
- production уже переведён на
qadam-coreиqadam-web, а delivery-контур вошёл в смешанную фазу: API уже работает через image-based container runtime, ноqadam-webиqadam-roadmapещё остаются на host-sidesystemd.
Дополнительно важно: текущая машина больше не должна восприниматься как единственный stage-контур для UI-проверок. Согласованный frontend/backend release теперь рассматривается через отдельный stage-сервер, который забирает main внешним автоматическим deploy-процессом.
2. Что уже работает
Инфраструктура и домены
- Публичный продукт доступен на
https://qadam.2fab.app. - Портал документации доступен на
https://qadam-roadmap.2fab.app. - Для обоих доменов выпущены сертификаты Let's Encrypt.
- На сервере настроены
systemd-сервисыqadam-api,qadam-api-container,qadam-webиqadam-roadmap. - На сервере дополнительно настроен
systemd-сервисqadam-core-runnerдля Gitea Actions. - На сервере дополнительно настроены
qadam-monitor.serviceиqadam-monitor.timerдля внешнего uptime/TLS monitoring. - На сервере дополнительно настроены
qadam-backup.serviceиqadam-backup.timerдля автоматического backup baseline и off-host retention. qadam-core-runnerбольше не хранит тяжёлый cache/workspace на корневом разделе: runner cache и hostexecutor workspace перенесены в/tmp, чтобы CI не конкурировал с production runtime за root disk.- На сервере установлен Docker Engine; его
data-rootвынесен на отдельный диск/mnt/qadam100gb/docker, чтобы image build и container smoke не конкурировали с host runtime за корневой раздел. - Внешний трафик обслуживает host-level
nginx. - Локально на хосте установлены PostgreSQL 17 и Redis.
- Публичный
/api/*трафикqadam.2fab.appтеперь идёт через nginx upstreamqadam_api_backendна127.0.0.1:5002, где работаетqadam-api-container.service. - Legacy
qadam-api.serviceбольше не обслуживает production-трафик и сохранён как rollback-контур на127.0.0.1:5001.
Репозитории и архитектура
- Текущий production runtime на сервере живёт в
/data/qadam-coreи/data/qadam-web. - Отдельный backend/bootstrap-репозиторий создан и запушен в Gitea:
https://git.2fab.app/eldar/qadam-core.git
- Отдельный frontend/bootstrap-репозиторий создан и запушен в Gitea:
https://git.2fab.app/eldar/qadam-web.git
- Старый checkout
/data/uzbekостаётся на сервере только как legacy-копия и больше не является production source of truth. qadam-coreсодержитapps/api,packages/prisma,packages/shared,docs,specs.qadam-webсодержитapps/web, отдельный сервис документацииapps/roadmap, локальный OpenAPI artifactopenapi/openapi.json, свой build-конфиг и отдельный frontend handoff-документ.- Отдельная памятка для frontend-команды зафиксирована в
docs/frontend/frontend-handoff.md; вqadam-web/docs/frontend-handoff.mdлежит её короткая локальная версия для repo onboarding. qadam-webтеперь рассматривается как отдельный рабочий контур для внешней frontend-команды, аqadam-core— как источник истины по API, документации и платформенной логике.- локальная разработка и change packages готовятся здесь, но stage-проверочный контур живёт отдельно и должен обновляться через merge в
main, а не как ручной обязательный deploy с этой машины. - Product frontend больше не несёт roadmap-портал внутри
apps/web; портал вынесен в отдельный standalone-сервисapps/roadmap. - Основной web runtime уже живёт в
apps/web/src/appи FSD-подобных слояхsrc/shared,src/entities,src/features,src/widgets,src/views. - Backend публикует Swagger UI на
/api/docsи OpenAPI JSON на/api/openapi.json. qadam-webуже умеет генерировать frontend contract types из собственногоopenapi/openapi.json, а не из backend-исходников.qadam-coreиqadam-webуже являются каноническими рабочими репозиториями и реальным production runtime.- В
qadam-coreтеперь работает repo-side Gitea Actions workflowQuality Gateна self-hosted runnerqadam-core-runner-01. - Self-hosted runner
qadam-core-runner-01теперь используетXDG_CACHE_HOME=/tmp/act_runner-cacheиTMPDIR=/tmp/act_runner-tmp, поэтому Prisma engines и act workspace не забивают/. qadam-core-runner-01теперь дополнительно входит в группуdocker, поэтому repo-side workflow может собирать API image и прогонять container smoke без ручного root-вмешательства.qadam-core-runner-01уже имеет registry-auth кgit.2fab.app, поэтому repo-side workflow может не только собрать API image, но и публиковать versioned tags в Gitea Container Registry.- Data layer централизован в
@repo/prisma: schema, migrations, generated client, seed и select helpers лежат в одном пакете. - Observability-контур уже использует Pino, optional Axiom transport и append-only
EventLogдля продуктовых событий. - Исторические implementation plans из
plans/проаудированы и формально переведены в архивный, а не канонический слой документации. - Документационный контур усилен отдельными runbook по backup/restore, incident response, environment matrix, post-deploy checklist, ownership model и change-package process.
- У проекта теперь есть отдельные execution checkpoints и project change log как operational delivery-слой поверх roadmap.
Реализованные прикладные области
- Авторизация: legacy
register/login/me/logout/refresh, плюс новый registration flowcheck-availability,register/buyer,register/seller, password reset иadd-buyer-role. - Каталог: публичная выдача, карточка айтема, получение отзывов, subjects, locations.
- Публичный каталог во frontend уже работает через searchParams-based filter context, SSR-prefetch и infinite scroll без старого
"Загрузить ещё"-паттерна. - Seller area: профиль с duplicate-safe contact updates, адреса, Telegram verify/unbind, айтемы, лиды, сотрудники, onboarding.
- Buyer area: профиль, дети, интересы, лиды, отзывы и multi-role buyer profile flow.
- Admin area: лиды, статистика, модерация, reference data и seller account status management.
- Tracking: базовая отправка событий.
- Аналитика и observability: структурные JSON-логи, EventLog и базовый tracking endpoint.
- Monitoring runtime: публичные
health/live/readyprobes и loopback-only Prometheus-compatible/metrics. - Alert delivery baseline: operational Telegram-канал уже подключён через
TELEGRAM_BOT_TOKENиTELEGRAM_ALERT_CHAT_ID. - External monitoring baseline:
qadam-monitorпроверяет product web, API readiness, roadmap web и TLS по обоим доменам, а изменения статуса отправляет в Telegram-канал. - Backup baseline:
qadam-backupежедневно снимает PostgreSQL dump, API/roadmap storage snapshot, runtime config, локально верифицирует артефакты и выгружает off-host archive в S3-compatible storage. - Docker migration baseline: для
qadam-core/apiуже подтверждён первый container smoke черезapps/api/Dockerfileиdeploy/compose/docker-compose.api-runtime.yml; контейнер проходитmigrateи отвечает200на/api/v1/health. - Для
qadam-core/apiтеперь есть канонический image build scriptdeploy/scripts/build-api-image.shи compose-based shadow smokedeploy/scripts/smoke-api-runtime-compose.sh, который поднимает container runtime на127.0.0.1:5002поверх production env без остановки host-levelqadam-api. - Для
qadam-core/apiуже подтверждён Gitea Container Registry namespacegit.2fab.app/eldar/qadam-core-api: image можно не только собрать локально, но и опубликовать и затем поднять через registry-tag в shadow smoke. - Для
qadam-core/apiуже подготовлен и применён reversible cutover path: host nginx использует named upstreamqadam_api_backend, production API переведён наqadam-api-container.service, а rollback обратно наqadam-api.serviceстандартизирован отдельным скриптом. - Для
qadam-webуже добавлен product web runtime image baseline: лёгкийDockerfileсобирает image из.next/standalone, registry namespacegit.2fab.app/eldar/qadam-web-appподтверждён publish/pull smoke, а shadow runtime успешно поднимается на127.0.0.1:3002от registry image без локальногоnext buildна production-сервере. - Repo-side quality gate
qadam-coreтеперь дополнен отдельнымAPI Container Smoke: он поднимает временные PostgreSQL и Redis контейнеры, запускает migrations внутри API image и проверяетhealth/readyиmetricsбез подключения к production БД. - Uploads: product media теперь уходят через S3-compatible storage в
DigitalOcean Spaces; backend возвращает готовый публичный URL, а локальный/uploads/images/...остаётся только как compatibility/fallback-контур для local driver. - Public seller profile backend теперь публикует санитизированный публичный контракт и explicit
seoblock (canonicalUrl,openGraph,jsonLd) для SSR/metadata слоя; непубличный seller должен отвечать404. - Минимальный stage-oriented web smoke baseline уже не только добавлен в
qadam-web, но и подтверждён живым прогоном на stage:10из10проверок (runtime health, public pages, public item, public seller profile, buyer/seller/admin dashboards) прошли успешно. - Внутренний портал roadmap/docs: просмотр markdown из
docs/, upload, delete, комментарии.
3. Что реализовано частично
Buyer-поток
- Backend buyer profile flow уже переведён на account-centric контракт:
POST/PATCH /me/profile,GET/POST/PATCH/DELETE /me/children,PATCH /me/interests. - Multi-role сценарий теперь поддержан на API-уровне через
POST /auth/add-buyer-role. - Review flow на backend теперь тоже перестал быть "автопубликацией": новые отзывы создаются в
PENDING, а buyer cabinet получаетstatusиmoderationNoteчерезGET /me/reviews. - На web-слое всё ещё почти нет полноценных smoke/e2e-проверок buyer-потока.
Seller-поток
- Backend seller onboarding и профиль уже расширены:
POST /auth/register/seller,PATCH /seller/profile, address CRUD,POST /seller/telegram/verify,DELETE /seller/telegram. - Item lifecycle на backend теперь идёт через явный
DRAFT -> PENDING -> ACTIVE/REJECTED: seller создаёт/редактирует айтем вdraft, явно отправляет его на модерацию, может отозвать pending-айтем обратно вdraft, а seller item responses получаютlatestModerationRecordс последней причиной/комментарием модерации. - Для seller review surface backend уже публикует
GET /seller/reviews,PATCH /seller/reviews/:id/reply,POST /seller/reviews/:id/complaint: продавец видит статус отзыва, может ответить на опубликованный отзыв в пределах 48 часов и может отправить спорный отзыв на повторную модерацию через complaint-driven переход вPENDING_MODERATION. - Для seller notifications backend теперь публикует
GET/PATCH /seller/notification-settings, автоматически создаёт дефолтные notification settings для исторических seller-аккаунтов и при новом лиде сначала пытается Telegram-доставку, а затем при необходимости переходит на SMTP-capable email fallback. - Seller Telegram onboarding на backend больше не сводится к ручному вводу кода без потока выдачи: seller получает
GET /seller/telegram/connect-link, бот принимаетPOST /api/v1/internal/telegram/webhook, выдаёт одноразовый 6-значный код иPOST /seller/telegram/verifyтеперь жёстче обрабатываетALREADY_VERIFIED,CODE_INVALID/CODE_EXPIREDиTELEGRAM_ALREADY_BOUND. - В seller notification settings
sellerEmailтеперь резолвится из seller profile email с fallback на account email, чтобы email fallback не зависел только от auth-слоя. notifyStatusChangeTelegramбольше не является пустым флагом: owner-facing status-change уведомления уже работают, когда статус лида меняет активныйSELLER_STAFF, а список отслеживаемых статусов задаётся черезSELLER_STATUS_CHANGE_NOTIFY_STATUSESи по умолчанию включаетCONTACTED,ENROLLED,REJECTED.- CRUD по лидам и сотрудникам реализован, но seller UX и smoke/e2e-контур по-прежнему требуют продуктовой доводки.
- Не все продуктовые правила доведены до финального UX и admin-governance слоя.
Admin-поток
- Страницы и API есть; item moderation теперь принимает решения только по
PENDINGайтемам и публикует историю последних seller-visible moderation records. - Admin seller directory теперь публикуется через
GET /admin/sellersс фильтрами и item counters, поэтому status management больше не держится на ручном знанииsellerId. - Для review moderation на backend теперь есть отдельный admin surface:
GET /admin/moderation/reviews,GET /admin/moderation/reviews/:id,PATCH /admin/moderation/reviews/:id; seller complaint flow уже подаёт туда спорные отзывы какPENDING_MODERATION. - После admin status change seller-facing защищённые маршруты возвращают явные
ACCOUNT_UNDER_REVIEW / ACCOUNT_BLOCKED, а не generic token error. - Public seller profile на backend больше не должен переиспользовать приватный seller profile shape как есть: наружу уходит отдельный public contract с очищенными полями, public-only адресами и backend-generated SEO metadata.
4. Что ещё не реализовано
- SMS/phone verification.
- Frontend adoption seller Telegram onboarding flow и stage/browser smoke по нему ещё не доведены до end-to-end product UX.
- SMTP-capable email fallback для seller lead notifications уже реализован в коде, но включение конкретного provider/env на целевом runtime остаётся отдельным operational шагом.
- Owner-facing status-change notifications для seller уже включены на backend только для non-owner actor (
SELLER_STAFF); дальнейшее расширение на новые actor/source-of-change сценарии остаётся отдельным продуктовым пакетом. - Карта поиска офлайн-центров.
- Полноценный CPL billing.
- CRM-слой v1.0.
- Онлайн-платежи и транзакционная модель.
- Нормальный e2e-контур для веба.
- Image-based delivery и docker/image-based runtime.
- CDN/fronting и lifecycle policy поверх уже включённого object storage для product media; roadmap storage пока осознанно остаётся локальным.
5. Состояние инфраструктуры на текущем сервере
Сервисы
qadam-api: legacy rollback-сервис, запускается из/data/qadam-core/apps/api/dist/main.jsи держится остановленным, пока public upstream обслуживает контейнер.qadam-api-container: production runtime API из registry image на127.0.0.1:5002.qadam-web: запускает standalone-сборку product frontend Next.js на127.0.0.1:3000.qadam-web: для product frontend дополнительно существует container shadow runtime на127.0.0.1:3002, но production-трафик пока обслуживает host-levelsystemdсервис на127.0.0.1:3000.qadam-roadmap: запускает standalone-сборку сервиса документации на127.0.0.1:3001.qadam-monitor: запускает/data/qadam-core/scripts/monitor-runtime.mjsпоsystemdtimer.qadam-backup: запускает/data/qadam-core/scripts/backup-runtime.mjsпоsystemdtimer.qadam-api: после security-hardening и после cutover остаётся только rollback-сервисом на127.0.0.1:5001, а не основным public runtime.qadam-api: дополнительно публикуетGET /api/v1/health/live,GET /api/v1/health/readyи loopback-onlyGET /api/v1/metrics.nginx: проксируетqadam.2fab.appиqadam-roadmap.2fab.app.- Docker Engine использует
data-root=/mnt/qadam100gb/docker; старый/var/lib/dockerбольше не является каноническим storage для контейнерного runtime.
Важные системные файлы
/etc/systemd/system/qadam-api.service/etc/systemd/system/qadam-api-container.service/etc/systemd/system/qadam-web.service/etc/systemd/system/qadam-roadmap.service/etc/systemd/system/qadam-monitor.service/etc/systemd/system/qadam-monitor.timer/etc/systemd/system/qadam-backup.service/etc/systemd/system/qadam-backup.timer/etc/nginx/sites-available/qadam.2fab.app.conf/etc/nginx/sites-available/qadam-roadmap.2fab.app.conf/etc/nginx/conf.d/qadam-api-upstream.conf/etc/docker/daemon.json/etc/qadam/qadam.env/etc/qadam/qadam-api-runtime.env/etc/qadam/qadam-monitor.env/etc/qadam/qadam-backup.env/etc/qadam/qadam-roadmap.env
Портал документации
- Сейчас читает markdown из
/data/qadam-core/docsчерезQADAM_PROJECT_ROOT=/data/qadam-core. - Runtime портала больше не обслуживается через
qadam-web; доменqadam-roadmap.2fab.appидёт напрямую в отдельный сервисqadam-roadmap. - Внутренние относительные markdown-ссылки внутри канонической документации теперь открываются внутри roadmap-портала, включая переходы в связанные
specsиdocs/Agents. - На главной roadmap-портала теперь есть отдельный блок
Что сейчас должна сделать frontend-команда, который автоматически собирается изdocs/frontend/frontend-change-log.md. - Архивные processed plans лежат в
/data/qadam-core/plans/archived/2026-03-28-integratedи по умолчанию скрыты в библиотеке roadmap-портала; они показываются только при включённомShow archived. - Загруженные документы хранит в
/var/lib/qadam-roadmap/uploads. - Комментарии хранит в
/var/lib/qadam-roadmap/comments.json. - Ответ frontend-команды по backend-пакетам хранит в
/var/lib/qadam-roadmap/frontend-package-feedback.jsonкак operational overlay со статусамиpending / in_progress / done / ignored. - Доступ закрыт
basic auth. qadam-roadmap.2fab.appбольше не зависит от/data/uzbek/docs.
6. Качество и технический долг
Что уже в хорошем состоянии
- Production-домены и HTTPS работают стабильно.
- API и web собираются и запускаются на хосте.
- Security review от
2026-03-27закрыт по критичным и high-замечаниям. qadam-coreпроходитinstall + check-types + test + build + export:openapi.qadam-webпроходитinstall + generate:api-contract + check-types + build.apps/roadmapпроходитcheck-types + buildкак отдельный runtime внутри репозиторияqadam-web.- Repo-side Gitea workflow
Quality Gateдляqadam-coreуже подтверждён первым успешным run на self-hosted runner. - React/Next production-сборка работает на актуальном
src/app, а не на legacy-дереве. - Базовый машиночитаемый API-контракт поднят через OpenAPI/Swagger и доступен на production-домене.
- Prisma data layer оформлен как отдельный workspace-пакет с migrations, seed и generated client.
- Structured logging и product event logging уже описываются отдельными каноническими документами по observability и Prisma.
- В CI появился quality gate
pnpm check:api-contractдля проверки drift OpenAPI artifact и generated web types. - В
qadam-coreпоявилсяpnpm check:docsдля проверки паспорта документов, относительных markdown-ссылок и синхронизации сdocs/README.md. - В
qadam-webуже работают searchParams-based filters, infinite scroll каталога, SVGR icons и базовый auth-layer черезproxy.ts. - Для срезов
auth,leads,catalog,reviews,public seller profileи buyer reviews cabinet web уже использует generated OpenAPI response types вместо ручных response-интерфейсов. - Seller leads экран, reviews block и submit-review flow уже сидят на общем query/mutation слое.
- Production-фактический runtime уже переведён на
qadam-coreиqadam-web. - Roadmap-портал теперь рендерит markdown через полноценный GFM-совместимый слой, а не через упрощённый самодельный форматтер.
- В
qadam-webдобавлен минимальный stage-oriented smoke baselinepnpm smoke:web:flows, который проверяет runtime health, публичные страницы и buyer/seller/admin dashboard flows через реальный login.
Что требует ближайшей доработки
- Buyer profile flow всё ещё не доведён до законченного продуктового сценария.
- Полноценного regression/e2e-контура во frontend всё ещё нет: сейчас есть только минимальный stage-oriented smoke baseline без browser-level пользовательских интеракций.
- Generated contract layer на backend уже полностью покрывает admin API; во frontend нужно дожать именно adoption и cleanup остаточного legacy API-layer.
- В
qadam-webостаются исторические дублирующиеся слоиcomponents,lib,src/components,src/lib, которые нужно целенаправленно убрать. - В
qadam-webещё остались прямыеfetch-пути и конкурирующие API-слои, особенно в admin/reference-срезах. - Frontend auth/register UI ещё не синхронизирован до конца с новым registration API и buyer profile flow из
qadam-core. - Репозиторий
qadam-webтеперь содержит два приложения с разной зоной ответственности:apps/webдля продуктового frontend иapps/roadmapдля внутреннего сервиса документации. Это нужно учитывать в CI и handoff. - На сервере всё ещё лежит legacy checkout
/data/uzbek, и его нужно не использовать как рабочую площадку новой разработки. - Image-based release для новых репозиториев ещё не доведён до полного рабочего контура.
- Для
qadam-core/apiуже есть рабочий image/container runtime с живым production cutover, а дляqadam-webуже подтверждён registry-backed shadow runtime; при этом product web иqadam-roadmapпока всё ещё обслуживают production через host-basedsystemd. - Нужен более зрелый analytics backlog поверх уже существующего
EventLogи observability-контура.
7. Каноническая модель деплоя
На сегодня канонический production-сценарий для этого сервера такой:
- Обновление
qadam-coreиqadam-web. - Проверка
qadam-core, экспорт OpenAPI и применение Prisma migrations. - Для API: сборка/publish image, обновление
QADAM_API_IMAGEв/etc/qadam/qadam-api-runtime.envи cutover черезqadam-api-container.service. - Для product web и roadmap: пока ещё сборка
qadam-web/apps/webиqadam-web/apps/roadmapс боевыми env и запуск черезsystemd. - Reverse proxy через host-level
nginx, где/api/*уже идёт через upstreamqadam_api_backend, а/*иqadam-roadmapпока остаются на host-level сервисах. - TLS через Let’s Encrypt и
certbot.
Важно: runtime уже переведён на split-репозитории, а production-контур стал смешанным: API уже работает через image-based container runtime, qadam-web уже имеет подтверждённый registry-backed shadow runtime, но полный docker/image-based delivery для product web и qadam-roadmap ещё не завершён.
Отдельно от этого production runbook теперь действует release-модель для stage:
- backend и frontend доводятся до merge-ready состояния в своих репозиториях;
- после согласования обе стороны мержат изменения в
main; - отдельный stage-сервер автоматически подтягивает
mainи разворачивает UI-проверочный контур; - поэтому текущая машина не должна считаться обязательной финальной точкой для ручного frontend stage deploy.
8. Главные риски
- Риск случайной разработки в legacy checkout
/data/uzbek, который больше не должен считаться рабочим репозиторием. - Риск отсутствия web regression-защиты: фронтенд без e2e/smoke-покрытия будет ломаться незаметно.
- Риск ложного ощущения "MVP уже готов": функциональность есть, но не все критичные потоки доведены до предсказуемого UX.
- Риск конфигурационного дрейфа между уже контейнеризированным
apiи всё ещё host-based runtime дляqadam-web/qadam-roadmap.