docs(ai): add scoped backend conventions

This commit is contained in:
2026-09-09 16:23:03 +03:00
parent 320e8a04b0
commit a83e26e5ef
10 changed files with 377 additions and 36 deletions
+56
View File
@@ -0,0 +1,56 @@
# Backend data
## Ownership и выбор операции
PrismaService — существующий shared DB provider с lifecycle приложения.
`prisma/schema.prisma` и migrations владеют persistence; `generated/prisma`
создаётся Prisma и не редактируется вручную. Конфигурация URL находится в
`prisma.config.ts`/validated environment; SQLite — текущая локальная база.
| Ситуация | Решение |
| --- | --- |
| Один query/write конкретного use case | Existing service + PrismaService |
| Несколько записей обязаны выполниться вместе | Database transaction вокруг инварианта |
| Конкурентная смена одного значения | Atomic conditional update/constraint с проверкой результата |
| Независимые reads | Не добавляй transaction ради внешнего вида |
| Общая persistence abstraction | Только при реальной общей ответственности; generic repository для одной Prisma реализации не нужен |
Выбирай только нужные данные, сохраняй user/account ownership в запросах и
application checks. Предварительный lookup не заменяет unique constraint при race.
Пример: AuthService обрабатывает P2002 и использует conditional `updateMany`
для refresh rotation. Сначала пойми invariant; не копируй его flow в другой use case.
Transaction не охватывает сетевой T-Bank вызов как будто это одна atomic DB
операция. Планируй порядок и compensation по текущей задаче; не удерживай DB
lock во время retry внешней сети. Access/cache generation semantics — у
[T-Bank source](../../../docs/features/tbank-connection.md#граница-финансового-кэша).
## Деньги и точность
Для денежных значений используй existing decimal helpers и строковый wire value,
не JS floating-point арифметику для сумм. Currency — отдельная часть Money;
разные валюты не складываются без явно заданного conversion contract.
Источник: [Money](../../../docs/architecture/domain-glossary.md#money),
пример: [decimal.ts](../../src/tbank/decimal.ts). UI formatting не меняет
backend ownership расчётов и доменную семантику.
## Schema и migration
Сначала определи, какие существующие данные/consumers должны сохраниться.
Миграцию проверяй на disposable копии с representative existing data; generated
client обновляй из schema. Не переписывай уже применённую migration ради нового
состояния и не выполняй reset/drop реальной базы как шаг верификации.
Для destructive или compatibility-sensitive изменения подготовь backup/restore,
переход и проверку отката до его применения. SQLite/local MVP не означает disposable data.
**Безопасный путь:** additive изменение, заполнение/проверка данных и только затем
удаление прежней формы, если задача этого требует. Примеры schema/migrations:
[Prisma source](../../prisma/schema.prisma); исторический rationale —
[ADR 001](../../../docs/adr/001-prisma-sqlite-local-mvp.md), не текущий список таблиц.
## Проверка
`npx prisma validate`; после schema change `npx prisma generate` и
`npm run typecheck:app`. Invariants/atomicity/migration safety требуют tests
на соответствующей boundary: mock Prisma не доказывает реальную transaction.
Выбор integration/e2e и известные ограничения — в [Testing](backend-testing.md).