## MOC: Backend-паттерны и архитектурные решения ### Слоистая архитектура ```mermaid graph TB HTTP[HTTP Request] --> Chi[Chi Router] Chi --> MW[Middleware: Auth, CORS, Rate Limit, Logger] MW --> H[Handler] H --> S[Service: бизнес-логика] S --> R[Repository: PostgreSQL/pgx] S --> C[Cache: Redis] S --> FS[File Storage: MinIO/S3] R --> PG[(PostgreSQL + PostGIS)] ``` ### Ключевые решения | Паттерн | Где реализовано | Заметка | |---|---|---| | Sentinel errors | `services/*.go` | [[atomic-sentinel-errors-go]] | | Dependency Injection (интерфейсы) | `services/*.go`, `main.go` | [[atomic-dependency-inversion-go]] | | Refresh token rotation | `services/auth.go` | [[decision-jwt-refresh-storage]] | | Rate limiting (Redis + fallback) | `middleware/ratelimit_redis.go` | [[decision-rate-limiter-redis]] | | WebSocket origin check | `handlers/websocket.go` | [[atomic-websocket-origin-check]] | | Refresh token race fix (`DeleteIfExists`) | `services/auth.go` | [[atomic-refresh-token-race-condition]] | | SSRF protection via MaxBytesReader | `handlers/*.go` | `http.MaxBytesReader(w, r.Body, 1MB)` | | Go-playground/validator | `validator/validator.go` | [[decision-validation-library]] | | Cursor-based pagination | `services/places.go` | base64 cursor, `limit+1` trick | | Graceful shutdown | `cmd/api/main.go` | `signal.Notify` + `server.Shutdown` с 30s timeout | | Fail-open/Fail-closed rate limiter | `main.go:119` | [[atomic-redis-rate-limiter-failopen-failclosed]] | | CSP nonce hardening | `Caddyfile` | [[atomic-csp-hardening]] | | Package-level mutable state (anti-pattern) | `handlers/errors.go:13` | [[atomic-global-appenv-package-var]] | | TOCTOU race (anti-pattern) | `services/auth.go:85-86` | [[atomic-toctou-race-registration]] | | PATCH tags/features fix | `handlers/places.go`, `services/places.go` | [[decision-patch-tags-features-fix]] | | Refresh token — cookie вместо header | `handlers/helpers.go`, `API_CONTRACT.md` | [[atomic-api-contract-refresh-cookie]] | ### Error handling chain ```mermaid sequenceDiagram Handler->>Service: call Service->>Repo: query Repo-->>Service: pgx error Service-->>Handler: sentinel error (%w) Handler->>Handler: errors.Is() -> HTTP status alt production Handler->>Handler: скрыть детали 500 else development Handler->>Handler: вернуть как есть end ``` ### Request body size limit Все хендлеры, принимающие JSON, обёрнуты в `http.MaxBytesReader(w, r.Body, 1MB)`. Это предотвращает атаки исчерпания памяти через гигантские payloads. ### Утечка координат карты (frontend) Обнаружена неконсистентность интерфейса `MapProvider`: `init()` принимает `[lng, lat]`, `setCenter()` — `[lat, lng]`. См. [[atomic-map-coordinates-inconsistency]]. ### Подавление ошибок (frontend) В `PlaceForm.tsx`, `MapView.tsx`, `useWebSocket.ts` ошибки подавляются пустым `catch`. См. [[atomic-error-swallowing-frontend]]. ### Покрытие тестами | Уровень | Инструмент | Примеры | |---|---|---| | Unit (сервисы) | `testing` + моки | `auth_test.go` (6 тестов), `places_test.go` (3 теста) | | Integration | `pgxpool` + test DB | `place_repo_test.go` (4 теста) | | Frontend | Vitest + testing-library | `ErrorBoundary.test.tsx` (2 теста) | **Покрытие**: ~5%. Нужно расширять — особенно хендлеры и middleware. ### Антипаттерны, найденные в code review | Антипаттерн | Место | Заметка | |---|---|---| | Package-level mutable state | `handlers/errors.go:13` | [[atomic-global-appenv-package-var]] | | TOCTOU race | `services/auth.go:85-86` | [[atomic-toctou-race-registration]] | | Mutex без defer | `middleware/ratelimit.go:61` | [[atomic-mutex-defer-panic]] | | N+1 запросы | `services/places.go:112-136` | [[atomic-n-plus-one-getbyid]] | | Silenced errors | `PlaceForm.tsx:42-43` | [[atomic-error-swallowing-frontend]] | | **PATCH не обновляет теги/фичи** | `handlers/places.go:263-308`, `services/places.go:194-242` | [[atomic-patch-place-tags-features]] | | **Фронтенд-типы не синхронизированы** | `frontend/src/types/index.ts` | [[atomic-frontend-types-backend-sync]] | ### Связанные заметки - [[architecture-overview]] — общая архитектура и таблица P0-P2 - [[backend-auth-security]] — JWT и refresh token - [[backend-validation]] — валидация - [[backend-rate-limiting]] — rate limiting - [[deploy-production-readiness]] — production readiness - [[MOC-security-patterns]] — безопасность - [[database-migrations]] — схема БД #architecture #backend #golang #MOC #best-practice #anti-pattern