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
1. Docs cross-check — обновил performance-baseline.md (Sprint 18/20/23 фиксы), secrets.md (16 новых env-vars из Sprint 20+ — Authentication Google/Microsoft, Monitoring, Cleanup, Hangfire:Cron, Telegram, Maintenance, App, Storage, PUBLIC_GA_ID/YM_ID). 2. Auto-gen api-reference — ApiReferenceDocsJob (Hangfire weekly вс 05:30 UTC) + Python-эквивалент `/tmp/gen-api-ref.py` для commit actual snapshot. docs/api-reference.md = 195 endpoints, 57 controllers. 3. Coverage gap-fill — Sprint18To23FeaturesTests.cs (16 Facts): - bulk-update + cross-tenant isolation - UserPresets CRUD - inline-edit price PATCH - CSV import 2 строки транзакцией - OrgExport create + list isolation - 1C-CSV import с русскими заголовками - audit-log export CSV streaming + BOM check - MoySklad sync-status stub - SSO providers + 503 unconfigured + 400 unknown provider - bug-001 NUL byte → 400 - bug-004 tiny price → 400 - export CSV BOM Покрывает все новые контроллеры Sprint 18-23 + regression-protect для критичных багов. 4. Contract tests — deploy/swagger-diff.sh: pull /swagger/v1/swagger.json с двух URL, diff endpoints+schemas через python3. Exit 0/1/2 для blue-green safety gate. Multi-path auto-detect. 5. docs/error-codes.md — каталог HTTP-кодов API (200-503) + humanizeError pattern для фронта + retry-policy таблица. 6. docs/glossary.md — 50+ доменных терминов (Tenant/Organization/Stock/ StockMovement/RetailSale/Counterparty/Owner/Employee/Role/Permission/ advisory lock/Serializable/…) с ссылками на code-сущности. 7. docs/ONBOARDING.md — first 3 days для нового разработчика (install → запуск → структура → первый PR + FAQ). 8. README.md — обновил под текущее состояние: React 19, Sprint-history 1-24, ссылки на ключевые docs, корректный 5-min quick start. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
264 lines
13 KiB
Markdown
264 lines
13 KiB
Markdown
# Onboarding для нового разработчика food-market
|
||
|
||
Этот документ — путь от «клонировал репо» до «открыл первый PR» за 3 дня.
|
||
Если что-то не сходится с реальностью — это **баг документации**,
|
||
отредактируй и оставь PR.
|
||
|
||
## День 1 — установка и первый запуск
|
||
|
||
### Что нужно
|
||
|
||
- macOS / Linux. Windows только для POS WPF (см. отдельно ниже).
|
||
- .NET 8 SDK (точная версия из `global.json` — `dotnet --list-sdks`
|
||
должен показывать её; если нет — `winget install Microsoft.DotNet.SDK.8`
|
||
/ `brew install dotnet@8`).
|
||
- Node.js 20+ (`nvm install 20 && nvm use 20`).
|
||
- pnpm 9+ (`npm i -g pnpm`).
|
||
- PostgreSQL 14+ (на macOS: `brew install postgresql@14 && brew services start postgresql@14`).
|
||
- git, curl, python3 (для скриптов в `tests/e2e/`).
|
||
- Docker для интеграционных тестов (Testcontainers) и stage-deploy.
|
||
|
||
### Установка проекта
|
||
|
||
```bash
|
||
git clone http://192.168.1.193:3000/nns/food-market.git
|
||
cd food-market
|
||
|
||
# БД для dev — пустая, инициируется миграциями автоматически.
|
||
createdb -U $USER food_market
|
||
|
||
# Backend
|
||
dotnet restore
|
||
dotnet build food-market.sln -c Debug --nologo
|
||
|
||
# Web frontend
|
||
cd src/food-market.web && pnpm install && cd ../..
|
||
```
|
||
|
||
### Запуск
|
||
|
||
```bash
|
||
# Терминал 1: API
|
||
ASPNETCORE_ENVIRONMENT=Development dotnet run --project src/food-market.api
|
||
# → http://localhost:5081, Swagger на /swagger
|
||
|
||
# Терминал 2: Web SPA
|
||
cd src/food-market.web && pnpm dev
|
||
# → http://localhost:5173
|
||
```
|
||
|
||
### Проверка что работает
|
||
|
||
```bash
|
||
# Health
|
||
curl http://localhost:5081/health/ready
|
||
|
||
# Зарегистрируйся
|
||
curl -X POST http://localhost:5081/api/auth/signup \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"organizationName":"DevOrg","email":"dev@local.test","password":"DevPass123!","phone":"+77001234567"}'
|
||
|
||
# Логин и получи токен
|
||
TOKEN=$(curl -sX POST http://localhost:5081/connect/token \
|
||
-d 'grant_type=password&username=dev@local.test&password=DevPass123!&client_id=food-market-web&scope=openid profile email roles api offline_access' \
|
||
| python3 -c 'import sys,json;print(json.load(sys.stdin)["access_token"])')
|
||
|
||
# Что я могу
|
||
curl -sH "Authorization: Bearer $TOKEN" http://localhost:5081/api/me | python3 -m json.tool
|
||
```
|
||
|
||
### Тесты
|
||
|
||
```bash
|
||
# Unit
|
||
dotnet test tests/food-market.UnitTests --nologo
|
||
|
||
# Integration (нужен Docker — Testcontainers поднимает Postgres-контейнер)
|
||
dotnet test tests/food-market.IntegrationTests --nologo
|
||
|
||
# E2E (Playwright против локального API)
|
||
cd tests/e2e
|
||
E2E_ADMIN_URL=http://localhost:5081 ./run.sh stage-smoke
|
||
```
|
||
|
||
## День 2 — где что лежит
|
||
|
||
### Структура (укрупнённо)
|
||
|
||
```
|
||
food-market/
|
||
├── src/
|
||
│ ├── food-market.domain/ — POCO + enum'ы + интерфейсы. Без EF, без ASP.NET.
|
||
│ ├── food-market.application/ — DTO, FluentValidation, MediatR-handler'ы, Mapster config.
|
||
│ ├── food-market.infrastructure/ — EF Core, миграции, Identity, OpenIddict storage.
|
||
│ ├── food-market.api/ — Controllers, middleware, Hangfire jobs, OpenIddict server.
|
||
│ ├── food-market.web/ — React 19 + Vite SPA админки (admin.food-market.kz).
|
||
│ ├── food-market.public/ — Astro marketing-сайт (food-market.kz).
|
||
│ ├── food-market.shared/ — DTO-контракты сервер↔POS.
|
||
│ ├── food-market.pos.core/ — POS-логика (UI-agnostic).
|
||
│ └── food-market.pos/ — WPF (net8.0-windows; собирается на любой OS).
|
||
├── tests/
|
||
│ ├── food-market.UnitTests/ — xUnit + InMemory EF (быстрые юниты).
|
||
│ ├── food-market.IntegrationTests/— xUnit + Testcontainers Postgres (через WebApplicationFactory).
|
||
│ ├── e2e/ — Playwright (TS) + ad-hoc Python smoke-скрипты.
|
||
│ └── load/ — k6 (нагрузочные).
|
||
├── deploy/ — Dockerfile.{api,web,public}, compose, nginx, скрипты (prod-deploy/rollback/smoke/anonymize/swagger-diff).
|
||
├── docs/ — markdown (этот файл — `ONBOARDING.md`, плюс ARCHITECTURE/RUNBOOK/etc).
|
||
└── food-market.sln
|
||
```
|
||
|
||
### Что почитать в первую очередь
|
||
|
||
Порядок имеет значение — от general к specific:
|
||
|
||
1. **[ARCHITECTURE.md](ARCHITECTURE.md)** — общая картина: слои, deployment-топология, ключевые потоки, что реализовано / scaffolding / не реализовано (после 22 спринтов).
|
||
2. **[glossary.md](glossary.md)** — все доменные термины (Tenant / Organization / Stock / RetailSale / …) с ссылками на классы.
|
||
3. **[MULTI-TENANCY.md](MULTI-TENANCY.md)** — query-filter, SuperAdmin override, как не утечь cross-org.
|
||
4. **[DEVELOPER-GUIDE.md](DEVELOPER-GUIDE.md)** — паттерны (CQRS-like, MediatR, валидаторы, Mapster), стиль кода, как добавлять новые endpoint'ы.
|
||
5. **[api-reference.md](api-reference.md)** — auto-generated список всех 190+ endpoint'ов (обновляется weekly через Hangfire).
|
||
6. **[error-codes.md](error-codes.md)** — каталог HTTP-кодов для humanizeError на фронте.
|
||
7. **[secrets.md](secrets.md)** — env-vars + где хранятся секреты.
|
||
8. **[observability.md](observability.md)** — Prometheus метрики, Serilog, /health.
|
||
9. **[RUNBOOK.md](RUNBOOK.md)** — как разруливать инциденты («api не стартует», «остатки разъехались», и т.п.).
|
||
10. **[performance-baseline.md](performance-baseline.md)** — k6 baseline + что НЕ масштабируется.
|
||
|
||
### Sprint-history
|
||
|
||
Хронология фич: `docs/sprint1-progress.md` … `docs/sprint24-progress.md`.
|
||
Каждый — что было сделано + цифры. Полезно когда видишь странное имя
|
||
файла и хочешь понять «когда и зачем».
|
||
|
||
### Тестовый стенд
|
||
|
||
- **Stage**: `https://test.admin.food-market.kz` — `~/deploy-stage.sh` собирает образ и катит. Подробности в [stage-access.md](stage-access.md).
|
||
- **Prod**: `https://admin.food-market.kz` — НЕ деплоится автоматически (Sprint 21 toolchain готов, см. `deploy/prod-deploy.sh`, но реальный сервер не настроен).
|
||
|
||
### Git workflow
|
||
|
||
- Origin — Forgejo на `http://192.168.1.193:3000/nns/food-market.git`.
|
||
GitHub — mirror.
|
||
- Никаких force-push'ей в main (после первого тэга).
|
||
- Branch для серьёзных фич: `feat/<sprint>-<short-name>`, в Pull Request →
|
||
Squash & Merge.
|
||
- Каждый коммит на собственной фиче — `feat(scope): subject` (см.
|
||
`git log --oneline` для примеров).
|
||
|
||
## День 3 — первый PR
|
||
|
||
### Найти первую задачу
|
||
|
||
- `grep -rn "TODO\|FIXME" src/` — около 30 живых TODO. Самые маленькие
|
||
обычно UX-полировка (i18n, copy, validation message).
|
||
- `docs/sprintNN-progress.md` последнего спринта → раздел «Открытые TODO».
|
||
- В Forgejo Issues (если есть): bug-001..004 в `tests/e2e/reports/bugs/`
|
||
— некоторые фиксы уже сделаны, остаются follow-up'ы.
|
||
- Слабый шаг: посмотри `docs/performance-baseline.md` раздел «Сводка:
|
||
что нужно поправить» — там список задач со статусом ✅/⚠️/❌.
|
||
|
||
### Что сделать перед PR
|
||
|
||
1. `git fetch origin && git rebase origin/main` (memory: `feedback_serialize_edits` —
|
||
мы один-коммитящий-за-раз; не делай параллельных правок).
|
||
2. `dotnet build` + `dotnet test` (unit + integration) — должны быть зелёные.
|
||
3. `pnpm -C src/food-market.web exec tsc --noEmit` — TS clean.
|
||
4. Локальный smoke если правил controller'ы: запусти API + `curl` на затронутый
|
||
endpoint.
|
||
5. Для UI: открой `/login` локально, проверь что страница работает.
|
||
|
||
### Шаблон PR-сообщения
|
||
|
||
```
|
||
<тип>(scope): краткое описание
|
||
|
||
Что: …
|
||
Зачем: …
|
||
Как тестировал: …
|
||
Связанные issue/sprint: …
|
||
|
||
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> (если работал в паре с Claude)
|
||
```
|
||
|
||
### Кодстайл
|
||
|
||
- **C#**: дефолтный .NET-стиль. Один файл — один класс. Async/await везде
|
||
где I/O. EF-проекции через `.ProjectToType<TDto>(MapsterConfig.Config)`
|
||
для новых endpoint'ов (Sprint 20+).
|
||
- **TS**: prettier+eslint конфиг в `src/food-market.web`. Hooks naming
|
||
`useFoo`. Server-state — TanStack Query, не useState.
|
||
- **CSS**: только Tailwind utility-classes. Никаких inline styles.
|
||
- **Комментарии**: только если объясняют **почему**, не **что**. Если
|
||
переписал паттерн — оставь reference на `[memory:feedback_serialize_edits]`
|
||
или sprint-doc.
|
||
|
||
## FAQ
|
||
|
||
### Q: API не стартует, ругается на global.json
|
||
|
||
`dotnet --list-sdks` должен содержать ровно ту версию что в `global.json`
|
||
(8.0.417). Если нет — установи SDK. **НЕ редактируй global.json** — это
|
||
сломает CI и другие dev-машины.
|
||
|
||
### Q: Integration-тесты падают с "Cannot find docker daemon"
|
||
|
||
Включи Docker Desktop / `sudo systemctl start docker`. Testcontainers
|
||
тащит `postgres:16-alpine` (один раз, потом из кеша).
|
||
|
||
### Q: Web стартует но не видит API
|
||
|
||
Проверь что `src/food-market.web/vite.config.ts` proxy указывает на
|
||
`http://localhost:5081`. Если порт API изменился — обнови.
|
||
|
||
### Q: Сертификат OpenIddict не создаётся
|
||
|
||
Dev-режим: `App_Data/` должен быть writable. Прод: см.
|
||
[openiddict-keys.md](openiddict-keys.md).
|
||
|
||
### Q: Как добавить новую сущность
|
||
|
||
Шаги (псевдо-flow):
|
||
1. POCO в `src/food-market.domain/<Area>/MyEntity.cs` (от `TenantEntity` если связана с org'ой).
|
||
2. DbSet + EntityTypeConfiguration в `src/food-market.infrastructure/Persistence/AppDbContext.cs` + `Configurations/`.
|
||
3. Migration в `Migrations/<timestamp>_<name>.cs` — **ВРУЧНУЮ**, не через `dotnet ef migrations add`. Обязательны `[Migration("id")]` + `[DbContext(typeof(AppDbContext))]` (memory: `feedback_ef_migrations`).
|
||
4. DTO + Validator в `src/food-market.application/<Area>/`.
|
||
5. Mapster TypeAdapterConfig в `MapsterConfig.Build()` если есть нетривиальное проецирование.
|
||
6. Controller в `src/food-market.api/Controllers/<Area>/`. Atomic per endpoint, multi-tenant через query-filter (автоматически).
|
||
7. Integration-тест в `tests/food-market.IntegrationTests/<Area>Tests.cs` — минимум один happy-path.
|
||
8. Если возвращаешь в Web — обновить `src/food-market.web/src/lib/types.ts`.
|
||
|
||
### Q: Как запустить нагрузочный тест
|
||
|
||
```bash
|
||
cd tests/load
|
||
BASE_URL=http://localhost:5081 k6 run retail-sales-parallel.js
|
||
# или против stage:
|
||
BASE_URL=https://test.admin.food-market.kz k6 run signup-burst.js
|
||
```
|
||
|
||
См. [performance-baseline.md](performance-baseline.md) для интерпретации цифр.
|
||
|
||
### Q: Где POS WPF тестировать
|
||
|
||
Нужен Windows. На macOS/Linux можно собрать (`dotnet build src/food-market.pos`)
|
||
но не запустить UI. Тесты POS-логики в `src/food-market.pos.core` —
|
||
кроссплатформенные.
|
||
|
||
### Q: Хочу понять как работает …
|
||
|
||
- **Tenant isolation** → `MULTI-TENANCY.md` + `AppDbContext.ApplyTenantFilter`.
|
||
- **OpenIddict** → `openiddict-keys.md` + Program.cs `AddOpenIddict()`.
|
||
- **POS sync с idempotency** → `food-market.pos.core` + `PosBatchAckController`.
|
||
- **ОФД** → `ofd-integration.md` + `Infrastructure/Fiscal/`.
|
||
- **CSV import** → `imports.md` + `ProductsController.ImportCsv`.
|
||
- **GDPR org export** → `OrgExportJob` (Sprint 22).
|
||
|
||
## Где спрашивать
|
||
|
||
- Forgejo issues — для багов и feature requests.
|
||
- В коде — поиск по docstring (комментарии часто отвечают «почему сделано
|
||
именно так»).
|
||
- Sprint-progress файлы — там цифры и trade-off'ы зафиксированы.
|
||
- Memory-файлы Claude Code в `~/.claude/projects/-home-nns-food-market/memory/`
|
||
— что-то типа CHANGELOG развития, более информально.
|
||
|
||
Welcome! 🚀
|