food-market/CLAUDE.md
nns fd2f5ae4f3 Phase 0: project scaffolding and end-to-end auth
- .NET 8 LTS solution with 7 projects (domain/application/infrastructure/api/shared/pos.core/pos[WPF])
- Central package management (Directory.Packages.props), .editorconfig, global.json pin to 8.0.417
- PostgreSQL 14 dev DB via existing brew service; food_market database created
- ASP.NET Identity + OpenIddict 5 (password + refresh token flows) with ephemeral dev keys
- EF Core 8 + Npgsql; multi-tenant query filter via reflection over ITenantEntity
- Initial migration: 13 tables (Identity + OpenIddict + organizations)
- AuthorizationController implements /connect/token; seeders create demo org + admin
- Protected /api/me endpoint returns current user + org claims
- React 19 + Vite 8 + Tailwind v4 SPA with TanStack Query, React Router 7
- Login flow with dev-admin placeholder, bearer interceptor + refresh token fallback
- docs/architecture.md, CLAUDE.md, README.md

Verified end-to-end: health check, password grant issues JWT with org_id,
web app builds successfully (310 kB gzipped).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 13:59:13 +05:00

5.6 KiB
Raw Blame History

food-market — project guide for Claude

Аналог системы МойСклад для розничной торговли в Казахстане. Multi-tenant сервер + web-админка + Windows-касса.

Naming

  • Брендинг lowercase везде: папки, файлы, csproj, docker-образы, репо → food-market, food-market.api.
  • C# namespacesfoodmarket.Api, foodmarket.Domain, foodmarket.Infrastructure и т.д. (C# не допускает дефис, поэтому foodmarket одним словом).
  • Отображаемое имя в UI — "Food Market" или "food-market" в техн. контекстах.

Стек

Слой Технология
Backend .NET 8 LTS, ASP.NET Core, EF Core 8, PostgreSQL 14+
Auth OpenIddict 5 (password + refresh), ASP.NET Identity
Backend libs MediatR, FluentValidation, Mapster (НЕ AutoMapper — тот стал платным + CVE), Serilog, Hangfire, SignalR
Web React 19 + Vite + TypeScript 6, Tailwind CSS v4, shadcn/ui, TanStack Query, TanStack Table, AG Grid Community, react-hook-form + Zod
POS WPF на .NET 8 (Windows 10+), CommunityToolkit.Mvvm, SQLite, Refit + Polly, System.IO.Ports для весов

Запрет на платные компоненты: никаких Kendo UI, DevExpress, Syncfusion commercial, Telerik в новом коде. Если задача требует такой компонент — сначала спросить.

Структура

food-market/
├── src/
│   ├── food-market.domain/          # чистые POCO, enum'ы, доменные события (никакого ASP.NET, EF)
│   ├── food-market.application/     # MediatR handlers, DTO, FluentValidation, интерфейсы
│   ├── food-market.infrastructure/  # EF Core, Identity, OpenIddict EF store, внешние сервисы
│   ├── food-market.api/             # ASP.NET Core, контроллеры, OpenIddict server
│   ├── food-market.web/             # React + Vite SPA
│   ├── food-market.shared/          # DTO-контракты сервер ↔ POS
│   ├── food-market.pos.core/        # логика POS (независима от UI)
│   └── food-market.pos/             # WPF (net8.0-windows, сборка возможна на macOS)
├── tests/
├── deploy/
│   └── docker-compose.yml           # Postgres 16 для прод/Linux
├── docs/
└── food-market.sln

Мультитенантность (важно)

Каждая доменная сущность реализует ITenantEntity (есть OrganizationId). AppDbContext применяет query filter автоматически через reflection — запросы видят только данные своей организации. SuperAdmin роль видит всё.

Tenant определяется из JWT claim org_id, который выдаётся при логине. См. HttpContextTenantContext в api.

При создании новой сущности:

  1. Если данные относятся к магазину — наследовать от TenantEntity.
  2. Если общие справочники (единицы измерения, страны) — от Entity.
  3. Справочник организаций (Organization) — от Entity (сама по себе не tenant-scoped).

БД для dev

Используется существующий postgres@14 из brew (порт 5432). БД food_market, owner nns, пароль пустой.

Connection string в appsettings.Development.json. Для прода/Linux будет postgres@16 через deploy/docker-compose.yml (порт 5433 чтобы не конфликтовать).

НЕ переключать systemwide postgres версию — это сломает смежные проекты (calcman, purchase, makesales, food-market-server).

Миграции EF Core

# Создать миграцию
dotnet ef migrations add <Name> \
  --project src/food-market.infrastructure \
  --startup-project src/food-market.api \
  --output-dir Persistence/Migrations

# Применить
dotnet ef database update \
  --project src/food-market.infrastructure \
  --startup-project src/food-market.api

Запуск dev

# API (http://localhost:5081)
ASPNETCORE_ENVIRONMENT=Development dotnet run --project src/food-market.api

# Web (http://localhost:5173)
cd src/food-market.web && pnpm dev

# Проверить здоровье
curl http://localhost:5081/health

# Получить токен (dev admin)
curl -X POST http://localhost:5081/connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password&username=admin@food-market.local&password=Admin12345!&client_id=food-market-web&scope=openid profile email roles api"

Соседние проекты (НЕ ломать)

В ~/Documents/devprojects/ есть: food-market-server, food-market-app, calcman, purchase, makesales. Любые изменения глобальных инструментов (nvm default, postgres CLI версия, .NET SDK) — только с подтверждения пользователя.

Источник правды по функциональности

МойСклад API: https://dev.moysklad.ru/doc/api/remap/1.2/. Перед моделированием новых сущностей в Phase 1+ — подтягивать актуальные разделы через WebFetch для соответствия их логике.