# Go Backend Blueprint (Iteration Draft)

## IDEAS
- instead of elastic search use ts vector and ts query to allow easy iseeu searching for smooth experience (pg vector?)

## Chosen Stack

- **Framework:** Gin
- **Dependency Injection:** Uber fx (runtime DI, Spring-like autowiring)
- **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 fx DI wiring
- `internal/http` - Gin Server provider, `router.go` for fx mapping
- `internal/http/api/...` - Domain handlers structured by route hierarchy (e.g., `api/health`, `api/protected/users`)
- `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.

### Dependency Injection (fx)

- Use `fx.Provide` to register constructors (config, logger, db pool, server, handlers).
- Use `fx.Invoke` in `main.go` to orchestrate route mapping and application startup.
- `internal/http/router.go` acts as the central route mapping orchestrator injected via `fx.Invoke`.
- Each domain handler (`internal/http/api/*/handler.go`) receives its dependencies via constructor injection.
- Lifecycle hooks (`fx.Lifecycle`) are used for graceful startup/shutdown of the HTTP server and DB pool.

---

## API and Runtime

### API Shape

- REST JSON API
- Possible future WebSocket support for interactive features
- Suggested versioning: `/api/v1`

### Health Endpoints

- `GET /api/health/live` - process is alive
- `GET /api/health/ready` - DB ping succeeds (and optionally migration version check)

### Logging

- Zap JSON logs
- Uber Zap logger will be initialized in `cmd/api/main.go` and injected into services/middleware (no global loggers).
- Logs will be written directly to a file from the application, with log rotation implemented via `lumberjack`.
- 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
- Migrations are securely bundled into the binary using Go's `embed.FS` from a dedicated `migrations` package to isolate them from `internal` db logic.

### 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`
- **Goose startup migrations** wired into `db.ProvidePool`, utilizing the `embed.FS` strategy.
- **fx DI fully implemented.** All dependencies are provided via `fx.Provide` constructors:
  - `config.Provide` → `*Config`
  - `logger.NewFromConfig` → `*zap.SugaredLogger`
  - `db.ProvidePool` → `*pgxpool.Pool` (lifecycle hooks for graceful shutdown)
  - `http.NewServer` → `*gin.Engine` (lifecycle hooks for startup/shutdown)
  - `health.NewHandler` → `*health.Handler`
- **HTTP route hierarchy** via `internal/http/router.go` (`GlueRoutes`):
  - `GET /api/health/live` - process is alive
  - `GET /api/health/ready` - DB ping succeeds
- **Next Planned:** Auth handler (`/api/auth/login`, `/api/auth/register`), JWT middleware, service layer.

---

## 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.
