food-market/docs/sprint9-progress.md
nns a1cccdeef5 docs(sprint9): итог — все 4 пункта ✓, stage 8/8 e2e зелёные
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 21:38:26 +05:00

5.8 KiB
Raw Permalink Blame History

Sprint 9 — лояльность, акции, mobile-адаптация, PWA

Цель: программы лояльности (баллы/% скидка) для постоянных покупателей, промокоды/акции в чеке, починить узкие экраны (телефон/планшет), PWA-обёртка владельца для отчётов с homescreen-икоником.

Старт: 2026-06-01. Исполнитель: Claude Opus 4.7 (автономный режим).

Это последний автономно-безопасный спринт. Дальше нужен человек: ОФД-интеграция, MoySklad-токены, POS WPF на Windows, kz-локализация, прод-деплой.

Принципы

  • Multi-tenant обязателен (OrganizationId на каждой новой таблице, query filter).
  • Каждый пункт: dotnet build + локальные тесты + ~/deploy-stage.sh + retest на https://test.admin.food-market.kz (включая mobile viewport 375x667).
  • НЕ трогать: global.json, прод-стек (admin.food-market.kz), POS WPF.

Чек-лист

  • 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.
  • 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-адаптация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'и не найдены.
  • 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.