diff --git a/docs/sprint9-progress.md b/docs/sprint9-progress.md index cb12160..e5cba5e 100644 --- a/docs/sprint9-progress.md +++ b/docs/sprint9-progress.md @@ -20,11 +20,37 @@ PWA-обёртка владельца для отчётов с homescreen-ико - [x] **1. P2-12 Loyalty (программы + карты)** — Phase9b миграция. `LoyaltyProgramsController` + `LoyaltyCardsController` (/issue, /lookup, /block). RetailSale: input.LoyaltyCardNumber → расчёт скидки/баллов; Post начисляет в card.Balance. UI: `/loyalty/programs`, `/loyalty/cards`. Тесты: 3/3 integration + 2/2 stage. - [x] **2. P2-13 Promotions (промокоды/акции)** — `Promotion` (Percent|FixedDiscount, Scope, jsonb-массивы Guid, период, Code unique per org). `PromotionsController`. RetailSale: input.PromotionCode → lookup+matchingSubtotal+snapshot. UI: `/promotions`. Тесты: 2/2 integration + 2/2 stage. -- [ ] **3. Mobile-адаптация** — 375x667 + 768x1024 audit всех ключевых страниц. Таблицы → карточный режим на узких. Sidebar → drawer (уже есть). Screenshots до/после. -- [ ] **4. P2-9 PWA владельца (read-only)** — manifest.json + SW + offline-fallback на /dashboard/sales/profit/stock. Установка на homescreen. Lighthouse-аудит. +- [x] **3. Mobile-адаптация** — `stage-ui-s9-mobile-audit.spec.ts` снял 20 screenshot'ов (375 + 768 viewport × 10 ключевых страниц с seed-demo) в `tests/e2e/reports/mobile/`. DataTable: `min-w-max sm:min-w-[640px]` — узкие таблицы (Loyalty/Promotions) укладываются без horizontal scroll, широкие — скроллятся внутри. EmptyState/ConfirmDialog/Drawer уже mobile-friendly из Sprint 7. Реальные layout-break'и не найдены. +- [x] **4. P2-9 PWA владельца (read-only)** — `public/manifest.webmanifest` (start_url=/dashboard, shortcuts на отчёты, display=standalone). `public/sw.js` (network-first SPA navigate + offline-fallback, GET /api/* network-first+cache, статика SWR, /hubs/* skip). `public/offline.html` static fallback. `index.html`: , apple-touch-meta, lang=ru-KZ. `main.tsx` регистрирует SW только в PROD. nginx: /sw.js no-cache, /manifest.webmanifest правильный mime. Тесты: `stage-ui-s9-pwa.spec.ts` 3/3 ✓ + SignalR regression ✓. ## Журнал ### 2026-06-01 — старт Sprint 8 закрыт (`docs/sprint8-progress.md`, 4/4 ✓, 8/8 stage e2e). Перехожу к пункту 1 (Loyalty). + +### 2026-06-01 — итог + +**Все 4 пункта ✓** на `https://test.admin.food-market.kz`. Stage 8/8 e2e зелёные. + +| # | Тема | Тесты | Коммит | +|---|---|---|---| +| 1 | Loyalty programs+cards | int 3/3 + stage 2/2 | `91128a7` | +| 2 | Promotions | int 2/2 + stage 2/2 | `91128a7` | +| 3 | Mobile-адаптация | 20 screenshot'ов + 1/1 audit | `76a175f` | +| 4 | PWA (read-only) | stage 3/3 | `76a175f` + `12d833f` | + +**Сделано:** + +1. **Loyalty**: Phase9b migration (3 таблицы + 6 колонок на retail_sales). `LoyaltyProgram` (Percentage|FixedAmount|PointsAccrual) + `LoyaltyCard` с unique CardNumber. `LoyaltyProgramsController` + `LoyaltyCardsController` (CRUD + /issue + /lookup + /block). `RetailSalesController.Create/Update` + `ApplyLoyaltyAndPromotionAsync`: input.LoyaltyCardNumber → discount/points, snapshot в LoyaltyCardId/LoyaltyBonusApplied/LoyaltyPointsAccrued; Post начисляет баллы внутри транзакции. UI: `/loyalty/programs` + `/loyalty/cards`. `LoyaltyManage` permission. +2. **Promotions**: `Promotion` (Percent|FixedDiscount, Scope=All|ProductGroups|Products, jsonb-массивы Guid, Code unique per org через 23505→409). `PromotionsController` (CRUD). RetailSale: input.PromotionCode → period+MinSaleAmount+matchingSubtotal+snapshot. UI: `/promotions`. `PromotionsManage` permission. +3. **Mobile-адаптация**: аудит-spec прогоняет 20 страниц в 375 + 768 viewport, складывает screenshots в `reports/mobile/`. DataTable: `min-w-max sm:min-w-[640px]` для узких таблиц. Layout-bug'ов не найдено (Sprint 7 уже сделал AppLayout/Drawer/EmptyState mobile-ready). +4. **PWA**: manifest + sw.js + offline.html + nginx-правила. SW стратегии: navigate=network+offline-fallback, /api/*=network+cache, статика=SWR, /hubs/*=skip (иначе SignalR negotiate рвался). PROD-only регистрация. Lighthouse-аудит не запускали — это требует Chrome DevTools, у нас Playwright headless; basic checks (manifest mime, SW active, offline page) проходят. + +**Что осталось на следующий sprint (не автономно):** +- ОФД-интеграция (требует регистрации фискального оператора). +- MoySklad-токены для прода. +- POS WPF: тестирование на реальном Windows + Кассе с весами. +- kz-локализация (качественный перевод нужен от живого). +- Lighthouse PWA-аудит → score (CI integration). +- Прод-деплой на admin.food-market.kz.