add build development phases
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# Backend conventions checklist (quick reference)
|
||||
|
||||
The authoritative rules are [`server/CLAUDE.md`](../../../server/CLAUDE.md) and
|
||||
[`server/CONVENTIONS.md`](../../../server/CONVENTIONS.md). This is a tick-list to keep handy while you
|
||||
build. If anything here seems to conflict with those files, **those files win**.
|
||||
|
||||
## Architecture
|
||||
- [ ] Clean Architecture respected: Domain → Application → Infrastructure → API; **dependencies point
|
||||
inward**. Domain references nothing; Application references only Domain; Infrastructure/API
|
||||
implement Application contracts. Never reference Infrastructure/API from Domain/Application.
|
||||
- [ ] New cross-layer dependency or project/folder ⇒ update the **Project map** in `server/CLAUDE.md`.
|
||||
- [ ] New infrastructure is registered via a `ServiceConfiguration/` extension method called from
|
||||
`Program.cs` — never inline in `Program.cs`.
|
||||
|
||||
## CQRS / features
|
||||
- [ ] Feature lives in `Baya.Application/Features/<Area>/{Commands|Queries}/<Name>/`.
|
||||
- [ ] Requests are `record`; handlers are `internal sealed`; one handler per request.
|
||||
- [ ] **Never throw for expected failures** — return `OperationResult.SuccessResult/FailureResult/NotFoundResult`.
|
||||
- [ ] Contracts the handler needs are interfaces in `Application/Contracts/`, implemented in Infrastructure.
|
||||
- [ ] Input-bearing commands have a FluentValidation validator (picked up by `ValidateCommandBehavior`).
|
||||
|
||||
## Persistence (EF Core)
|
||||
- [ ] Read queries use `AsNoTracking()` **and** project with `.Select(...)` to a DTO — never hydrate
|
||||
entities to map them. Mapping (Mapster) happens in the handler after the query.
|
||||
- [ ] Every unbounded list is **paginated** (`Skip`/`Take`); no unbounded `ToListAsync()`.
|
||||
- [ ] Access the DB via `IUnitOfWork` in handlers; commit once per command (`CommitAsync`).
|
||||
- [ ] One `IEntityTypeConfiguration<T>` per entity in `Persistence/Configuration/<Area>Config/`.
|
||||
- [ ] Soft-deletable entities declare a global query filter (`!IsDeleted` / `deleted_at IS NULL`).
|
||||
- [ ] Audit fields (`CreatedAt/ModifiedAt/CreatedById/ModifiedById`) are set by the SaveChanges
|
||||
interceptor via `ICurrentUser` — handlers don't pass them.
|
||||
- [ ] Encrypted PII columns (phone, national_id, IBAN, addresses, clinical notes) go through the field
|
||||
encryptor seam — never stored or logged in plaintext.
|
||||
|
||||
## Performance, caching, money, idempotency
|
||||
- [ ] Read-heavy/config/reference data is cached behind the cache seam with sensible invalidation;
|
||||
`platform_configs` values are read through the typed config accessor (cached), not hardcoded.
|
||||
- [ ] **Money is IRR `BIGINT` — no floats, anywhere.** Toman conversion happens only inside a provider
|
||||
adapter at its boundary. The three booking amounts always satisfy
|
||||
`gross = commission + payout`.
|
||||
- [ ] Money-path writes are **idempotent** (webhook dedup on the unique external-event key; filtered
|
||||
unique on succeeded transaction; forward-only state machines) and, where the phase says so, guarded
|
||||
by a Redis **distributed lock** — with the DB constraint as the authoritative backstop.
|
||||
- [ ] `ledger_entries` is append-only and balanced (Σdebit = Σcredit per `transaction_group_id`).
|
||||
|
||||
## API surface
|
||||
- [ ] Controllers are `sealed`, inherit `BaseController`, inject `ISender`, return
|
||||
`base.OperationResult(...)` — never `Ok()/BadRequest()/NotFound()` directly. (Note: the baseline
|
||||
has **no** controllers yet — REST is introduced in an early phase; follow that pattern thereafter.)
|
||||
- [ ] Routes use `[controller]`/`[action]` tokens (snake_case transformer); pass `CancellationToken`.
|
||||
- [ ] Authorize with the narrowest fitting policy; auth/OTP/refund/payout-sensitive endpoints are
|
||||
rate-limited.
|
||||
- [ ] The endpoint's contract is published to `dev/contracts/` (see operating-rules §6).
|
||||
|
||||
## Quality
|
||||
- [ ] `async`/`await` all the way; `CancellationToken` threaded through; no `.Result`/`.Wait()`/`async void`.
|
||||
- [ ] Package versions only in `Directory.Packages.props`.
|
||||
- [ ] Handler unit tests (NSubstitute) + at least one `WebApplicationFactory` integration test per new
|
||||
feature area (happy path, 401, validation 400).
|
||||
- [ ] `dotnet build` zero new warnings; `dotnet test` green; no dead code.
|
||||
Reference in New Issue
Block a user