rhythm-backend/BACKEND_BLUEPRINT.md
Dmitri 1ddf0eba4b
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 2m11s
initial pool creation
2026-04-19 18:32:24 +02:00

164 lines
4.3 KiB
Markdown

# Go Backend Blueprint (Iteration Draft)
## Chosen Stack
- **Framework:** Gin
- **Migrations:** Goose (SQL-only)
- **DB Access:** SQLC (no ORM), package per bounded context
- **PostgreSQL Driver/Pool:** pgx/v5 + pgxpool
- **Logging:** Uber Zap (structured logs)
- **Health Probes:** liveness/readiness endpoints
- **API Docs:** OpenAPI (for frontend TypeScript type generation)
- **Deployment:** Docker Compose on self-hosted hardware
---
## Architecture Direction
### Layering
- `cmd/api` - application entrypoint and dependency wiring
- `internal/http` - Gin router, handlers, middleware
- `internal/service` - business logic + transaction boundaries
- `internal/db/<context>` - SQLC-generated code by bounded context
- `internal/store` - shared DB/Tx helpers
- `internal/auth` - JWT validation + role guards
- `internal/config` - env configuration loading
- `migrations/` - Goose SQL migration files
- `api/openapi/` - OpenAPI spec + generated artifacts
### Transaction Strategy
- Handlers stay thin.
- Service layer owns DB transactions.
- SQLC queries are called with either pool or tx using `DBTX` interfaces.
- No transaction logic in handlers.
---
## API and Runtime
### API Shape
- REST JSON API
- Possible future WebSocket support for interactive features
- Suggested versioning: `/api/v1`
### Health Endpoints
- `GET /health/live` - process is alive
- `GET /health/ready` - DB ping succeeds (and optionally migration version check)
### Logging
- Zap JSON logs
- Correlation/request ID in middleware
- Structured error logging from middleware and service boundaries
---
## Database and Migrations
### Goose
- SQL-only migrations
- Keep up/down migration scripts
- Run on startup in non-prod optional, required in CI/CD/deploy step
### SQLC
- Generate one package per bounded context (similar to Spring repository modules)
- Keep SQL in context directories (`query.sql`, `models.sql` style)
- Service layer composes multiple repositories when needed
### Work in Progress Snapshot
- `sqlc.yaml` is now configured for PostgreSQL with schema from `migrations/*.sql`
- First bounded context added: `internal/db/users`
- Current users SQLC artifacts generated:
- `db.go`, `models.go`, `queries.sql.go`, `querier.go`
- Current SQLC generation options in use:
- `sql_package: pgx/v5`
- `emit_interface: true` (generated `Querier` interface)
- `emit_json_tags: false` (can be revisited if API structs are returned directly)
- Initial queries implemented for users: `GetUser`, `CreateUser`, `DeleteUser`
- DB pool wiring into `cmd/api` and service construction is planned next
---
## Testing Approach (Beginner-Friendly)
### Phase 1 (Recommended Start)
- Unit tests for pure service logic (no DB)
- Integration tests for SQLC repositories with real Postgres via Docker
### DB Interface Testing (via SQLC `Querier`)
- Treat generated SQLC interfaces (e.g. `usersdb.Querier`) as service dependencies
- For service unit tests, provide a fake/mock implementation of `Querier`
- Focus unit tests on business rules, branching, and error mapping (not SQL behavior)
- Keep SQL correctness in integration tests against real Postgres
- This split gives fast unit tests plus high-confidence DB integration coverage
### Phase 2
- HTTP handler tests with `httptest`
- Auth middleware tests
### Phase 3
- Minimal end-to-end happy path tests
---
## OpenAPI + Frontend Type Generation
- Keep spec in repo at `api/openapi/openapi.yaml`
- Generate frontend TypeScript types from OpenAPI (e.g. `openapi-typescript`)
- Optionally serve Swagger UI from backend
---
## Deployment
- Docker Compose for app + postgres
- Healthcheck in compose should target readiness endpoint
- Env-based configuration (`.env`, `.env.example`)
---
## Pending Decisions
1. JWT signing:
- HS256 shared secret (simple)
- RS256 keypair (better long-term)
2. Token model:
- Access token only
- Access + refresh token
3. Initial roles:
- USER / ADMIN
- USER / MODERATOR / ADMIN
4. OpenAPI workflow:
- Contract-first (spec first)
- Code-first annotations
5. CORS policy:
- Allowed frontend origins in dev/prod
6. Schema strategy:
- Single schema (`public`) confirmation
7. Initial bounded contexts:
- e.g. `auth`, `users`, `rooms` (or your domain names)
---
## Iteration Notes
- This file is intentionally a working draft.
- We will refine decisions and turn this into a concrete implementation checklist.