GET /api/admin/v1/property-object-types/{groupId}/month-overrides — Помесячные оверрайды типа объекта недвижимости (admin)
Назначение
Отдаёт администратору платформы полный список помесячных оверрайдов
PropertyObjectTypeMonthOverride типа объекта
недвижимости GroupId для таба «помесячные оверрайды». Оверрайды — child-сущности агрегата
PropertyObjectTypeConfig: читаются только в контексте
существующего родителя (инвариант INV-MO2 — если тип объекта недвижимости не настроен, ответ 404). Доступ —
только администратор платформы через admin API (ADR-0053).
| Поле | Значение |
|---|
| Сервис/контекст | invest-analytics |
| API area | admin (ADR-0053) |
| Feature group | admin-property-object-types |
| Статус | draft |
| Документ | docs/06-services/invest-analytics/api/admin/get-month-overrides.md |
Актор и доступ
| Проверка | Значение |
|---|
| Actor type | Operator(Admin) — администратор платформы (доступ через admin API, m2m client-credentials) |
| Auth policy / Permissions | policy AdminSystemOnly (клиент pin-admin-system); каталожное соответствие — permission invest-analytics.property-object-types.view |
| Scope (RBAC) | платформа |
| Tenant isolation | не применяется — платформенная настройка (ADR-0052 п.3) |
| Audit | read: не аудируется (PII нет) |
HTTP-контракт
| Поле | Значение |
|---|
| Method | GET |
| Route | /api/admin/v1/property-object-types/{groupId}/month-overrides |
| Success status | 200 |
| Idempotency header | не применяется (safe GET) |
| Correlation | сквозной trace через traceparent; X-Admin-User-Id — обязателен |
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|
GroupId | route | long | Да | > 0; существование настройки типа — шаг проверки (404) | — |
AdminUserId | header X-Admin-User-Id | Guid | Да | != Guid.Empty | контекст admin-области |
Пагинация не применяется — единицы–десятки строк на тип
(../../domain/property-object-type-month-override.md).
Модель ответа MonthOverridesResult
| Поле | Тип | Обязательность | Источник | Masking | Описание |
|---|
groupId | long | Да | echo route | — | Тип объекта недвижимости. |
propertyObjectTypeVersion | long | Да | PropertyObjectTypeConfig.Version | — | Ревизия родителя (для expectedVersion в replace-all PUT). |
items | IReadOnlyList<MonthOverrideItemModel> | Да (может быть пуст) | children агрегата | — | Оверрайды, сортировка year ASC, month ASC. |
MonthOverrideItemModel
Проекция полей дома property-object-type-month-override.md
один-в-один (null = «поле месяца не оверрайдится»; семантика/единицы — там и в
economic-model-config.md):
| Поле | Тип | Обязательность | Источник | Masking | Описание |
|---|
year | int | Да | .Year | — | Год месяца-оверрайда (2000–2100). |
month | int | Да | .Month | — | Месяц (1–12). |
marketPriceM2 | decimal? | Нет | .MarketPriceM2 | — | Абсолютная рыночная цена м², руб. |
priceGrowthMonthly | decimal? | Нет | .PriceGrowthMonthly | — | Темп роста цены в месяце. |
dailyRentM2 | decimal? | Нет | .DailyRentM2 | — | Абсолютная аренда руб/м²/сутки. |
rentGrowthMonthly | decimal? | Нет | .RentGrowthMonthly | — | Темп роста аренды. |
occupancy | decimal? | Нет | .Occupancy | — | Заполняемость месяца. |
expenseShare | decimal? | Нет | .ExpenseShare | — | Доля расходов месяца. |
ebitda | decimal? | Нет | .Ebitda | — | Абсолютный накопленный EBITDA/м². |
appreciationTaxMonthly | decimal? | Нет | .AppreciationTaxMonthly | — | Месячная ставка налога на прирост (годовая = ×12). |
ebitdaTaxMonthly | decimal? | Нет | .EbitdaTaxMonthly | — | Месячная ставка налога на EBITDA (годовая = ×12). |
Алгоритм
- Контекст и доступ. Администратор платформы через admin API (policy
AdminSystemOnly); scope —
платформа; право invest-analytics.property-object-types.view; заголовок X-Admin-User-Id.
- Проверка входа.
GroupId > 0, X-Admin-User-Id непустой — иначе ValidationError. Настройка типа
объекта недвижимости с этим GroupId должна существовать (INV-MO2 — оверрайды читаются только в
контексте родителя); если её нет → ошибка INVEST_ANALYTICS_PROPERTY_OBJECT_TYPE_NOT_FOUND (404).
- Что читаем. Полный список помесячных оверрайдов типа по
GroupId, отсортированный по year ASC,
month ASC (без пагинации — правило загрузки child-а агрегата,
../../domain/property-object-type-month-override.md).
- Правила и маппинг. Каждая строка проецируется в
MonthOverrideItemModel; propertyObjectTypeVersion
— ревизия родителя PropertyObjectTypeConfig.Version (для expectedVersion при replace-all сохранении).
- Результат. Список оверрайдов + ревизия родителя; пустой список — валидный ответ (тип настроен,
месяцы не переопределены).
Ошибки и failure modes
| Код | HTTP status | Условие | Сообщение | Retry |
|---|
ValidationError | 400 | GroupId <= 0 / заголовки | Ошибка валидации запроса | no retry |
FORBIDDEN | 403 | Клиент не pin-admin-system / нет policy | Доступ запрещён | no retry |
INVEST_ANALYTICS_PROPERTY_OBJECT_TYPE_NOT_FOUND | 404 | Настройка типа не создана (INV-MO2) | Настройка типа не найдена — сначала создайте тип | no retry |
Совместимость и наблюдаемость
- Additive-поля item-модели — без breaking; удаление/переименование — breaking (синхронно с домом
сущности и wire-моделью PUT).
- Logs:
admin-month-overrides-read (adminUserId, groupId, count). Metrics:
invest_analytics_admin_operations_total{operation="get-month-overrides"}. Traces — сквозной trace через
traceparent.
Acceptance Criteria
- Given тип
GroupId настроен и имеет 3 помесячных оверрайда, When администратор шлёт GET, Then
200 с items из 3 строк, отсортированных year ASC, month ASC; propertyObjectTypeVersion = ревизия
родителя.
- Given тип
GroupId настроен, но месяцы не переопределены, When GET, Then 200 с items = []
— валидный ответ (не ошибка).
- Given настройки типа с этим
GroupId не существует (INV-MO2), When GET, Then 404 INVEST_ANALYTICS_PROPERTY_OBJECT_TYPE_NOT_FOUND (оверрайды читаются только в контексте родителя).
- Given
GroupId <= 0 или пустой X-Admin-User-Id, When GET, Then 400 ValidationError.
- Given клиент не
pin-admin-system, When GET, Then 403 FORBIDDEN.
Обратные ссылки
Автоссылки: где используется этот документ.
Связанные документы