food-market/docs/sprint3-progress.md
nns 3ded4db73a docs(sprint3): P1-9 done
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 11:14:41 +05:00

43 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Спринт 3 — отчёты и аналитика (P1)
Автономная работа. После каждого пункта: `dotnet build` (SDK 8.0.126),
unit + integration тесты этого пункта, коммит порцией, отметка `[x]` здесь,
коммит прогресса.
Multi-tenant: все запросы фильтруются по `OrganizationId` через query filter
`AppDbContext`. Каждый отчёт — отдельный e2e/integration на изоляцию orgA vs orgB.
## Чек-лист
1. [x] **P1-8 Отчёт «Продажи»**`/api/reports/sales` с группировкой по период
(день/неделя/месяц), товар, кассир, касса, способ оплаты; фильтры
(от/до, магазин, группа товаров). Web `/reports/sales`: фильтр периода,
табы по группировкам, экспорт CSV+XLSX.
✅ Реализация: проекция в плоский ряд на сервере + агрегация в C#
(EF8 не переводит «distinct count» в group-проекции с nullable-ключами).
`CsvHelper` + `ClosedXML`. Bonus: исправлен баг `RetailSalesController.Update`
(DbUpdateConcurrency на свеже-созданном возврате). 5 интеграционных тестов.
2. [x] **P1-9 Отчёт «Остатки на дату»**`/api/reports/stock` восстанавливает
остатки на произвольную дату через журнал `StockMovement` (Σ движений до
даты по продукту). Web `/reports/stock`: выбор даты, фильтр магазин/группа,
экспорт. Edge: дата в будущем, дата раньше первой операции.
✅ Реконструкция через Σ `StockMovement.Quantity` где `OccurredAt ≤ date`.
Стоимость — последний `UnitCost` движения до даты + fallback на `Product.Cost`.
Edge'ы покрыты тестами: 5 интеграционных (today=current, before-first→empty,
future=current, future-supply исключается на «сегодня», tenant-изоляция).
3. [ ] **P1-10 Отчёт «Прибыль»**`/api/reports/profit` = выручка себестоимость
по периодам/группам/товарам. Cost-snapshot уже есть в `RetailSaleLine`
(через `UnitCost` movement'а). Защита от деления на ноль при нулевой выручке.
4. [ ] **P1-11 Отчёт «ABC-анализ»** — топ товаров по выручке за период,
классы A/B/C по Парето (A=80%, B=15%, C=5% накопительной выручки).
Параметр метрики (выручка/прибыль/маржа). Web с визуализацией.
5. [ ] **P1-19 OpenAPI / Swagger**`Swashbuckle.AspNetCore`,
`/swagger/v1/swagger.json` в Development. Сгенерировать TS-клиент для
food-market.web (`openapi-typescript`/`nswag`) и подключить для пары
контроллеров как образец.
## Лог
- Каждый пункт: build + тесты + коммит порцией + отметка [x] + коммит прогресса.
- Все правки на `main` (origin Forgejo), без коммита `global.json`.