All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m25s
143 lines
3.3 KiB
Markdown
143 lines
3.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
|
|
|
|
---
|
|
|
|
## 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
|
|
|
|
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.
|