78 lines
5.2 KiB
Markdown
78 lines
5.2 KiB
Markdown
# Спринт 5 — оптовые продажи, email, аудит, надёжность import-job
|
||
|
||
Автономная работа. После каждого пункта: `dotnet build` (SDK 8.0.126),
|
||
unit + integration тесты, коммит порцией, отметка `[x]`, коммит прогресса.
|
||
|
||
Multi-tenant: все новые сущности — `TenantEntity` с `OrganizationId` +
|
||
query filter. E2E на изоляцию A vs B где применимо.
|
||
|
||
## Чек-лист
|
||
|
||
1. [x] **P1-5 Оптовая отгрузка (Demand)** — Domain `Demand`+`DemandLine`
|
||
(CounterpartyId юрлица, способ оплаты нал/безнал, цена опт., НДС). EF +
|
||
миграция. Контроллер CRUD + Post/Unpost. Web `/sales/demands`.
|
||
`StockMovement` тип `WholesaleSale`. Multi-tenant. Тесты.
|
||
✅ Зеркалит RetailSale без RetailPoint/Cashier; `DemandPayment.Credit`
|
||
(постоплата/дебиторка), `PaidAmount` для отслеживания. Permissions
|
||
переиспользуют существующие `DemandsEdit/Post`. Метрики
|
||
`documents_posted{type="demand"}`. 3 интеграционных теста.
|
||
2. [x] **P1-18 Аудит мутаций tenant'а** — Domain `OrgAuditLog` (как
|
||
`SuperAdminAuditLog`, но per-org). Hook через EF SaveChangesInterceptor
|
||
на Supply/Sale/Demand/Product/Counterparty. UI: `/audit-log` для админа.
|
||
Multi-tenant строго. Тесты.
|
||
✅ `OrgAuditInterceptor` снимает diff на `SavingChanges` (до commit) —
|
||
атомарно с мутацией. ChangesJson: `{"field":{"before":X,"after":Y}}`.
|
||
Белый список типов: Supply/SupplierReturn/RetailSale/Demand/Product/
|
||
ProductPrice/ProductBarcode/Counterparty. Web `/audit-log` с фильтрами
|
||
и diff-viewer'ом. Tenant-isolation через query-filter. 3 интеграционных.
|
||
3. [x] **P1-22 Email-шаблоны** — расширить MailKit-сервис:
|
||
`Resources/EmailTemplates/*.html`. Шаблоны: приглашение сотрудника с
|
||
временным паролем (sendInvite=true), еженедельный summary владельцу
|
||
(Hangfire recurring), low-stock alert (Hangfire daily). Тесты рендеринга.
|
||
✅ `IEmailSender.SendHtmlAsync` (multipart/alternative с plain fallback);
|
||
`EmailTemplateRenderer` (mustache-light: `{{key}}` escape, `{{{raw}}}`,
|
||
`{{#key}}…{{/key}}` условие); `EmailTemplates` загружает embedded
|
||
`Resources/EmailTemplates/*.html` (Subject: первой строкой). Шаблоны:
|
||
invite/weekly-summary/low-stock. Hangfire: weekly понедельник 07:00,
|
||
low-stock ежедневно 08:00. 8 unit-тестов.
|
||
4. [x] **TD-5 ImportJobRegistry в БД** — сейчас in-memory `ConcurrentDictionary`,
|
||
теряется при рестарте. Перевод на таблицу `ImportJobs` (Id, OrgId, Status,
|
||
Progress, Total, StartedAt, FinishedAt, Errors JSON). Миграция.
|
||
`MoySkladImportController` использует. Тесты.
|
||
✅ `Domain.Integrations.ImportJob` (TenantEntity); миграция `Phase8c_ImportJobs`.
|
||
`ImportJobRegistry` теперь IServiceScopeFactory-backed: `Create` пишет
|
||
строку немедленно, `SaveAsync` обновляет, `Get/RecentlyFinished` читают
|
||
из БД. Контроллер `MoySkladImportController.RunInBackgroundAsync` дополнен
|
||
periodic flush через Timer (каждые 2 сек) + финальный flush в finally —
|
||
UI видит реальный прогресс, terminal-state сохраняется через рестарт.
|
||
3 интеграционных теста (survives across scope, RecentlyFinished, tenant-isolation).
|
||
|
||
## Итог
|
||
|
||
**Все 4 пункта выполнены.** Спринт 5 завершён 2026-05-28.
|
||
|
||
Сводка:
|
||
- **P1-5 Demand** — оптовая отгрузка контрагенту-юрлицу с `DemandPayment.Credit`
|
||
и `PaidAmount`-полем; 3 интеграционных.
|
||
- **P1-18 OrgAuditLog** — per-tenant журнал через `SaveChangesInterceptor`,
|
||
atomic с мутацией, diff в jsonb; 3 интеграционных.
|
||
- **P1-22 Email** — `IEmailSender.SendHtmlAsync` (multipart) + mustache-light
|
||
renderer + 3 шаблона + 2 recurring Hangfire-джоба; 8 unit.
|
||
- **TD-5 ImportJob** — persistence в БД, переживает рестарт, periodic flush
|
||
для live-прогресса; 3 интеграционных.
|
||
|
||
**Сборка:** зелёная.
|
||
**Тесты:** 35 unit + 68 integration = **103 зелёных**.
|
||
|
||
### Что осталось вне scope
|
||
- ОФД-оператор (нужен внешний участник: `Транском`/`Касса24`);
|
||
- MoySklad webhook-токены прод;
|
||
- WPF/POS UI (Windows-SDK);
|
||
- Стейдж→прод-деплой;
|
||
- Real SMTP-сервер для прод (Mailgun/Sendgrid/etc).
|
||
|
||
## Лог
|
||
|
||
- Каждый пункт: build + тесты + коммит порцией + отметка [x] + коммит прогресса.
|
||
- Все правки на `main` (origin Forgejo), без коммита `global.json`.
|