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 — остальное. Товары с
|
`cumulativeShare ≤ 80`, B — `≤ 95`, C — остальное. Товары с
|
||||||
неположительной метрикой исключаются. Web: цветные плашки класса +
|
неположительной метрикой исключаются. Web: цветные плашки класса +
|
||||||
полоса накопительной доли. 4 интеграционных теста.
|
полоса накопительной доли. 4 интеграционных теста.
|
||||||
5. [ ] **P1-19 OpenAPI / Swagger** — `Swashbuckle.AspNetCore`,
|
5. [x] **P1-19 OpenAPI / Swagger** — `Swashbuckle.AspNetCore`,
|
||||||
`/swagger/v1/swagger.json` в Development. Сгенерировать TS-клиент для
|
`/swagger/v1/swagger.json` в Development. Сгенерировать TS-клиент для
|
||||||
food-market.web (`openapi-typescript`/`nswag`) и подключить для пары
|
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