MOC-backend-patterns.md 4.5 KB

MOC: Backend-паттерны и архитектурные решения

Слоистая архитектура

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]]

Error handling chain

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]]

Связанные заметки

  • [[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