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 через nginxauth_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/archive | profile + 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/catalog | apikeys |
GET /api/cabinet/credentials/suppliers/catalog | credentials.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— nginxauth_requestsubrequest (используется 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_adminaudit 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.
- nginx —
auth_requestк auth-service (JWT-cookie validation). - auth-service — emit JWT after login.
- outbox — atomic event publish.
Хранилище
| Таблица | Назначение |
|---|---|
customer | Customer entity + version |
customer_owner_member | Owner graph (multi-owner) |
customer_profile | Single-table profile fields |
api_keys | Token storage (HMAC + scopes + role + env) |
customer_credentials | Customer-scope supplier credentials (encrypted secrets) |
outbox_events | Async event publication |
Конфигурация
| Env var | Default | Описание |
|---|---|---|
KEYS_HASH_PEPPER | — | ≥32 bytes, HMAC pepper для API-keys hash. Required. |
JWT_SECRET | — | HS512 secret для auth-service. |
CABINET_PROFILE_AUTOSAVE_DEBOUNCE_MS | 400 | UI debounce для autosave. |
Локальный запуск
make local-prod-upUI на 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_verifymemory + 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.
Связанные документы
- ADR:
0051,0041. - Public API:
../public-api/README.md. - Ingestion (потребитель customer credentials):
../ingestion/README.md. - Design handoff:
docs/handoff/2026-05-04/cabinet/.