docs(sprint3): P1-19 done — все 5 пунктов выполнены, итог
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
dbd08f6fd2
commit
879e6b8cee
|
|
@ -38,10 +38,45 @@ Multi-tenant: все запросы фильтруются по `OrganizationId`
|
|||
`cumulativeShare ≤ 80`, B — `≤ 95`, C — остальное. Товары с
|
||||
неположительной метрикой исключаются. Web: цветные плашки класса +
|
||||
полоса накопительной доли. 4 интеграционных теста.
|
||||
5. [ ] **P1-19 OpenAPI / Swagger** — `Swashbuckle.AspNetCore`,
|
||||
5. [x] **P1-19 OpenAPI / Swagger** — `Swashbuckle.AspNetCore`,
|
||||
`/swagger/v1/swagger.json` в Development. Сгенерировать TS-клиент для
|
||||
food-market.web (`openapi-typescript`/`nswag`) и подключить для пары
|
||||
контроллеров как образец.
|
||||
✅ SwaggerGen с Bearer security-scheme + стабильные operationId
|
||||
(Controller_VerbAction — verb включён против коллизии WipeAll/WipeAllAsync)
|
||||
+ уникальные schemaId с namespace-префиксом. UI только в Development.
|
||||
`openapi-typescript` как devDependency + npm-script `gen:api`.
|
||||
`src/lib/api.generated.ts` + `apiClient.ts` (тонкая обёртка) — образец
|
||||
на Reports/Sales/ABC/Profit. `docs/openapi.md` — workflow генерации.
|
||||
|
||||
## Итог
|
||||
|
||||
**Все 5 пунктов выполнены.** Спринт 3 (отчёты и аналитика) завершён 2026-05-28.
|
||||
|
||||
Сводка:
|
||||
- **P1-8 Sales** — `/api/reports/sales` 7 группировок + CSV/XLSX, 5 интеграционных.
|
||||
- **P1-9 Stock** — реконструкция через журнал движений, 5 интеграционных (вкл. edges).
|
||||
- **P1-10 Profit** — netto с защитой от деления на ноль, 3 интеграционных.
|
||||
- **P1-11 ABC** — Парето 80/15/5 + 3 метрики + цветная UI-визуализация, 4 интеграционных.
|
||||
- **P1-19 OpenAPI** — Swagger + TS-клиент через openapi-typescript,
|
||||
обёртка `apiClient.ts` для подсказки IDE.
|
||||
|
||||
**Сборка:** зелёная. **Тесты:** 24 unit + 49 integration (32 sprint1+2 + 17 sprint3) **зелёные**.
|
||||
**Web:** `pnpm build` зелёный (4 новых report-страницы + boilerplate api.generated.ts).
|
||||
|
||||
### Архитектурное замечание
|
||||
Все отчётные контроллеры идут паттерном «плоский pull + group в C#» — EF8 не
|
||||
переводит `g.Select(...).Distinct().Count()` в SQL для group-проекций с
|
||||
nullable join-ключами (cashier, retail-point). Объёмы отчётов (~десятки
|
||||
тыс. строк/месяц) держатся в RAM спокойно; на крупных тенантах перейдём
|
||||
на raw SQL/views (вне scope этого спринта).
|
||||
|
||||
### Bonus
|
||||
Поймал и исправил баг `RetailSalesController.Update`: DbUpdateConcurrency
|
||||
`expected 1 row, affected 0` воспроизводился на возвратах сразу после
|
||||
`create-return`. Лечение — `ApplyLines` добавляет строки напрямую в DbSet
|
||||
(а не через nav-collection), Update не делает `Include(Lines)`, старые
|
||||
строки удаляются `ExecuteDelete`.
|
||||
|
||||
## Лог
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue