food-market/docs/sprint6-progress.md
nns 4675f38a0f
Some checks failed
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
Docker Public / Build + push Public (push) Has been cancelled
Docker Public / Deploy Public on stage (push) Has been cancelled
docs(sprint6): P2-4 done — все 5 пунктов выполнены, итог
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 17:59:47 +05:00

5 KiB
Raw Blame History

Спринт 6 — технический долг + 2FA

Автономная работа. После каждого пункта: dotnet build (SDK 8.0.126), unit + integration тесты, коммит порцией, отметка [x], коммит прогресса.

Не ломать auth. НЕ трогать global.json/POS/nginx/ОФД.

Чек-лист

  1. 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. TD-2 FluentValidationFluentValidation.AspNetCore, validator'ы для SupplyInputDto/RetailSaleInputDto/ProductInputDto/CounterpartyInputDto/ EmployeeInputDto. Auto-register. Тесты на каждый. Не используем deprecated FluentValidation.AspNetCore — текущая рекомендация: AddValidatorsFromAssemblyContaining<Program>() + кастомный ValidationFilter (IAsyncActionFilter). На неуспех → 400 ValidationProblemDetails. 5 validator'ов, 16 unit-тестов, 70 integration зелёных без регрессий.
  3. TD-4 Структурные log-fields в SerilogLogContext.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. 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 — два шага. Identity AuthenticatorTokenProvider (RFC 6238). Endpoints: /api/me/2fa/{status, enroll, verify, disable} с QR-URI. Password-grant на /connect/token принимает custom param otp_code; при включённом 2FA без него — invalid_grant с error_description=2fa_required. 4 интеграционных теста (тест сам генерит TOTP через RFC 6238).

Итог

Все 5 пунктов выполнены. Спринт 6 завершён 2026-05-28.

Сводка:

  • TD-6 RowVersion — Postgres xmin через UseXminAsConcurrencyToken на 5 документах, 409 при conflict. Bonus: исправил Supply.Update.
  • TD-2 FluentValidationValidationFilter + 5 validator'ов (Supply, RetailSale, Product, Counterparty, Employee).
  • TD-4 Structured loggingLogEnrichmentMiddleware (OrgId/UserId/ CorrelationId в LogContext), business-логи на Post-операциях.
  • TD-1 CQRS partial — MediatR + 3 handler-образца с testable-абстракциями.
  • P2-4 TOTP 2FA — endpoints + интеграция в password-grant.

Сборка: зелёная. Тесты: 57 unit + 74 integration = 131 зелёных.

Что осталось вне scope автономной работы

  • ОФД-оператор (Транском/Касса24),
  • MoySklad webhook-токены прод,
  • WPF/POS UI на Windows,
  • Стейдж→прод-деплой,
  • Реальный SMTP-провайдер прод (Mailgun/Sendgrid),
  • Backup-коды для 2FA recovery (отдельная задача).

Лог

  • Каждый пункт: build + тесты + коммит порцией + отметка [x] + коммит прогресса.
  • Все правки на main (origin Forgejo), без коммита global.json.