food-market/README.md
nns 019c57ae3b
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
feat(s25): autonomous continuous quality monitoring (8/8)
Hourly smoke watchdog + auto-fix loop + dashboard + multi-tenant guard
+ perf regression + cleanup job + README badge.

1. ~/quality-watchdog.sh (cron 5 * * * *) — 8 checks (~60s):
   /health/ready, signup→login→/api/me, GET products, Playwright UI
   smoke (3.1 product CRUD), /metrics format, /hubs/notifications
   negotiate with token, multi-tenant isolation, perf p95.
2. Auto-fix loop: 2× consecutive red → ~/.fm-watchdog/incident-*.txt
   + queue/0000-incident-* to bump it ahead of Server-Claude's
   sprint queue. fm-watchdog.sh sees prefix 0000- as next.
3. scripts/quality-dashboard.py — renders docs/quality-status.md
   (current emoji, 8-step table, perf baseline, 7-day history,
   24-run sparkline) + injects README badge 🟢/🟡/🔴.
4. Multi-tenant smoke: signup 2 orgs `quality-{epoch}-A/B`, create
   product in A, verify B sees 404/403 + total=0.
5. Perf regression: p95 over 10 reqs for /api/me, products,
   sales/retail/stats. Baseline = median of last 10 samples
   (robust to noise). >50% from baseline → alert. First 5 runs
   always green (warm-up).
6. HousekeepingJobs.PruneQualityTestOrgsAsync (cron 30 2 * * * UTC):
   finds orgs `quality-%` older than 24h, dynamically scans
   information_schema for tables with OrganizationId, iteratively
   DELETEs with FK-violation retry (up to 10 passes), then cleans
   AspNetUser*/OpenIddict* by email pattern `quality-%@test-fm.local`,
   finally users + organizations.
7. README badge: <!-- quality-badge --> marker updated each run.

Validated: stage deploy ✓, Hangfire job registered ✓, dry-run SQL on
24 stage candidates → 0 remaining ✓, 3 cron-triggered runs all 8/8
green (12:42/12:45/12:48 +05) ✓.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 12:50:35 +05:00

