# Сессия 2026-06-12 ## Архитектурный анализ **Вердикт: модульный монолит (modular monolith)** Не чистый монолит, не микросервисы. Осмысленная архитектура с DI и разделением на слои. ### Слои ``` UI (EJS) → HTTP → API (JSON) → Queries → PostgreSQL ↑ DI через фабрики: createApiRouter({ auth, q }) ``` UI не ходит в БД напрямую — всегда через `ui/api-client.js` → HTTP → `/api/v1/*`. Разделение по протоколу. ### Степень связанности | Модуль | Связанность | Почему | |--------|-------------|--------| | `validators.js` | Ноль | Только `net`, чистые функции | | `config.js` | Ноль | Чистые данные | | `api-client.js` | Ноль | Только `http`/`https` | | `bearerAuth.js` | Ноль | Standalone middleware | | `queries.js` → `db.js` | Tight | Data-access — иначе быть не может | | `server.js` → всё | Tight | Оркестратор — нормально | ### Что хорошо - DI-паттерн: роутеры получают зависимости через фабрики - Нет циклических зависимостей — граф чистый DAG - Большинство модулей тестируемы изолированно - Лёгкий вынос API в микросервис: поменять `API_BASE` в `api-client.js` ### Что не очень - `server.js` знает про все модули (15 импортов) — но для монолита норма - `src/auth.js` делает и JWT, и IAM, и bearer — можно разделить - Дублирование `buildSessionUser` в `oidc.js` и `auth.js` ### Граф зависимостей ``` server.js ├── src/db.js → pg ├── src/middleware/session.js → express-session, connect-pg-simple ├── src/middleware/csp.js ├── src/middleware/rateLimit.js ├── src/auth.js → src/config.js ├── src/queries.js → src/db.js, src/validators.js ├── src/validators.js → net ├── src/config.js (ноль зависимостей) ├── src/api/index.js → src/api/routes/* → src/validators.js │ └── src/api/middleware/bearerAuth.js (ноль зависимостей) ├── ui/index.js → ui/routes/* → ui/api-client.js (только http/https) │ └── ui/routes/auth.js → src/auth.js (только safeReturn) └── src/routes/oidc.js ```