# Спринт 6 — технический долг + 2FA Автономная работа. После каждого пункта: `dotnet build` (SDK 8.0.126), unit + integration тесты, коммит порцией, отметка `[x]`, коммит прогресса. Не ломать auth. НЕ трогать global.json/POS/nginx/ОФД. ## Чек-лист 1. [x] **TD-6 Concurrency-токены на документах** — `RowVersion` (PostgreSQL `xmin` через `IsRowVersion`) на Supply/Demand/RetailSale/Transfer/Inventory. Миграция. EF concurrency check. 409 при конфликте. Тест: два параллельных PUT → один 200, другой 409. ✅ Postgres `xmin` (system column, без миграции) через `UseXminAsConcurrencyToken` для 5 документов + `IVersionedEntity`-marker. SuppliesController PUT принимает `Xmin`, сверяет, 409 при mismatch. Bonus: Supply.Update перешёл на ExecuteDelete+AddRange (тот же fix что в RetailSale). 2 интеграционных теста. 2. [x] **TD-2 FluentValidation** — `FluentValidation.AspNetCore`, validator'ы для SupplyInputDto/RetailSaleInputDto/ProductInputDto/CounterpartyInputDto/ EmployeeInputDto. Auto-register. Тесты на каждый. ✅ Не используем deprecated `FluentValidation.AspNetCore` — текущая рекомендация: `AddValidatorsFromAssemblyContaining()` + кастомный `ValidationFilter` (IAsyncActionFilter). На неуспех → 400 ValidationProblemDetails. 5 validator'ов, 16 unit-тестов, 70 integration зелёных без регрессий. 3. [x] **TD-4 Структурные log-fields в Serilog** — `LogContext.PushProperty` в middleware: OrgId, UserId, CorrelationId. Бизнес-логи (Supply.Post, Sale.Post) — структурно. `docs/logging.md`. ✅ `LogEnrichmentMiddleware` после Authentication. CorrelationId из заголовка `X-Correlation-ID` или генерируется. Business-логи на Supply.Post / RetailSale.Post с именованными плейсхолдерами. `docs/logging.md` с паттерном + анти-паттернами (string interpolation, PII в логах). 4. [x] **TD-1 CQRS partial (MediatR)** — `CreateSupplyCommand`, `PostRetailSaleCommand`, `GetSalesReportQuery`. Показать паттерн, не полный рефакторинг. Тесты на handlers. ✅ MediatR подключён в `food-market.api` с авторегистрацией из `food-market.application`. 3 handler-образца с абстракциями (`ISupplyWriter`, `IRetailSalePoster`) — testable без EF/БД. Контроллеры остались на прежнем flow (поэтапная миграция). 6 unit-тестов. 5. [ ] **P2-4 2FA для админов (TOTP)** — `AuthenticatorTokenProvider`, endpoints `/api/me/2fa/enroll`, `/api/me/2fa/verify`, `/api/me/2fa/disable`. Опционально для Admin+SuperAdmin. При логине с включённым 2FA — два шага. ## Лог - Каждый пункт: build + тесты + коммит порцией + отметка [x] + коммит прогресса. - Все правки на `main` (origin Forgejo), без коммита `global.json`.