docs: simplify conventions layout
Backend security / security (pull_request) Successful in 7s
Backend verify / verify (pull_request) Successful in 2m3s
Conventional commits / commits (pull_request) Successful in 24s
Backend security / security (push) Successful in 7s
Backend verify / verify (push) Successful in 2m10s
Backend security / security (pull_request) Successful in 7s
Backend verify / verify (pull_request) Successful in 2m3s
Conventional commits / commits (pull_request) Successful in 24s
Backend security / security (push) Successful in 7s
Backend verify / verify (push) Successful in 2m10s
This commit was merged in pull request #18.
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
# Backend data
|
||||
|
||||
## Ownership и выбор операции
|
||||
|
||||
PrismaService — существующий shared DB provider с lifecycle приложения.
|
||||
`prisma/schema.prisma` и migrations владеют persistence; `generated/prisma`
|
||||
создаётся Prisma и не редактируется вручную. Конфигурация URL находится в
|
||||
`prisma.config.ts`/validated environment; SQLite — текущая локальная база.
|
||||
|
||||
| Ситуация | Решение |
|
||||
| --- | --- |
|
||||
| Данные для use case | Concrete repository; use case не импортирует PrismaService/Prisma и не строит queries |
|
||||
| Несколько записей обязаны выполниться вместе | Database transaction вокруг инварианта |
|
||||
| Конкурентная смена одного значения | Atomic conditional update/constraint с проверкой результата |
|
||||
| Независимые reads | Не добавляй transaction ради внешнего вида |
|
||||
| Общая persistence abstraction | Только при реальной общей ответственности; generic repository для одной Prisma реализации не нужен |
|
||||
|
||||
Размещение repository определяется [Architecture](../architecture.md):
|
||||
в слоистом module это `infrastructure/`.
|
||||
Repository — конкретный класс `*.repository.ts` у business owner, без обязательных
|
||||
interface/port/adapter. Он владеет queries, includes/filtering, DB mapping и
|
||||
согласованным чтением. Суффиксы `*.persistence.ts`, `*.store.ts`, `*.dao.ts`
|
||||
для той же роли не используем. Nest module регистрирует repository приватно.
|
||||
|
||||
Новые business decisions (можно ли менять архивную карту, допустим ли перевод)
|
||||
принадлежат application/domain; repository сохраняет persistence и ownership
|
||||
ограничения. Existing checks/HTTP helpers в BankCardsRepository — migration
|
||||
candidate, не повод дублировать их при новом use case или разрывать transaction.
|
||||
`BaseRepository<T>`, `GenericRepository<T>` и RepositoryFactory поверх Prisma
|
||||
не нужны без отдельной общей ответственности.
|
||||
|
||||
`BankCardsRepository.summaryData` проверяет владельца карты и получает операции
|
||||
с категориями в одной read transaction. `GetBankSummaryUseCase` выбирает период,
|
||||
вызывает repository, затем чистый `bankSummary` и формирует ответ. Prisma records
|
||||
не становятся domain entities: расчёт получает только нужные ему значения.
|
||||
|
||||
Не создавай обёртку на каждый вызов Prisma. Существующие связные CRUD/transaction
|
||||
services (auth, lifecycle подключения, изменения карт/операций/категорий)
|
||||
сохраняют queries рядом с CAS и проверками инварианта, если их перенос требует
|
||||
лишь набора pass-through методов. Новая самостоятельная read/write capability
|
||||
получает repository method; самостоятельный use case не выполняет Prisma queries.
|
||||
`BankCardsRepository.write` сохраняет общую retry/transaction boundary для
|
||||
существующих banking services. Такой callback с Prisma transaction client —
|
||||
локальная техническая граница этих services, не API для domain или use cases.
|
||||
|
||||
Выбирай только нужные данные, сохраняй 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/integrations/tbank.md#граница-финансового-кэша).
|
||||
|
||||
## Деньги и точность
|
||||
|
||||
Для денежных значений используй existing decimal helpers и строковый wire value,
|
||||
не JS floating-point арифметику для сумм. Currency — отдельная часть Money;
|
||||
разные валюты не складываются без явно заданного conversion contract.
|
||||
Источник: [Money](../../../docs/glossary.md#money),
|
||||
пример: [decimal.ts](../../src/common/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](testing.md).
|
||||
Reference in New Issue
Block a user