Разделение API-контрактов и Domain-моделей
Назначение
Правила устранения утечки persistence JSONB и aggregate internals в публичный REST API сервисов Pin.
Это code-time руководство для разработчиков backend, а не содержание ТЗ. Термины реализации (mapper, validator, handler, EF-колонка) относятся к коду. Спецификации-постановки (
docs/06-services/**) их не цитируют; в постановке остаётся только принцип: публичный API != внутренности персистентности.
Слои
| Слой | Расположение | В Swagger |
|---|---|---|
| Domain JSONB | Domain/JsonDocuments/ | Нет |
| Application CRUD | Application/<Feature>/Models/ | Да |
| Api forms | Api/Features/*/ | Да (1:1 с Create/Update) |
Запрет: using Domain.JsonDocuments в Api и public Application types (*Form, *Command, *Query, *Result, List*Entry).
CRUD-модели
| Операция | Имя | Ограничения |
|---|---|---|
| Create | Create* | Нет FieldId, version, signature, system Meta |
| Update | Update* | FieldId для existing; новые — FieldKey only |
| Get | Get*Result, Get*Schema | Server ids + read-only metadata |
| List | List*Entry | Минимальная проекция |
Create не наследует Update. Общие поля — internal base records в Application, public API — отдельные sealed types.
FieldKey и FieldId
- Create: только
FieldKey(required slug). - Update:
FieldId(Guid) для существующих;FieldKeyalways; новые поля безFieldId. - Get: оба поля.
Именование JSONB в API
| EF column | API property |
|---|---|
SchemaJsonb | Schema |
DataJsonb (dictionary item) | FieldValues |
DataJsonb (catalog entry) | EntryFields |
RulesJsonb | Rules |
LevelsJsonb | ThresholdLevels |
Results
- Domain-specific ids:
DictionaryId,CatalogEntryId. - Domain enums в results, не
enum.ToString(). - List items: suffix
Entry(ListDictionariesEntry).
ADR
docs/02-architecture/adr/0050-api-domain-model-separation.md
Обратные ссылки
Автоссылки: где используется этот документ.