Три опорных решения
Один мастер
Сервис хранит заявки, назначения и журнал. Сфера — источник справочников. Решение ожидает Q-02.
Заменяемые источники
Bitrix24, Time и 1С подключаются через адаптеры. Неполный ответ не превращается в удаление или ноль.
Проверка без браузера
Расчёты — чистые функции. Решения и синк проверяются через интерфейсы модулей на настоящей тестовой БД.
architecture.md
C4 L1: контекст
Границы сервиса: Сфера, Time и 1С остаются отдельными источниками. Вход подтверждает личность, право на проект проверяет сервис.
Исходник Mermaid
flowchart LR
PM[Руководитель проекта] -->|Заявка, изменение, свои отчёты| S[Сервис ресурсного планирования]
RM[Ресурсный менеджер] -->|Решения, общий план| S
S -->|Чтение справочников и проектов| B[Сфера / Bitrix24]
S -->|Чтение фактических часов| T[Time Лоции]
S -->|Чтение календаря и возможных ставок| C[1С]
S -->|Вход и проверка личности| I[Bitrix24 OAuth или корпоративный SSO]
O[Технический оператор] -->|Состояние синка, восстановление| Sarchitecture.md
C4 L2: контейнеры
Один репозиторий, web и worker из одного релиза. В локальном режиме PGlite принадлежит одному процессу; синк запускается явно.
Исходник Mermaid
flowchart TB
U[Браузер: Nuxt UI] -->|HTTPS, cookie, общие DTO| A[Nitro API: доступ и модули]
A -->|Транзакции и проекции| D[(Postgres)]
W[Фоновый Node worker: тот же пакет модулей] -->|Задания, lease, checkpoint| D
A -->|Ручной запуск: запись задания| D
W -->|Порты чтения| E[Bitrix24 / Time / 1С]
A -->|Порт идентификации| I[OAuth / SSO]
A --> L[Логи, метрики, Sentry]
W --> L
D --> B[Резервные копии и проверка восстановления]architecture.md
C4 L3: глубокие модули
Шесть модулей с небольшими интерфейсами. Правила не зависят от HTTP и формата ответов внешних систем.
Исходник Mermaid
flowchart LR
H[HTTP handlers] --> A[Доступ]
H --> R[Заявки и согласование]
H --> P[Назначения и ресурсный план]
H --> V[Отчёты]
R --> P
R --> C[Расчёты]
P --> C
V --> C
R --> A
P --> A
V --> A
W[Worker / ручной запуск] --> S[Справочники и синк]
S --> X[SphereClient / ProjectSource / TimeSource / OneCSource]
R --> DB[(Транзакционная БД)]
P --> DB
V --> DB
S --> DB
A --> DBarchitecture.md
Модель хранения и транзакции
Согласованное назначение имеет версии. Журнал решения и изменение плана коммитятся вместе. Внешние ID хранятся отдельно от локальных.
Исходник Mermaid
erDiagram
REQUEST ||--|{ RESOURCE_LINE : contains
REQUEST ||--o{ DECISION_LOG : records
RESOURCE_LINE ||--o{ ASSIGNMENT : creates
ASSIGNMENT ||--|{ ASSIGNMENT_VERSION : versions
ASSIGNMENT ||--o{ ASSIGNMENT_CHANGE : changes
EMPLOYEE ||--o{ ASSIGNMENT : assigned
PROJECT ||--o{ REQUEST : requested
PROJECT ||--o{ PROJECT_MANAGER : grants
EMPLOYEE ||--o{ ACTUAL_ENTRY : worked
PROJECT ||--o{ ACTUAL_ENTRY : measured
CALENDAR_VERSION ||--|{ CALENDAR_DAY : definesspec.md
Жизненные циклы
Только ожидающая заявка допускает решение. После возврата создаётся новая заявка; старая остаётся в истории.
Исходник Mermaid
stateDiagram-v2
[*] --> pending: create или change
pending --> approved: РМ согласует
pending --> returned: РМ возвращает с причиной
pending --> rejected: РМ отклоняет с причиной
returned --> [*]: новая исправленная заявка с другим ID
rejected --> [*]
approved --> [*]: решение неизменноdata-flows.md
F1. Сотрудники, подразделения, ресурсные роли — INT 02
Деактивация закрывает вход и новые назначения, но сохраняет согласованный план. Должностная роль не даёт права РМ.
Исходник Mermaid
sequenceDiagram
participant W as Sync runner
participant B as SphereClient
participant S as Сфера
participant D as БД
W->>B: listDepartments / searchUsers
B->>S: department.get / user.get, страницы
S-->>B: ID, атрибуты, ACTIVE, next
B-->>W: Нормализованные записи и полнота
W->>D: staging + проверка mapping ролей
W->>D: activate snapshot, мягкая деактивация, отзыв сессий
Note over W,D: История назначений не удаляетсяdata-flows.md
F2. Проекты и РП — INT 01
Рабочая группа — рекомендация, не принятое решение. Смена сущности меняет ProjectSource, а не бизнес-правила.
Исходник Mermaid
sequenceDiagram
participant W as Sync runner
participant P as ProjectSource
participant B as Сфера
participant D as БД
W->>P: read(cursor)
P->>B: sonet_group.get ИЛИ crm.deal.list ИЛИ crm.item.list
B-->>P: ID, название, ответственный, закрытие
P-->>W: SourceProject и reference пользователя
W->>D: ExternalIdentity + Project + ProjectManager
Note over W,D: Нет подтверждённого mapping РП — нет доступа к проектуdata-flows.md
F3. Фактические часы из Time Лоции
Повтор импорта не удваивает часы. Полный снимок позволяет отличить ноль от отсутствия данных. Реальный API Time предстоит подтвердить.
Исходник Mermaid
sequenceDiagram
participant W as Sync runner
participant T as TimeSource
participant B as SphereClient
participant D as БД
W->>T: read(window, cursor)
T-->>W: entryId, userId, taskId, date, seconds, version
W->>B: getTasks(неизвестные taskId)
B-->>W: taskId и groupId
W->>D: сопоставление сотрудника и проекта, quarantine неизвестных
W->>D: upsert entries + coverage + checkpoint
Note over W,D: Только полное покрытие позволяет вывести явный нольdata-flows.md
F4. Календарь, отпуск и расходные ставки — 1С
Календарь версионируется, расходная ставка фиксируется в решении. API 1С и политика пересчёта — вопросы заказчику.
Исходник Mermaid
sequenceDiagram
participant W as Sync runner
participant C as OneCSource
participant D as БД
participant R as Requests
W->>C: calendar(year) и разрешённые costRates
C-->>W: Полные версии календаря и ставок
W->>D: validate, stage, activate version
R->>D: получить серверную ставку и версию календаря
R->>D: сохранить costRateSnapshot при решении
Note over D,R: Смена справочника не переписывает согласованную ставкуdata-flows.md
F5. Вход и определение роли — NFR 01
Bitrix OAuth или корпоративный SSO подтверждает личность; локальные grants определяют права. Тестового входа в рабочей сборке нет.
Исходник Mermaid
sequenceDiagram
participant U as Браузер
participant A as Access
participant I as Bitrix24 OAuth или SSO
participant D as Session и Grants
U->>A: начать вход
A-->>U: redirect + одноразовый state
U->>I: аутентификация
I-->>A: callback с code и state
A->>I: серверный обмен и проверка личности
I-->>A: подтверждённый subject
A->>D: найти Principal, active, AccessGrant
A-->>U: HttpOnly cookie или отказ доступа
U->>A: запрос бизнес API
A->>D: проверить сессию, активность и scopedata-flows.md
F6. Заявки, назначения и мастер-данные — INT 03, NFR 02
Проверка дневной ёмкости, версия назначения и журнал — одна транзакция. Запись обратно в Сферу не включена в предложенный вариант.
Исходник Mermaid
sequenceDiagram
participant U as РП или РМ
participant A as Requests
participant P as Assignments
participant D as БД
U->>A: commandId, expectedVersion, действие
A->>A: доступ, валидация, idempotency
A->>D: BEGIN и блокировки сотрудников
A->>D: перечитать заявку, версии, ставки
A->>P: applyDecision в той же Tx
P->>P: весь дневной план, лимит FTE
P->>D: новая версия назначения
A->>D: DecisionLog + Request + CommandReceipt
A->>D: COMMIT
A-->>U: результат или типизированный конфликт
Note over A,D: Любая ошибка до COMMIT — полный ROLLBACKДокументы и решения
До реализации нужны ответы о проектах и РП, мастере данных, ставках, API Time и 1С, входе и эксплуатационных требованиях. Рекомендации не подменяют решение заказчика.