Два документа после полного обхода кодовой базы: - docs/TZ-доработка.md — что нужно сделать, P0/P1/P2 приоритеты, дорожная карта по спринтам, технический долг - docs/TZ-тестирование.md — сценарии тестирования по модулям, multi-tenant изоляция, регрессионный чек-лист, стратегия покрытия unit/integration/E2E Сводка готовности: ядро (auth/catalog/Supply/RetailSale/multi-tenancy) 85-95%, но критичные пробелы: ОФД, складские документы Enter/Loss/ Transfer/Inventory, Demand, отчёты, POS-приложение, observability. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
222 lines
30 KiB
Markdown
222 lines
30 KiB
Markdown
# ТЗ на доработку Food Market
|
||
|
||
> Дата составления: 2026-05-22
|
||
> Автор анализа: Claude Opus 4.7
|
||
> Базируется на полном обходе кодовой базы `~/food-market` (backend + web + public + tests + deploy).
|
||
|
||
---
|
||
|
||
## 1. Текущее состояние системы
|
||
|
||
### 1.1. Сводная таблица готовности по модулям
|
||
|
||
| Модуль / слой | Статус | Готовность | Ключевой комментарий |
|
||
|---|---|---:|---|
|
||
| **food-market.domain** | ✅ готово | 95% | 26 сущностей, мультитенантность через `ITenantEntity`/`IOptionalTenantEntity`, чисто (нет TODO/HACK). |
|
||
| **food-market.infrastructure** | ✅ готово | 90% | EF Core 8, query filters, MailKit SMTP, StockService, MoySkladClient, 34 миграции. |
|
||
| **food-market.api (контроллеры)** | ✅ готово | 85% | 27 контроллеров, ~120 endpoint'ов, OpenIddict (password + refresh), CRUD полный. |
|
||
| **food-market.application** | 🟡 частично | 60% | Только DTO + интерфейсы, нет MediatR handlers — вся логика в контроллерах. |
|
||
| **food-market.web (админка)** | ✅ готово | 95% | 35 страниц, темная тема, адаптив, RU-локаль, onBlur-валидация. |
|
||
| **food-market.public (сайт)** | ✅ готово | 90% | Astro 4: landing, тарифы, блог, KB, legal; SignupForm → API. |
|
||
| **food-market.shared (POS контракты)** | ❌ нет | 0% | Только .csproj, ни одного CS-файла. |
|
||
| **food-market.pos.core + food-market.pos** | ❌ скелет | 5% | Пустой WPF-проект, только зависимости в .csproj. |
|
||
| **POS Sync API** | ❌ нет | 0% | Нет `/api/pos/sync`, нет `/api/pos/sales bulk`, нет WebSocket. |
|
||
| **Documents: Supply / RetailSale** | ✅ готово | 100% | Полный цикл (Draft → Post → Unpost), Stock + Movement, Cost (скользящее среднее). |
|
||
| **Documents: Inventory / Loss / Enter / Transfer** | ❌ нет | 0% | Нет контроллеров и страниц. Domain-сущности тоже не определены. |
|
||
| **Documents: Demand (оптовая отгрузка)** | ❌ нет | 0% | Только enum `MovementType.WholesaleSale`, контроллера/сущности нет. |
|
||
| **Reports** | ❌ нет | 5% | Есть `/api/sales/retail/stats` для дашборда, отдельных отчётов нет. |
|
||
| **MoySklad интеграция** | 🟡 частично | 50% | Импорт товаров и контрагентов ✅; нет Demand/Payment sync, нет webhook'ов. |
|
||
| **OpenIddict auth** | ✅ готово | 100% | Password + refresh_token; org_id, role, sub claims; persistent dev-ключи. |
|
||
| **Multi-tenancy** | ✅ готово | 95% | Query filters + `HttpContextTenantContext`; SuperAdmin override read-only/edit. |
|
||
| **Permission-based authz (RolePermissions)** | 🟡 частично | 30% | 30+ флагов в БД, но контроллеры проверяют только Roles (Admin/Cashier и т.д.). |
|
||
| **SuperAdmin Console** | ✅ готово | 95% | Organizations CRUD, audit log, archive/restore, platform settings (SMTP); биллинг-KPI заглушка. |
|
||
| **Hangfire** | 🟡 частично | 40% | `ReferencePriceRefreshJob` ✅; нет dashboard, нет scheduled cleanup, нет retry. |
|
||
| **Email (SMTP)** | ✅ готово | 100% | MailKit, DataProtection-шифрование пароля, forgot-password flow. |
|
||
| **Платёжные интеграции (Kaspi/Halyk/Jusan)** | ❌ нет | 0% | Упомянуты только в маркетинге; есть `PaymentMethod` enum, реальных шлюзов нет. |
|
||
| **ОФД (фискализация чеков РК)** | ❌ нет | 0% | Поля `FiscalSerial`/`FiscalRegNumber` есть в RetailPoint, отправки чеков нет. |
|
||
| **Маркетплейсы (Ozon, Wildberries, Kaspi Magazin)** | ❌ нет | 0% | Только маркетинговые баннеры. |
|
||
| **CI/CD (Forgejo Actions)** | ✅ готово | 90% | docker-api/web/public + smoke-тест /health после деплоя; self-hosted runner. |
|
||
| **Docker / docker-compose (stage)** | ✅ готово | 95% | postgres:16 + api + web + public + persistent volumes + local registry. |
|
||
| **E2E тесты** | 🟡 частично | 40% | Один сценарий `full-cycle` (12 шагов), отчёт в md; нет регрессии и параллелизма. |
|
||
| **Backend unit/integration тесты** | ❌ нет | 0% | Совсем. В CI стоит `\|\| echo "No tests yet"`. |
|
||
| **Logging / Serilog** | ✅ готово | 90% | Console + File с ротацией 14 дней; нет structured fields для бизнес-событий. |
|
||
| **Health checks (детальные)** | 🟡 частично | 20% | Только `/health` → {status:ok}; нет проверки БД, SMTP, диска. |
|
||
| **Метрики / observability** | ❌ нет | 0% | Нет Prometheus/AppInsights/OpenTelemetry. |
|
||
| **Rate limiting** | 🟡 частично | 15% | Только в `forgot-password` (3/час/IP, in-memory). |
|
||
| **Backup БД** | 🟡 частично | 60% | `deploy/backup.sh` есть, но не привязан к cron/timer, restore-скрипта нет. |
|
||
|
||
### 1.2. Что точно работает (готово к продакшен-использованию)
|
||
|
||
- **Регистрация → онбординг → ежедневная работа магазина** (товары, цены, приёмки, розничные продажи, остатки).
|
||
- **Управление пользователями и ролями**, soft-delete, передача владельца, восстановление пароля по email.
|
||
- **SuperAdmin-консоль платформы** (создание/архивирование организаций, SMTP, аудит).
|
||
- **Импорт каталога из МойСклад** (товары + контрагенты, асинхронный job с прогрессом).
|
||
- **Полный stage-стенд** на docker-compose с локальным registry и автодеплоем через Forgejo Actions.
|
||
|
||
### 1.3. Где точно не получится запуститься без доработки
|
||
|
||
- **Невозможно работать с физическим магазином без ККМ-фискализации** (РК требует чеки в ОФД).
|
||
- **Невозможно вести полноценный складской учёт** — нет инвентаризации, оприходования, списания, перемещения.
|
||
- **Нет аналитики/отчётов** — только сводка на дашборде, ABC-анализа, отчёта по поставщикам/прибыли нет.
|
||
- **Нет POS-приложения** — главная ценность проекта (offline-касса на Windows) — пустой проект.
|
||
- **Нет защиты от перебора паролей** в основных endpoint'ах (login/signup), только в forgot-password.
|
||
|
||
---
|
||
|
||
## 2. ТЗ на доработку по приоритетам
|
||
|
||
### Приоритет P0 — блокеры запуска в продакшен
|
||
|
||
| # | Задача | Что сделать | Зачем |
|
||
|---:|---|---|---|
|
||
| P0-1 | **Production-сертификаты OpenIddict** | Заменить `App_Data/openiddict-dev-key.xml` на реальные RSA/X.509 сертификаты, читать из KeyVault или secrets. | Сейчас токены подписываются dev-ключом без шифрования access-token. В проде это утечка claims. |
|
||
| P0-2 | **HTTPS на nginx** | Настроить TLS-termination на reverse-proxy (Let's Encrypt через certbot), форсировать HTTPS-only, добавить HSTS. | OAuth/refresh_token нельзя гонять по HTTP. |
|
||
| P0-3 | **Rate limiting на login/signup** | Добавить `Microsoft.AspNetCore.RateLimiting` (sliding window) на `/connect/token`, `/api/auth/signup`. 5 попыток/минута/IP, 20/час/IP. | Перебор паролей и DOS публичного signup. |
|
||
| P0-4 | **Health check БД** | Расширить `/health` на `/health/live` (alive) + `/health/ready` (DB ping, миграции применены). Использовать `Microsoft.Extensions.Diagnostics.HealthChecks`. | Сейчас docker-compose `healthcheck` возвращает 200 даже когда БД упала — стейдж не падает корректно. |
|
||
| P0-5 | **Permission-based authorization** | В `RolePermissions` (Domain) уже 30+ флагов. Реализовать `PermissionHandler` (IAuthorizationHandler) + атрибут `[RequiresPermission("ProductsEdit")]`, проверять в контроллерах вместо `[Authorize(Roles=...)]`. | Без этого все Admin'ы организации имеют полные права, кастомные роли (Менеджер/Кладовщик/Кассир) — фикция. |
|
||
| P0-6 | **Автоматический backup БД** | Создать systemd-timer (`food-market-backup.timer`) на ежедневный запуск `deploy/backup.sh`, добавить restore-инструкцию в `docs/`. Хранить 30 дней локально + копия в S3/MinIO. | Сейчас бэкап делается вручную, восстановления не отрепетировали. |
|
||
| P0-7 | **ОФД фискализация РК** | Интегрировать одного оператора (например, Webkassa или ОФД-Соло, КГД РК), отправлять `RetailSale.Post` чек, сохранять QR-код и фискальный номер в `RetailSale.FiscalQrCode`/`FiscalNumber`. | В РК продажа без чека ОФД — административное правонарушение. Без этого нельзя продавать. |
|
||
| P0-8 | **.env.example + документация secrets** | Описать все required env-переменные (`ConnectionStrings__DefaultConnection`, `Cors__AllowedOrigins`, `Smtp__*`, `OpenIddict__Issuer`, `OFD__Token`). Обновить `docs/stage-setup.md`. | Сейчас новый деплой не задокументирован. Передача знаний из головы — узкое место. |
|
||
| P0-9 | **Чек-листы перед релизом** | Документ `docs/release-checklist.md`: миграции применены, бэкап свежий, smoke-тесты прошли, E2E full-cycle зелёный, мониторинг здоров. | Снижает риск выкатки в проде сломанной версии. |
|
||
|
||
### Приоритет P1 — важные функциональные пробелы
|
||
|
||
| # | Задача | Что сделать | Зачем |
|
||
|---:|---|---|---|
|
||
| P1-1 | **Документ «Оприходование» (Enter)** | Domain-сущность `Enter` + `EnterLine` (как Supply, но без поставщика). Контроллер CRUD + Post/Unpost. UI-страницы `/inventory/enters`. Создаёт `StockMovement` с типом `Enter`. | Нужно вводить начальные остатки и излишки инвентаризации без поставщика. |
|
||
| P1-2 | **Документ «Списание» (Loss)** | Domain-сущность `Loss` + `LossLine` (причина: брак, истечение срока, бой, недостача). Контроллер + UI. `StockMovement` тип `WriteOff`. | Списание брака — обязательная функция магазина. |
|
||
| P1-3 | **Документ «Перемещение» (Transfer)** | Domain `Transfer` + `TransferLine` (FromStore → ToStore). Контроллер с атомарной транзакцией (списание + поступление). UI-форма. | В сети магазинов товар постоянно перемещается между складами. |
|
||
| P1-4 | **Документ «Инвентаризация» (Inventory)** | Domain `Inventory` + `InventoryLine` (book qty, actual qty, diff). Контроллер с импортом текущих остатков + Post создаёт корректирующее движение `InventoryAdjustment`. UI-форма с CSV-импортом фактического количества. | Регулярная сверка остатков — обязательно для розницы. |
|
||
| P1-5 | **Документ «Оптовая отгрузка» (Demand)** | Domain `Demand` + `DemandLine` (покупатель, способ оплаты — наличные/безнал, цена опт.). Контроллер. UI-страницы. `StockMovement` тип `WholesaleSale`. | Часть клиентов работает с юрлицами, отгрузка по накладной с НДС. |
|
||
| P1-6 | **Возврат от покупателя (CustomerReturn)** | Расширить `RetailSale` опцией «Возврат» (по чеку или без). Domain enum `MovementType.CustomerReturn` уже есть. UI: кнопка «Создать возврат» из посту-проведённой продажи. | Закон о защите прав потребителей в РК требует приёма возвратов. |
|
||
| P1-7 | **Возврат поставщику (SupplierReturn)** | По аналогии с CustomerReturn для Supply. UI: «Возврат поставщику» из проведённой приёмки. | Брак, неликвид, отказ от партии. |
|
||
| P1-8 | **Отчёт «Продажи»** | `/api/reports/sales` с группировкой по периодам (день/неделя/месяц), товарам, кассирам, кассам, способам оплаты. UI: страница `/reports/sales` с фильтром периода и экспортом в CSV/XLSX. | Без отчёта по продажам управлять бизнесом невозможно. |
|
||
| P1-9 | **Отчёт «Остатки на дату»** | `/api/reports/stock` с восстановлением остатков на любую дату через `StockMovement` журнал. UI с экспортом. | Налоговый учёт, инвентаризация. |
|
||
| P1-10 | **Отчёт «Прибыль»** | `/api/reports/profit` — выручка - себестоимость по периодам/группам/товарам. Используем `Cost` snapshot из `RetailSaleLine`. | Главный показатель магазина. |
|
||
| P1-11 | **Отчёт «ABC-анализ»** | Топ товаров по выручке/прибыли/маржинальности за период. Группа A/B/C по правилу Парето. | Управление ассортиментом. |
|
||
| P1-12 | **POS Sync API** | Endpoints: `GET /api/pos/sync?since={ts}` (товары, цены, остатки, контрагенты с изменениями после ts); `POST /api/pos/sales` (батч продаж с idempotency-key). Контракты в `food-market.shared`. | Без этого POS-приложение не может синхронизироваться с сервером. |
|
||
| P1-13 | **POS WPF MVP** | Минимальный UI: логин кассира (привязка к RetailPoint), список товаров/поиск по штрихкоду, корзина, оплата (нал/карта), печать чека (с ОФД), оффлайн-буфер на SQLite, фоновая синхронизация. | Главная фича проекта по позиционированию. |
|
||
| P1-14 | **MoySklad — Demand sync** | Импорт оптовых отгрузок (демандов) из МойСклад. Расширить `MoySkladImportService`. | Текущая интеграция только односторонняя для каталога; продажи не синхронизируются. |
|
||
| P1-15 | **MoySklad — webhook на изменения** | Получать webhook'и от МойСклад при изменении товаров, автоматически обновлять каталог (вместо ручного «Импортировать сейчас»). | Двусторонняя живая синхронизация. |
|
||
| P1-16 | **Hangfire dashboard** | Подключить `Hangfire.Dashboard` с авторизацией только для SuperAdmin. Добавить scheduled jobs: ежедневный cleanup `StockMovement` (старше 2 лет), audit-log (старше 90 дней), eтиничные jobs (e.g. рассылка email). | Сейчас jobs запускаются только вручную через AdminCleanupController; нет видимости. |
|
||
| P1-17 | **Метрики Prometheus** | Подключить `prometheus-net.AspNetCore` (`/metrics` endpoint). Базовый набор: http_requests_total, http_request_duration, db_query_duration, business: sales_count, supply_posted_count, errors_total. | Без observability нельзя гнать прод. |
|
||
| P1-18 | **Аудит мутаций tenant'а** | Расширить `SuperAdminAuditLog` на обычные org-мутации (`OrgAuditLog`): кто, когда, что изменил в Supply/Sale/Product/Counterparty. Хранить diff JSON. | Розница часто судится с сотрудниками по поводу пропавших товаров — нужны доказательства. |
|
||
| P1-19 | **OpenAPI спецификация** | Включить `Swashbuckle.AspNetCore`. Опубликовать `/swagger/v1/swagger.json` (только в Dev) и сгенерировать TypeScript-клиент для food-market.web. | Удалит ручной труд по типизации API в фронте и POS. |
|
||
| P1-20 | **Unit-тесты критичной логики** | Покрыть xUnit'ом: `StockService.ApplyMovement`, расчёт Cost при `SuppliesController.Post`, расчёт автонаценки по `ProductGroup.MarkupPercent`, валидация платежа `RetailSalesController.Post`, multi-tenant query filter. | Без этих тестов любое изменение логики Supply/Sale = потенциально баг с минусовыми остатками или потерями денег. |
|
||
| P1-21 | **Integration-тесты на тестовой БД** | `Testcontainers.PostgreSql` + `WebApplicationFactory`. Покрыть: signup-flow, supply post→unpost, retail sale post с overselling, tenant isolation (org A vs org B), permission проверки. | Регрессия на каждый коммит в CI. |
|
||
| P1-22 | **Email-нотификации** | Готовый MailKit-сервис расширить шаблонами: приглашение сотрудника (с временным паролем), еженедельный отчёт владельцу, low-stock alert. Хранить шаблоны в `Resources/EmailTemplates/*.html`. | Сейчас email отправляется только при forgot-password. |
|
||
|
||
### Приоритет P2 — желательные улучшения
|
||
|
||
| # | Задача | Что сделать | Зачем |
|
||
|---:|---|---|---|
|
||
| P2-1 | **Платёжный шлюз Kaspi Pay** | Интеграция Kaspi Pay QR (касса показывает QR, покупатель оплачивает с приложения, callback фиксирует оплату в RetailSale). | Самый популярный способ безнала в РК. |
|
||
| P2-2 | **Платёжные шлюзы банков** | Halyk Epay, Jusan Pay, Forte Pay (POS-терминал API или e-commerce). | Альтернативы Kaspi. |
|
||
| P2-3 | **Интеграция с маркетплейсами** | Ozon Seller API, Wildberries, Kaspi Magazin — синхронизация остатков и цен (исходящая), импорт заказов (входящая). | Расширение каналов продаж. |
|
||
| P2-4 | **2FA для админов** | TOTP (Google Authenticator) для роли Admin и SuperAdmin. Использовать `Identity.AddDefaultTokenProviders` + `AuthenticatorTokenProvider`. | Защита платёжного функционала. |
|
||
| P2-5 | **SSO (Google/Microsoft)** | Расширить OpenIddict внешними провайдерами для логина персонала. | UX для офисных сотрудников. |
|
||
| P2-6 | **Многоязычность (en/kz)** | Подключить `react-i18next` в web, выделить русские строки в `locales/ru.json`. Перевести интерфейс на казахский (государственное требование). | Государство РК требует госязык в публичных интерфейсах. |
|
||
| P2-7 | **WebSocket / SignalR для real-time** | Push-уведомления на дашборд (новая продажа), кассе (изменение цены), импортах (вместо polling). | UX + снижение нагрузки от polling. |
|
||
| P2-8 | **Аналитика на public-сайте** | Google Analytics или Yandex.Metrika, A/B тесты pricing'а, события signup-конверсии. | Маркетинг. |
|
||
| P2-9 | **Mobile-приложение (PWA или React Native)** | Просмотр остатков, продаж, KPI для владельца. | UX для владельцев. |
|
||
| P2-10 | **Распознавание чеков (OCR)** | Загрузка фото чека от поставщика → распознавание → автозаполнение Supply. | Уменьшение ручного ввода. |
|
||
| P2-11 | **Электронные счёт-фактуры (ЭСФ)** | Интеграция с ИС ЭСФ КГД РК (выпуск счетов-фактур для юрлиц). | Часть оптовых клиентов требует ЭСФ. |
|
||
| P2-12 | **Бонусные программы / скидочные карты** | Domain: `LoyaltyProgram`, `LoyaltyCard`. Списание/начисление в RetailSale. | Удержание клиентов. |
|
||
| P2-13 | **Промокоды / акции** | Domain: `Promotion`, правила (категория, период, % скидки). UI-настройка из админки. | Маркетинг для магазина. |
|
||
| P2-14 | **Telegram-бот для владельца** | Ежедневная сводка выручки, low-stock alerts. | UX для владельцев. |
|
||
| P2-15 | **Multi-storage для изображений** | Сейчас файлы лежат в `/app/uploads` (volume). Перевести на S3-совместимое хранилище (MinIO/Yandex.Cloud). | Масштабируемость, отказоустойчивость. |
|
||
|
||
---
|
||
|
||
## 3. Дорожная карта (рекомендованная последовательность)
|
||
|
||
### Спринт 1 — Стабилизация (2-3 недели)
|
||
|
||
Цель: безопасно выкатить текущий функционал в прод.
|
||
|
||
- P0-1 → P0-9 (все блокеры запуска)
|
||
- P1-20, P1-21 (юнит/интеграционные тесты на текущую логику)
|
||
- P1-18 (аудит мутаций tenant'а)
|
||
|
||
**Критерий готовности:** прод-стенд работает с HTTPS, rate-limit'ы установлены, бэкап автоматический, фискализация ОФД работает, права RolePermissions проверяются.
|
||
|
||
### Спринт 2 — Складской учёт (3-4 недели)
|
||
|
||
Цель: полноценное складское ядро ERP.
|
||
|
||
- P1-1 (Enter), P1-2 (Loss), P1-3 (Transfer), P1-4 (Inventory)
|
||
- P1-6 (CustomerReturn), P1-7 (SupplierReturn)
|
||
- P1-16 (Hangfire dashboard + scheduled cleanup)
|
||
|
||
**Критерий готовности:** магазин может вести полный складской учёт без обходных путей.
|
||
|
||
### Спринт 3 — Отчёты и аналитика (2 недели)
|
||
|
||
- P1-8 (Sales report), P1-9 (Stock on date), P1-10 (Profit), P1-11 (ABC)
|
||
- P1-19 (OpenAPI / Swagger)
|
||
|
||
**Критерий готовности:** владелец видит, как идёт бизнес, без выгрузки в Excel.
|
||
|
||
### Спринт 4 — POS (4-6 недель)
|
||
|
||
- P1-12 (POS Sync API), `food-market.shared` контракты
|
||
- P1-13 (POS WPF MVP)
|
||
- P1-17 (метрики Prometheus + Grafana dashboard)
|
||
|
||
**Критерий готовности:** касса работает оффлайн, синхронизируется с сервером, печатает фискальные чеки.
|
||
|
||
### Спринт 5 — Оптовые продажи + MoySklad full sync (2-3 недели)
|
||
|
||
- P1-5 (Demand)
|
||
- P1-14 (MoySklad Demand sync), P1-15 (webhook'и)
|
||
- P1-22 (email-шаблоны)
|
||
|
||
**Критерий готовности:** клиент, работающий с юрлицами через МойСклад, может полностью перейти на Food Market.
|
||
|
||
### Спринт 6+ — Интеграции и фичи (P2)
|
||
|
||
P2-1 Kaspi Pay → P2-3 маркетплейсы → P2-6 локализация → P2-11 ЭСФ → P2-12/13 лояльность/акции.
|
||
|
||
---
|
||
|
||
## 4. Технический долг (для рефакторинга)
|
||
|
||
Не блокирует функциональность, но затрудняет развитие.
|
||
|
||
| # | Что | Почему важно |
|
||
|---:|---|---|
|
||
| TD-1 | **CQRS через MediatR** — перенести бизнес-логику из контроллеров в Command/Query handlers. | Сейчас невозможно переиспользовать логику между API/POS/Hangfire. Контроллеры по 500 строк. |
|
||
| TD-2 | **FluentValidation** — заменить inline-валидацию в контроллерах на отдельные `Validator<T>`. | Сейчас валидация перемешана с бизнес-логикой, тестировать сложно. |
|
||
| TD-3 | **Mapster** — выделить mapping в отдельные `MapperConfig`. | Сейчас projection'ы инлайнятся в LINQ-запросы, переиспользования нет. |
|
||
| TD-4 | **Структурные log-fields в Serilog** — добавить `org_id`, `user_id`, `correlation_id` в log scope. | Сейчас в логах сложно найти конкретного пользователя/организацию. |
|
||
| TD-5 | **ImportJobRegistry в БД** — сейчас in-memory `ConcurrentDictionary`. При рестарте API теряется. Перевести на таблицу `ImportJobs`. | Жизненный цикл job'а >5 минут — рестарт обычное дело. |
|
||
| TD-6 | **Concurrency-токены на документах** — `RowVersion` (xmin/timestamp) на Supply/RetailSale, чтобы исключить race condition при параллельной правке. | Сейчас два кассира могут испортить один чек. |
|
||
|
||
---
|
||
|
||
## 5. Сводка по оценке готовности
|
||
|
||
```
|
||
┌──────────────────────────────────┬──────────────┬─────────────┐
|
||
│ Категория │ Готовность │ Состояние │
|
||
├──────────────────────────────────┼──────────────┼─────────────┤
|
||
│ Авторизация и multi-tenancy │ 95% │ ✅ готово │
|
||
│ Каталог товаров │ 95% │ ✅ готово │
|
||
│ Документы (Supply, RetailSale) │ 100% │ ✅ готово │
|
||
│ Документы (Inventory/Loss/...) │ 0% │ ❌ нет │
|
||
│ Отчёты │ 5% │ ❌ нет │
|
||
│ POS │ 5% │ ❌ нет │
|
||
│ MoySklad │ 50% │ 🟡 частично │
|
||
│ Платежи и фискализация │ 0% │ ❌ нет │
|
||
│ Инфраструктура (CI/CD, Docker) │ 90% │ ✅ готово │
|
||
│ Безопасность (HTTPS, rate-limit) │ 30% │ 🟡 частично │
|
||
│ Observability (метрики, аудит) │ 20% │ 🟡 частично │
|
||
│ Тестирование │ 40% │ 🟡 частично │
|
||
└──────────────────────────────────┴──────────────┴─────────────┘
|
||
|
||
Общая готовность к продакшен-запуску: 60-65%
|
||
- Для MVP "магазин на одном POS-терминале": требуется ОФД + базовые складские документы.
|
||
- Для полноценного ERP: требуется выполнение P0+P1.
|
||
- Для конкуренции с МойСклад: требуется ещё и P2.
|
||
```
|