All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m25s
3.3 KiB
3.3 KiB
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 wiringinternal/http- Gin router, handlers, middlewareinternal/service- business logic + transaction boundariesinternal/db/<context>- SQLC-generated code by bounded contextinternal/store- shared DB/Tx helpersinternal/auth- JWT validation + role guardsinternal/config- env configuration loadingmigrations/- Goose SQL migration filesapi/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
DBTXinterfaces. - 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 aliveGET /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.sqlstyle) - Service layer composes multiple repositories when needed
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
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
-
JWT signing:
- HS256 shared secret (simple)
- RS256 keypair (better long-term)
-
Token model:
- Access token only
- Access + refresh token
-
Initial roles:
- USER / ADMIN
- USER / MODERATOR / ADMIN
-
OpenAPI workflow:
- Contract-first (spec first)
- Code-first annotations
-
CORS policy:
- Allowed frontend origins in dev/prod
-
Schema strategy:
- Single schema (
public) confirmation
- Single schema (
-
Initial bounded contexts:
- e.g.
auth,users,rooms(or your domain names)
- e.g.
Iteration Notes
- This file is intentionally a working draft.
- We will refine decisions and turn this into a concrete implementation checklist.