Appearance
Plane Epic: Navigation & Tenancy UX (Variant C)
Для AI-агентов. Подробное описание полного передела навигации, привязки Syrve-экранов к подключению и документации. Использовать при создании/импорте Plane issues и при выполнении итераций.
Epic import key: MHPAY-NAV-000
Epic Plane issue: MHPAY-109
Cycle: MHPAY-C1 (Platform Foundation) + MHPAY-C4 (UX)
Status: Imported in Plane (2026-07-06)
Updated: 2026-07-06
Связанные документы:
- scoped-rbac-and-tenancy.md — текущая модель Platform → Organization → Outlet
- syrve-payment-orchestration.md —
SyrveConnectionRMS/CHAIN scope - plane-task-template.md — обязательный шаблон handoff
- architecture-decisions-plane-backlog-v1.md — общий backlog
Проблема (контекст для агента)
Сейчас sidebar в frontend/src/components/layout/AppLayout.tsx смешивает три разных уровня в одной плоской группе «Syrve»:
- connection-level: Подключения, Статус sync, Счета и ДДС;
- organization-level: Настройки (квоты, пользователи орг.);
- platform-level: Банковские адаптеры, Пользователи платформы, Workers.
Маршруты /syrve/document-sync-runs и /syrve/references глобальные — бэкенд подставляет default connection для текущего org/outlet (GetDefaultConnectionAsync), без явного connectionId в URL и без active connection context.
RBAC при этом корректен на уровне Platform / Organization / Outlet (UserRoleAssignment без ConnectionId). Проблема — information architecture (IA) и неявная привязка Syrve read-путей к default connection.
Целевая иерархия (Variant C — принято для epic)
text
Platform (MegaAdmin / MegaManager)
├── Пользователи платформы → /platform/users
├── Workers → /admin/workers
├── Банковские адаптеры (каталог) → /settings/bank-adapters
└── Глобальные настройки платформы → (future / platform settings)
Organization (OrganizationAdmin + active org context)
├── Настройки организации → /settings (квоты, org users/roles)
└── Подключения Syrve (список) → /syrve/connections
└── [выбранное подключение :connectionId]
├── Обзор / health / credentials → /syrve/connections/:id
├── Статус sync → /syrve/connections/:id/sync-runs
└── Счета и ДДС → /syrve/connections/:id/references
Outlet / Location (Accountant + active outlet context)
├── Операции: выписки, matching, allocations, audit
├── Сверка Syrve: накладные, очередь проведений, аномалии
└── (данные Syrve фильтруются через active/default connection для org/outlet)Не переносить под connection: банковские выписки, сопоставления, распределения — они outlet-scoped, не connection-scoped.
Не вводить в Variant C: ConnectionId в UserRoleAssignment (отдельный future epic).
Состав Variant C — 7 задач
| # | Import key | Plane issue | Название (RU) |
|---|---|---|---|
| Epic | MHPAY-NAV-000 | MHPAY-109 | [Epic] Навигация, tenancy и иерархия подключений (вариант C) |
| 1 | MHPAY-ADR-007 | MHPAY-110 | ADR: информационная архитектура навигации и tenancy |
| 2 | MHPAY-NAV-001 | MHPAY-111 | Sidebar: Платформа / Организация / Syrve / Операции |
| 3 | MHPAY-NAV-002 | MHPAY-112 | Вложенные маршруты подключения и редиректы |
| 4 | MHPAY-API-003 | MHPAY-113 | Явный connectionId в Syrve read API |
| 5 | MHPAY-RBAC-006 | MHPAY-114 | Активный контекст Syrve-подключения (расширение MHPAY-53) |
| 6 | MHPAY-FE-003 | MHPAY-115 | Playwright: иерархия навигации и scope подключения |
| 7 | MHPAY-DOC-002 | MHPAY-116 | Синхронизация продуктовой и security-документации |
Рекомендуемый порядок выполнения агентом: ADR-007 → NAV-001 → (NAV-002 ∥ API-003) → RBAC-006 → FE-003 → DOC-002.
Связь с существующим backlog: расширить MHPAY-53 (MHPAY-RBAC-004), не дублировать MHPAY-50..52.
MHPAY-ADR-007 — ADR: Navigation & Tenancy Information Architecture
Meta
| Field | Value |
|---|---|
| Import key | MHPAY-ADR-007 |
| State | Backlog |
| Priority | high |
| Labels | adr, navigation, rbac, syrve, ai-agent, docs |
| Modules | AI Agents & Process, Frontend Operator Workspace |
Context
Операторы и megaadmin видят platform/org/connection пункты в одной куче. Нужен формальный ADR, чтобы последующие NAV/API задачи не переоткрывали scope.
Goal
Принятый ADR с диаграммой IA, правилами маршрутов, redirect policy и явным out-of-scope для connection-scoped RBAC.
Scope / What To Do
- [ ] Создать
docs/docs/architecture/adr/navigation-tenancy-information-architecture-v1.md - [ ] Зафиксировать: sidebar sections, nested connection routes, redirect table (old → new)
- [ ] Зафиксировать: active context stack = org + outlet + optional connection
- [ ] Зафиксировать: какие экраны остаются outlet-level vs connection-level
- [ ] Ссылка из
scoped-rbac-and-tenancy.mdиarchitecture-decisions-plane-backlog-v1.md
Out of Scope
- Реализация UI/API (только ADR)
- Connection-scoped role assignments
- Redis session persistence для context
Acceptance Criteria
- [ ] ADR содержит redirect matrix для всех затронутых путей
- [ ] ADR явно запрещает смешивать platform admin в группу Syrve
- [ ]
current-implementation-state.mdобновлён
AI Agent Instructions
text
- Docs-only итерация. Не менять runtime код.
- Прочитать AppLayout.tsx, router.tsx, scoped-rbac-and-tenancy.md, syrve-payment-orchestration.md.
- Использовать целевую иерархию из этого epic-документа как baseline.
- UUID/JSON/EF policies не затрагиваются.Targeted Repo Inspection
text
frontend/src/components/layout/AppLayout.tsx
frontend/src/routes/router.tsx
frontend/src/shared/permissions.ts
frontend/src/shared/activeContext.ts
backend/src/MyHoreca.Pay.Application/Abstractions/ScopedRbacAbstractions.cs
backend/src/MyHoreca.Pay.Infrastructure/Tenancy/ActiveContextAppService.cs
docs/docs/architecture/scoped-rbac-and-tenancy.mdPermission / RBAC Impact
None — ADR only. Документирует, что MVP RBAC scopes не меняются.
MHPAY-NAV-001 — Sidebar IA: Platform / Organization / Syrve / Operations
Meta
| Field | Value |
|---|---|
| Import key | MHPAY-NAV-001 |
| State | Backlog |
| Priority | high |
| Labels | frontend, navigation, rbac, operator-ui, ai-agent |
| Modules | Frontend Operator Workspace |
Context
navGroups в AppLayout.tsx кладёт platform admin рядом с connection ops. Accountant видит «Счета и ДДС» в sidebar, но не «Подключения» — иерархия неочевидна.
Goal
Sidebar отражает четыре логических уровня; platform admin вынесен в отдельную группу; permissions фильтрация сохранена.
Scope / What To Do
- [ ] Реструктурировать
navGroupsвAppLayout.tsx:- Операции — без изменений по составу (outlet workflow)
- Сверка / Распределение / Проведение — без изменений
- Syrve — только
Подключения(list); убрать sync/references/settings из top-level Syrve group - Организация —
Настройки(/settings) для org admin - Платформа —
Банковские адаптеры,Пользователи платформы,Workers(megaOnly)
- [ ] Добавить ключи i18n в
frontend/src/shared/i18n/(layout.nav.platform,layout.nav.organizationи т.д.) - [ ] CSS: при необходимости minor правки
global.cssдля новыхnav-group-title(без redesign) - [ ] Обновить
codegraph/manifest.yamlесли меняется структура layout routes grouping
Out of Scope
- Nested routes под
:connectionId(→ NAV-002) - Backend changes
- Active connection selector в header (→ RBAC-006)
Acceptance Criteria
- [ ] Megaadmin видит группу «Платформа» с bank adapters / platform users / workers
- [ ] OrganizationAdmin видит «Организация → Настройки», «Syrve → Подключения»
- [ ] Accountant не видит Подключения/Настройки/Platform (как сейчас по permissions)
- [ ]
npm run buildиnpm run lintпроходят - [ ] Старые URL (
/syrve/referencesи т.д.) пока работают до NAV-002
AI Agent Instructions
text
- Минимальный diff: только AppLayout + i18n + при необходимости CSS.
- Сохранить permission checks: megaOnly, canAny, hasMegaRole — не ослаблять.
- Не менять router.tsx в этой задаче.
- Прогнать rbac-syrve-navigation.spec.ts — ожидания обновить под новые group titles.Targeted Repo Inspection
text
frontend/src/components/layout/AppLayout.tsx
frontend/src/shared/i18n/translations.base.ts (+ domains при необходимости)
frontend/src/shared/permissions.ts
frontend/tests/rbac-syrve-navigation.spec.ts
frontend/src/styles/global.cssTest Plan
bash
cd frontend && npm run lint && npm run build
cd frontend && npx playwright test rbac-syrve-navigation.spec.tsAPI / Frontend Impact
Frontend routes unchanged; sidebar structure only.
MHPAY-NAV-002 — Connection-Scoped Sub-Routes & Redirects
Meta
| Field | Value |
|---|---|
| Import key | MHPAY-NAV-002 |
| State | Backlog |
| Priority | high |
| Labels | frontend, navigation, syrve, routing, ai-agent |
| Modules | Frontend Operator Workspace, Syrve Integration |
Context
Sync runs и references логически принадлежат конкретному SyrveConnection, но живут на глобальных путях.
Goal
Все connection-specific экраны доступны только под /syrve/connections/:connectionId/...; старые пути редиректят на default connection или list.
Scope / What To Do
- [ ] Добавить layout/route nest в
frontend/src/routes/router.tsx:/syrve/connections/:connectionId— detail (существующийSyrveConnectionDetailPage)/syrve/connections/:connectionId/sync-runs—SyrveDocumentSyncRunsPage/syrve/connections/:connectionId/references—SyrveReferencesPage
- [ ] Создать
SyrveConnectionLayout.tsx(или аналог) с sub-nav: Обзор | Sync | Счета и ДДС - [ ] Sub-nav виден только при
canAny([syrve.connections.view, organization.connections.manage, ...]) - [ ] Redirects:
/syrve/document-sync-runs→ resolve default connection id →/syrve/connections/{id}/sync-runsили/syrve/connections+ toast/syrve/references→ аналогично
- [ ] Обновить внутренние ссылки в wizard/pages (
CounterpartyMatchWizard,SyrveConnectionDetailPage) - [ ] Обновить
codegraph/manifest.yamlapi_surface/ frontend routes
Out of Scope
- Передача
connectionIdв API query (→ API-003; до этого страницы могут показывать default connection data) - Org settings под connection (settings остаётся
/settings)
Acceptance Criteria
- [ ] Из списка подключений переход на sync/references без глобальных sidebar links
- [ ] Старые bookmark URL редиректят без 404
- [ ] Permission guards на nested routes совпадают с текущими policies
- [ ] Playwright smoke: открыть connection → sync-runs tab
AI Agent Instructions
text
- Переиспользовать существующие page components; не дублировать таблицы.
- connectionId из useParams(); валидировать UUID format на клиенте.
- При отсутствии доступа к connection — PermissionDenied / NotFound по существующим guard паттернам.
- До API-003: страницы могут вызывать старые list endpoints (org-scoped default) — задокументировать gap в handoff.Targeted Repo Inspection
text
frontend/src/routes/router.tsx
frontend/src/pages/syrve/SyrveConnectionDetailPage.tsx
frontend/src/pages/syrve/SyrveDocumentSyncRunsPage.tsx
frontend/src/pages/syrve/SyrveReferencesPage.tsx
frontend/src/api/hooks/useSyrveApi.ts
frontend/src/pages/matching/CounterpartyMatchWizard.tsx (links)Test Plan
bash
cd frontend && npm run build
cd frontend && npx playwright test rbac-syrve-navigation.spec.ts syrve-connections-probe.spec.tsMHPAY-API-003 — Explicit connectionId in Syrve Read APIs
Meta
| Field | Value |
|---|---|
| Import key | MHPAY-API-003 |
| State | Backlog |
| Priority | high |
| Labels | backend, api, syrve, tenancy, ai-agent |
| Modules | Api, Infrastructure, Syrve Integration |
Context
GET /api/syrve/document-sync-runs, GET /api/syrve/references/* используют implicit default connection. При нескольких RMS/CHAIN в org оператор не видит, чьи данные отображаются.
Goal
Read endpoints принимают явный connectionId (route или query), проверяют org scope, возвращают данные только этого подключения.
Scope / What To Do
- [ ] Добавить endpoints (предпочтительно nested, согласовать с ADR-007):
GET /api/syrve/connections/{connectionId}/document-sync-runsGET /api/syrve/connections/{connectionId}/references/accountsGET /api/syrve/connections/{connectionId}/references/cash-flow-articles
- [ ] Scoped authorization: user must have access to connection's
OrganizationId(+LocationIdif RMS) - [ ] Старые global endpoints: deprecate → proxy to default connection or 308/redirect documented in api.md
- [ ] Обновить
docs/docs/backend/api.md - [ ] Unit tests:
ScopedRbacTests/ Syrve controller tests — cross-tenant 403, wrong connection 404
Out of Scope
- Изменение posting/write endpoints
- Connection-scoped RBAC permissions
- Redis context
Acceptance Criteria
- [ ] Запрос с чужим
connectionId→ 403 или 404 (по existing concealment policy) - [ ] Sync runs list фильтруется по
SyrveConnectionId - [ ] References читают snapshots/catalog для указанного connection
- [ ]
dotnet testпо затронутым проектам проходит
AI Agent Instructions
text
- Следовать IScopedAuthorizationService + connection org/location scope checks (см. SyrveOrchestrationControllers).
- Не дублировать GetDefaultConnectionAsync в новых endpoints — требовать explicit id.
- JSON: PayJsonSerializer, typed DTOs only.
- Обновить frontend hooks в отдельной итерации или в RBAC-006 — указать в handoff.Targeted Repo Inspection
text
backend/src/MyHoreca.Pay.Api/Controllers/SyrveOrchestrationControllers.cs
backend/src/MyHoreca.Pay.Infrastructure/Syrve/SyrveOrchestrationServices.cs
backend/src/MyHoreca.Pay.Infrastructure/Syrve/Iiko/IikoSyrveConnectionProvider.cs
backend/src/MyHoreca.Pay.Application/Abstractions/ScopedRbacAbstractions.cs
backend/tests/MyHoreca.Pay.UnitTests/ScopedRbac/TenantIsolationTests.cs
docs/docs/backend/api.mdTest Plan
bash
dotnet test backend/tests/MyHoreca.Pay.UnitTests/MyHoreca.Pay.UnitTests.csproj --filter FullyQualifiedName~Syrve
dotnet test backend/tests/MyHoreca.Pay.UnitTests/MyHoreca.Pay.UnitTests.csproj --filter FullyQualifiedName~ScopedRbacAPI / Frontend Impact
New nested endpoints; useSyrveApi.ts hooks update в RBAC-006 или в этой задаче если scope позволяет.
MHPAY-RBAC-006 — Active Syrve Connection Context (extends MHPAY-53)
Meta
| Field | Value |
|---|---|
| Import key | MHPAY-RBAC-006 |
| Parent | MHPAY-53 / MHPAY-RBAC-004 |
| State | Backlog |
| Priority | high |
| Labels | frontend, backend, rbac, syrve, context, ai-agent |
| Modules | Identity & RBAC, Frontend Operator Workspace |
Context
MHPAY-53 реализовал active org/outlet (GET/POST /api/auth/context, X-Organization-Id, X-Location-Id). Connection выбирается неявно через IsDefault.
Goal
Оператор явно выбирает активное Syrve-подключение; выбор валидируется бэкендом; UI и API используют его для connection-scoped экранов.
Scope / What To Do
Backend
- [ ] Расширить
ActiveContextDto/SetActiveContextRequestполемSyrveConnectionId?(nullable) - [ ]
ActiveContextAppService: валидация — connection belongs to org; RMS requires matching locationId - [ ] Audit entry
ActiveContextс connection id - [ ] Опционально: header
X-Syrve-Connection-IdвDependencyInjectionscope resolution - [ ] Unit tests в
ScopedRbacTests.cs
Frontend
- [ ] Расширить
ActiveContextStateвfrontend/src/shared/activeContext.ts - [ ] Connection selector в header (
AppLayout) — только если >1 доступное подключение в scope - [ ]
httpClientпередаёт header при наличии active connection - [ ]
useSyrveApihooks:connectionIdиз params или active context - [ ]
ContextSelectionPage: auto-select default connection при single-connection org
Out of Scope
- Server-side Redis persistence (future)
- Connection-level role assignments
- Изменение accountant outlet workflow routes
Acceptance Criteria
- [ ] Multi-connection org: смена connection обновляет sync/references без смены org/outlet
- [ ] Cross-org connection selection → 403
- [ ] Single connection: auto-selected, selector скрыт
- [ ] Backward compatible: clients without connection id still work via default (deprecation window)
AI Agent Instructions
text
- Расширять MHPAY-53, не создавать параллельный context store.
- Backend — source of truth; frontend localStorage только cache выбора.
- Не ломать existing auth/context contract: additive fields only.
- После изменения DTO обновить frontend api contracts + mockApi.ts для Playwright.Targeted Repo Inspection
text
backend/src/MyHoreca.Pay.Infrastructure/Tenancy/ActiveContextAppService.cs
backend/src/MyHoreca.Pay.Api/Controllers/AuthController.cs
backend/src/MyHoreca.Pay.Application/Abstractions/ScopedRbacAbstractions.cs
frontend/src/shared/activeContext.ts
frontend/src/api/httpClient.ts
frontend/src/pages/login/ContextSelectionPage.tsx
frontend/tests/helpers/mockApi.tsPermission / RBAC Impact
None new permissions — используются organization.connections.manage / platform.connections.view_all для list; read paths — existing scoped checks.
MHPAY-FE-003 — Playwright: Navigation Hierarchy & Connection Scope
Meta
| Field | Value |
|---|---|
| Import key | MHPAY-FE-003 |
| State | Backlog |
| Priority | medium |
| Labels | frontend, playwright, e2e, navigation, rbac, ai-agent |
| Modules | Frontend Operator Workspace |
Context
rbac-syrve-navigation.spec.ts проверяет flat sidebar. После NAV/RBAC нужны тесты иерархии и connection scope.
Goal
Automated regression для sidebar groups, nested connection routes, redirects, permission denials.
Scope / What To Do
- [ ] Обновить
frontend/tests/rbac-syrve-navigation.spec.ts - [ ] Добавить
frontend/tests/syrve-connection-navigation.spec.ts:- org admin: connections list → detail → sync-runs sub-nav
- accountant: no connections link; references only via operational path if applicable
- redirect
/syrve/references→ connection-scoped URL
- [ ] Обновить
mockApi.ts— connections list, nested API paths - [ ] При необходимости:
mhpay-e2e-smoke.spec.tsshallow check
Acceptance Criteria
- [ ] Все новые/обновлённые Playwright specs green locally
- [ ] Нет flaky waits — использовать
getByTestId/ role locators
AI Agent Instructions
text
- Не добавлять live Syrve dependencies — только mocks.
- Следовать existing mockApi patterns (MOCK_ORG_ID, seedAuthTokens).Test Plan
bash
cd frontend && npx playwright test rbac-syrve-navigation.spec.ts syrve-connection-navigation.spec.tsMHPAY-DOC-002 — Product & Security Docs Sync
Meta
| Field | Value |
|---|---|
| Import key | MHPAY-DOC-002 |
| State | Backlog |
| Priority | medium |
| Labels | docs, rbac, navigation, ai-agent |
| Modules | Docs portal |
Context
После NAV/API/RBAC документы расходятся с UI и контрактами.
Goal
Операторская и agent документация отражает Variant C hierarchy.
Scope / What To Do
- [ ]
docs/docs/product/user-roles.md— где какая навигация для каждой роли - [ ]
docs/docs/security/permission-matrix.md— sidebar visibility matrix - [ ]
docs/docs/architecture/scoped-rbac-and-tenancy.md— секция Active Connection Context - [ ]
docs/docs/frontend/overview.md— role-aware navigation update - [ ]
docs/docs/backend/api.md— если не обновлено в API-003 - [ ]
codegraph/manifest.yaml— routes, hooks, tests pointers
Acceptance Criteria
- [ ] Каждая роль MVP имеет явное «видит / не видит» для platform/org/connection nav
- [ ]
cd docs && npm run buildпроходит
Epic-Level Prohibitions (все задачи Variant C)
text
- Не вводить connection-scoped UserRoleAssignment без отдельного ADR и epic.
- Не переносить bank import/matching/allocation routes под /syrve/connections/.
- Не делать Mantine redesign / mobile overhaul (→ MHPAY-107).
- Не ослаблять permission checks для megaadmin convenience.
- Не использовать System.Text.Json; не JObject в application code.
- Не коммитить secrets, .env, реальные банковские файлы.
- Commit messages: [MHPAY-XXX], без упоминания AI tools (см. AGENTS.md).Epic Verification (финальный gate)
bash
dotnet build backend/src/MyHoreca.Pay.Api/MyHoreca.Pay.Api.csproj
dotnet test backend/tests/MyHoreca.Pay.UnitTests/MyHoreca.Pay.UnitTests.csproj --filter "FullyQualifiedName~ScopedRbac|FullyQualifiedName~Syrve"
cd frontend && npm run lint && npm run build
cd frontend && npx playwright test rbac-syrve-navigation.spec.ts syrve-connection-navigation.spec.ts syrve-connections-probe.spec.ts
cd docs && npm run buildHandoff после epic
- [ ]
current-implementation-state.md— полный список изменённых файлов и endpoints - [ ]
architecture-decisions-plane-backlog-v1.md— статусы MHPAY-108..114 - [ ] Plane issues → Done с commit hashes
- [ ] MHPAY-53 комментарий: extended by RBAC-006
Import в Plane
Импортировано 2026-07-06 скриптом tools/plane-mcp/create_navigation_tenancy_issues.py.
Отчёт: tools/plane-mcp/create-navigation-tenancy-issues-report.json
| Plane | Import key | Название (RU) |
|---|---|---|
| MHPAY-109 | MHPAY-NAV-000 | [Epic] Навигация, tenancy и иерархия подключений (вариант C) |
| MHPAY-110 | MHPAY-ADR-007 | ADR: информационная архитектура навигации и tenancy |
| MHPAY-111 | MHPAY-NAV-001 | Sidebar: Платформа / Организация / Syrve / Операции |
| MHPAY-112 | MHPAY-NAV-002 | Вложенные маршруты подключения и редиректы |
| MHPAY-113 | MHPAY-API-003 | Явный connectionId в Syrve read API |
| MHPAY-114 | MHPAY-RBAC-006 | Активный контекст Syrve-подключения |
| MHPAY-115 | MHPAY-FE-003 | Playwright: иерархия навигации |
| MHPAY-116 | MHPAY-DOC-002 | Синхронизация продуктовой документации |
Повторный запуск идемпотентен (external_source=myhoreca-pay-nav-import).