Задача Егора 2ч.

This commit is contained in:
2026-07-17 01:27:02 +03:00
parent 3f685d3e22
commit 3d798c13e3
20 changed files with 2003 additions and 275 deletions

View File

@@ -1190,16 +1190,20 @@ GET /api/workload/teachers?departmentId=1&startDate=2026-05-20&endDate=2026-06-0
него используется нормализованный `domain`.
**Логика:**
1. Создаёт временный HikariCP pool, ещё не доступный маршрутизатору.
2. Открывает соединение и явно проверяет его готовность.
3. Выполняет Flyway-валидацию и миграции tenant-БД.
4. Читает актуальный `tenants-secret`, применяет только upsert запрошенного `domain` и
1. До мутации разбирает и при необходимости полностью применяет текущую mounted-проекцию
tenant-конфигурации как безопасный baseline; ошибка подготовки возвращает `503`.
2. Создаёт временный HikariCP pool, ещё не доступный маршрутизатору.
3. Открывает соединение и явно проверяет его готовность.
4. Выполняет Flyway-валидацию и миграции tenant-БД.
5. Читает актуальный `tenants-secret`, применяет только upsert запрошенного `domain` и
выполняет условный `PUT` с прочитанным Kubernetes `resourceVersion`.
5. При конфликте повторно читает Secret и заново применяет свою мутацию с ограниченным
6. При конфликте повторно читает Secret и заново применяет свою мутацию с ограниченным
retry/backoff; неизменившаяся конфигурация не записывается повторно.
6. Одной атомарной публикацией заменяет связку `TenantConfig + DataSource`.
7. Передаёт прежний pool на отложенное закрытие после завершения активных запросов
7. Одной атомарной публикацией заменяет связку `TenantConfig + DataSource`.
8. Передаёт прежний pool на отложенное закрытие после завершения активных запросов
либо по истечении защитного таймаута.
9. Возвращает внутри backend `TenantLifecycleMutationResult` с подтверждённой
`TenantSecretUpdateReceipt` для согласования mounted-проекции.
Backend соединяется с Kubernetes API только через проверенный service-account CA и
hostname verification. Если безопасно сохранить tenant-конфигурацию не удалось, операция
@@ -1236,6 +1240,15 @@ HTTP-статусы: `400` для некорректного payload и `503` д
компенсация также допускается только для подтверждённой версии и не затирает более новое
изменение другого pod. Неизвестный `domain` возвращает `404`, lifecycle-ошибка — `503`.
Для `POST` и `DELETE` baseline готовится до API-мутации под общим lifecycle monitor.
После успеха backend использует семантические `previousTenants` и `committedTenants` из
`TenantSecretUpdateReceipt`. Fence создаётся только для реального изменения общего Secret
(`persisted=true`, `changed=true`): известные старые и промежуточные снимки временно
откладываются, ожидаемый committed-снимок применяется полностью. Persisted no-op и локальная
операция fence не создают, а неизвестный merged snapshot другого pod синхронизируется сразу.
SHA-256 файла подтверждается только после полного успешного sync; ошибки повторяются с
экспоненциальной задержкой от 30 до 300 секунд.
### `POST /api/database/test`
Тест подключения к произвольной БД (без регистрации тенанта).