129 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# food-market
<!-- quality-badge --> 🟢 **Quality:** [`docs/quality-status.md`](docs/quality-status.md) <!-- /quality-badge -->
[![CI](http://192.168.1.193:3000/nns/food-market/actions/workflows/ci.yml/badge.svg)](http://192.168.1.193:3000/nns/food-market/actions)
[![Docker API](http://192.168.1.193:3000/nns/food-market/actions/workflows/docker-api.yml/badge.svg)](http://192.168.1.193:3000/nns/food-market/actions)
[![Stage verify](http://192.168.1.193:3000/nns/food-market/actions/workflows/stage-verify.yml/badge.svg)](http://192.168.1.193:3000/nns/food-market/actions)
[![Regression](http://192.168.1.193:3000/nns/food-market/actions/workflows/regression.yml/badge.svg)](http://192.168.1.193:3000/nns/food-market/actions)
![coverage](./badges/coverage.svg)
Аналог системы МойСклад для розничной торговли в Казахстане. Multi-tenant
SaaS + web-админка + Windows-касса. Поддерживает 8 типов документов учёта,
ОФД-интеграцию (scaffolding), кассу на POS WPF с offline-буфером, отчёты,
loyalty-programs, MoySklad-импорт, GDPR-export.
## Состав
| Часть | Технологии | Точка входа |
|---|---|---|
| **API** | .NET 8 LTS, ASP.NET Core, EF Core 8, PostgreSQL 16, OpenIddict 5 | `src/food-market.api` → http://localhost:5081 |
| **Web-админка** | React 19, Vite, TypeScript, Tailwind v4, TanStack Query, AG Grid | `src/food-market.web` → http://localhost:5173 |
| **Public marketing** | Astro 5, TypeScript, Tailwind | `src/food-market.public` → http://localhost:4321 |
| **POS-касса** | WPF .NET 8 Windows, SQLite, Refit+Polly, COM-весы | `src/food-market.pos` (сборка кроссплатформенно, UI — Windows) |
## 5-минутный quick start
```bash
git clone http://192.168.1.193:3000/nns/food-market.git
cd food-market
# БД (Postgres 14+ должен быть запущен, default user)
createdb -U $USER food_market
# Backend (миграции применятся на старте; Swagger на /swagger)
ASPNETCORE_ENVIRONMENT=Development dotnet run --project src/food-market.api &
# Web SPA
cd src/food-market.web && pnpm install && pnpm dev &
# Зарегистрироваться + получить токен
curl -X POST http://localhost:5081/api/auth/signup \
-H "Content-Type: application/json" \
-d '{"organizationName":"Dev","email":"dev@local.test","password":"DevPass1!","phone":"+77001234567"}'
curl -X POST http://localhost:5081/connect/token \
-d 'grant_type=password&username=dev@local.test&password=DevPass1!&client_id=food-market-web&scope=openid profile email roles api offline_access'
# Открыть http://localhost:5173 → залогиниться dev@local.test / DevPass1!
```
Подробнее — [`docs/ONBOARDING.md`](docs/ONBOARDING.md).
## Где что лежит
```
food-market/
├── src/
│ ├── food-market.domain/ # POCO + enum'ы + interfaces. Без EF / ASP.NET.
│ ├── food-market.application/ # DTO, FluentValidation, MediatR-handler'ы, Mapster.
│ ├── food-market.infrastructure/ # EF Core, миграции, Identity, OpenIddict storage.
│ ├── food-market.api/ # Controllers (60), middleware, Hangfire jobs (10 recurring), OpenIddict server.
│ ├── food-market.web/ # React 19 SPA админки.
│ ├── food-market.public/ # Astro marketing-сайт.
│ ├── food-market.shared/ # DTO-контракты сервер↔POS.
│ ├── food-market.pos.core/ # POS-логика (UI-agnostic).
│ └── food-market.pos/ # WPF (.NET 8 Windows).
├── tests/
│ ├── food-market.UnitTests/ # xUnit + InMemory EF.
│ ├── food-market.IntegrationTests/# xUnit + Testcontainers Postgres.
│ ├── e2e/ # Playwright + ad-hoc Python smoke.
│ └── load/ # k6 (нагрузочные).
├── deploy/ # Dockerfile.{api,web,public}, compose, nginx, prod-toolchain.
├── docs/ # 50+ markdown файлов.
└── food-market.sln
```
## Ключевая документация
- **[ARCHITECTURE.md](docs/ARCHITECTURE.md)** — общая картина: слои, deployment, что реализовано / scaffolding / не реализовано.
- **[ONBOARDING.md](docs/ONBOARDING.md)** — first 3 days для нового разработчика.
- **[glossary.md](docs/glossary.md)** — все доменные термины с ссылками на код.
- **[MULTI-TENANCY.md](docs/MULTI-TENANCY.md)** — как изолируются org'и.
- **[api-reference.md](docs/api-reference.md)** — auto-generated список всех 195 endpoint'ов.
- **[error-codes.md](docs/error-codes.md)** — каталог HTTP-кодов для humanizeError на фронте.
- **[secrets.md](docs/secrets.md)** — env-vars + где хранятся секреты.
- **[RUNBOOK.md](docs/RUNBOOK.md)** — операционные процедуры (что делать при инциденте).
- **[performance-baseline.md](docs/performance-baseline.md)** — k6 цифры + bottleneck'и.
## Мультитенантность
Один процесс API обслуживает много организаций. Каждая видит только свои
данные через EF Core query-filter по `OrganizationId`. `SuperAdmin` роль
видит всё. См. [MULTI-TENANCY.md](docs/MULTI-TENANCY.md).
## Деплой
- **Stage**: `https://test.admin.food-market.kz`. Деплой одной командой:
```bash
~/deploy-stage.sh # docker build api+web → push в local registry → ssh prod-vm → compose up -d
```
- **Prod**: `https://admin.food-market.kz`. Toolchain готов (Sprint 21):
```bash
deploy/check-prod-readiness.sh # backup+disk+health+env
deploy/prod-deploy.sh <api-tag> <web-tag> # blue-green
deploy/prod-rollback.sh <to-tag> # быстрый откат
deploy/post-deploy-smoke.sh # 10 шагов smoke + Telegram alert
```
Реальный prod-сервер пока не настроен (DNS / certbot / nginx upstream).
## Sprint-история (что было сделано)
Хронология в `docs/sprintNN-progress.md`. По состоянию на Sprint 24:
- **1-7** — фундамент: auth (OpenIddict), multi-tenancy, каталог, документы, кассы.
- **8-10** — отчёты, dashboard, dark mode + Cmd+K.
- **11** — ОФД scaffolding (Webkassa / Kassa24 / ОФД-Соло).
- **12-13** — документация / runbook / k6, security headers + rate-limits.
- **14-15** — performance (bundle 51%, индексы, N+1 fix), a11y (WCAG-AA).
- **16-17** — regression suite (44 Playwright specs), onboarding wizard + help.
- **18** — TODO cleanup (P0 race, audit filters, notification center).
- **19** — power UX (bulk-update, presets, Cmd+J, inline-edit, CSV import/export, keyboard nav).
- **20** — Mapster + SSO scaffold + maintenance jobs (cleanup, VACUUM, disk-monitor, perf-regression).
- **21** — stage→prod toolchain (7 deploy-скриптов + auto-tag).
- **22** — data tooling: GDPR-export, 1C-CSV import, anonymize-prod, DB-schema docs, audit export streaming.
- **23** — adversarial bug-hunt (4 bugs found + 4 fixed, includes CRITICAL 40001→500 fix).
- **24** — docs cross-check + auto-generated API reference + ONBOARDING + integration-test gap-fill.
## Лицензия
Internal proprietary, не для публикации без разрешения владельца.