Cabinet

NOTE

Статус: Live (HEAD 5e4ce54, 2026-05-06). Base BC + 4 sub-BC уже работают: profile, customer, apikeys, credentials. Остаётся развитие UI (subscription, stats, oauth) и I4b/I4c keys-features (usage counter, IP allowlist).

Этот README описывает зонтичный BC cabinet, обслуживающий пользовательский личный кабинет Tracium (/cabinet/* UI + /api/cabinet/* HTTP). Читайте, когда нужно понять, какие подсистемы кабинета есть, как они взаимодействуют и что осталось до полного roadmap’а.

Назначение

Самообслуживание customer’а: профиль организации, выпуск API-ключей, управление учётными записями поставщиков (customer credentials), будущие screens — подписка, статистика, журнал событий, OAuth-привязки.

Статус документа

  • Тип знания: current service
  • Статус реализации: 4 sub-BC в backend/internal/core/cabinet/{apikeys,credentials,customer,profile} + UI в web/landing/src/app/cabinet/*
  • Текущее место кода:
    • backend/internal/core/cabinet/apikeys — HMAC-SHA-256 token storage + reveal-once + rotate + scopes/role + admin CRUD (I4a + RBAC Phase 2)
    • backend/internal/core/cabinet/customer — Customer entity (multi-owner, archive)
    • backend/internal/core/cabinet/profile — single-table customer_profile + atomic-outbox PG repo (I1)
    • backend/internal/core/cabinet/credentials/supplier_catalog — Go-const SupplierMeta для 5 поставщиков (ETM/IEK/Systeme/DKC/Russvet)
    • Customer credential CRUD — backend/internal/core/credentials/api/http/handler.go (clientBasePath /api/v1/credentials)
    • UI — web/landing/src/app/cabinet/{profile,keys,credentials,oauth,stats,subscription,security,archived}
  • Что читать дальше: ../../20-architecture/adr/0051-public-api-auth-and-api-key-rbac.md, ../../20-architecture/adr/0041-credentials-pool-and-secrets-isolation.md, ../public-api/README.md

Область действия

Входит:

  • HTTP API под /api/cabinet/* (JWT-cookie auth через nginx auth_request).
  • Профиль customer’а (юр.лицо, контакты, налоговые реквизиты).
  • Выпуск/ротация/блокировка API-ключей с scope-системой (whoami / products:read / search:read сейчас active; orders:write / credentials:* planned).
  • CRUD customer credentials для поставщиков (5 supported: ETM/IEK/Systeme/DKC/Russvet).
  • Архивирование (soft-delete) аккаунта.

Не входит:

  • Public API (/v1/*) — отдельный edge-слой, JWT не принимает (ADR-0051). См. ../public-api/README.md.
  • Admin API (/api/v1/admin/*) — отдельный flow для платформы; admin может выпускать ключи за customer’ов, но это admin BC.
  • Биллинг и платёжный шлюз — пока не реализовано, planned.
  • OAuth-привязки (Google/Yandex/email-link) — planned, ComingSoon screen.

Публичный контракт

Вход

HTTP (cabinet, JWT-cookie):

Метод + путьПодсистема
GET /api/cabinet/profile / PATCH /api/cabinet/profile / POST /api/cabinet/profile/switch-type / POST /api/cabinet/profile/archiveprofile + customer
GET /api/cabinet/keys / POST /api/cabinet/keys / GET/PATCH/DELETE /api/cabinet/keys/{id} / POST /api/cabinet/keys/{id}/rotate / POST /api/cabinet/keys/{id}/revoke / GET /api/cabinet/scopes/catalogapikeys
GET /api/cabinet/credentials/suppliers/catalogcredentials.supplier_catalog
GET/POST /api/v1/credentials / GET/PATCH /api/v1/credentials/{id}/(secret|status)credentials (customer-scope)

Internal:

  • GET /_internal/auth/api-key/verify — nginx auth_request subrequest (используется public API path; не cabinet-side).

Выход

  • Outbox events для audit:
    • cabinet.apikey.{created,revoked,rotated,renamed,deleted}.v1
    • Profile change events.
  • Чтение customer credentials publish’ится через secret-resolver в ingestion BC (per-credential SessionManager).

Внутренняя архитектура

Каждый sub-BC — clean architecture (api/http/, app/, domain/, infra/pg/).

  • apikeys — самый сложный: HMAC pepper, 31-char trk_live_*/trk_test_* tokens, reveal-once UX, rotation (atomic single-tx), scopes/role с D9 active-vs-planned гейтом, admin-flow с created_by_admin audit field.
  • profile — debounced auto-save, optimistic concurrency через customer_version.
  • customer — owner-member graph, archive не удаляет данные.
  • credentials.supplier_catalog — Go-const SupplierMeta (5 поставщиков); add 6-го требует release backend’а.

Зависимости

  • PostgreSQL — все sub-BC.
  • nginxauth_request к auth-service (JWT-cookie validation).
  • auth-service — emit JWT after login.
  • outbox — atomic event publish.

Хранилище

ТаблицаНазначение
customerCustomer entity + version
customer_owner_memberOwner graph (multi-owner)
customer_profileSingle-table profile fields
api_keysToken storage (HMAC + scopes + role + env)
customer_credentialsCustomer-scope supplier credentials (encrypted secrets)
outbox_eventsAsync event publication

Конфигурация

Env varDefaultОписание
KEYS_HASH_PEPPER≥32 bytes, HMAC pepper для API-keys hash. Required.
JWT_SECRETHS512 secret для auth-service.
CABINET_PROFILE_AUTOSAVE_DEBOUNCE_MS400UI debounce для autosave.

Локальный запуск

make local-prod-up

UI на https://tracium.dev:4444/cabinet, API на https://api.tracium.dev:4444/api/cabinet/*.

Тестирование

  • Unit + integration: go test ./internal/core/cabinet/... + -tags=integration для PG-зависимых.
  • Frontend: cd web/landing && pnpm vitest run — vitest unit tests.
  • E2E: Playwright — web/landing/e2e/cabinet-{profile,keys,credentials}.spec.ts.
  • Live curl-verify: см. tracium_curl_live_verify memory + execution memos для каждого sub-BC.

Наблюдаемость

  • Metrics: apikey_auth_attempts_total{result}, cabinet_profile_save_total, etc.
  • Phase logs: platform/observability.StartPhase.
  • Outbox events для audit-trail.

Открытые вопросы / TODO

См. tracium_path_to_launch.md и tracium_cabinet_design_handoff.md:

  • I4b Keys — usage counter + IP allowlist + expired-tick + cross-env (~70-80 commits). Перепроектировать под ADR-0051 (auth-service / nginx-terminator, не in-process middleware).
  • I4c Keys — manual block + tier-limits + Playground (~45-50 commits).
  • Stats screen — HonestBars + per-key/per-credential time-series.
  • OAuth screen — Google/Yandex/email-link bindings.
  • Subscription/Billing — Billing BC + PSP integration.
  • Security audit log — events_log read-side из outbox.
  • Overview KPI — сейчас минимальный screen с email/userid.
  • Credentials health columns + test-connection — backend customer-DTO extension + UI.

Связанные документы