Added detailed implementation plan for step '1.2 Shared Backend Packages'

master
oabrivard 1 month ago
parent ed99d88d92
commit 78e9720c25

@ -0,0 +1,322 @@
# 1.2 Shared Backend Packages - Detailed Implementation Plan (Aligned to Current Codebase)
## Overview
| Attribute | Value |
|-----------|-------|
| **Priority** | HIGH |
| **Duration** | 3-4 days |
| **Dependencies** | Phase 1.1 complete (Go workspace, linting) |
| **Team Size** | 1-2 developers |
## Objectives
1. Build and finalize shared domain primitives (errors, events, types, value objects)
2. Provide infra helpers (auth, DB, observability, utils, security)
3. Replace placeholder implementations with production-ready behavior
4. Ensure unit test coverage and stable public APIs
---
## Target Package Structure (Current)
```
backend/shared/
├── domain/
│ ├── errors/
│ ├── events/
│ ├── types/
│ └── valueobjects/
└── infra/
├── auth/
│ ├── zitadel/
│ └── rbac/
├── database/
│ ├── postgres/
│ └── redis/
├── observability/
│ ├── logging/
│ ├── metrics/
│ └── tracing/
├── security/
└── utils/
├── httputil/
└── validation/
```
---
## Task Breakdown
### Task 1: Domain Errors
**Files:**
- `backend/shared/domain/errors/errors.go`
- `backend/shared/domain/errors/codes.go`
**Keep:**
- `DomainError` with `Code`, `Message`, `Err`
- `Wrap`, `New`, `Unwrap`
- Error code constants
**Add or confirm:**
- Stable error code list
- `errors.Is` compatibility as implemented
- HTTP mapping documented via `infra/utils/httputil/errors.go`
**Acceptance criteria:**
- Error codes are stable and exhaustive for current domains
- Errors wrap and compare predictably
- HTTP mapping is documented and tested in httputil
---
### Task 2: Domain Events
**Files:**
- `backend/shared/domain/events/event.go`
- `backend/shared/domain/events/contracts.go`
**Keep:**
- `Event` interface with `EventType`, `OccurredAt`, `AggregateID`, `AggregateType`
- `EventBus` with `Publish` and `Subscribe`
- Event type constants for game, user, question, leaderboard
- `NewBaseEvent` helper
**Acceptance criteria:**
- Event interfaces match current definitions
- Event types are enumerated and documented
---
### Task 3: Domain Types
**Files:**
- `backend/shared/domain/types/id.go`
- `backend/shared/domain/types/pagination.go`
- `backend/shared/domain/types/enums.go`
**Keep:**
- UUID `ID` type and validation
- Pagination helpers and bounds
- Shared enums: session status, difficulty, roles, completion types
**Add or confirm:**
- Pagination normalization logic documented
**Acceptance criteria:**
- IDs validate UUID format
- Pagination bounds are enforced
- Enums are centralized and reused
---
### Task 4: Value Objects
**Files:**
- `backend/shared/domain/valueobjects/player_name.go`
- `backend/shared/domain/valueobjects/score.go`
**Keep:**
- PlayerName validation and normalization
- Score and Attempt utilities
**Decision:**
- Do not introduce `time_window.go` in this phase (not referenced in codebase)
**Acceptance criteria:**
- Player name validation is deterministic
- Score helpers are documented and tested
---
### Task 5: Auth (Zitadel + RBAC)
**Files:**
- `backend/shared/infra/auth/zitadel/client.go`
- `backend/shared/infra/auth/zitadel/middleware.go`
- `backend/shared/infra/auth/rbac/roles.go`
**Goal:** Replace placeholder JWT validation with real Zitadel token validation.
**Implementation details:**
- Add dependency: `github.com/golang-jwt/jwt/v5`
- Add dependency: `github.com/MicahParks/keyfunc/v3` for JWKS discovery + refresh
- Use OIDC discovery at `{BaseURL}/.well-known/openid-configuration`
- Implement `ValidateToken`:
1. Fetch discovery document and `jwks_uri`
2. Parse JWT with JWKS
3. Validate signature, `iss`, `aud`, expiry
4. Extract claims into `AuthClaims`
5. Set `MFAVerified` based on `amr` containing `mfa` or `otp`
- Implement `RefreshToken` and `RevokeToken` using discovery endpoints
- Keep `JWTMiddleware` behavior and tests (fake validator pattern)
- Keep RBAC helpers unchanged
**Acceptance criteria:**
- JWT validation works with real JWKS
- Issuer and audience checks enforced
- Admin endpoints require `admin` role and MFA verified
- Unit tests for token validation and MFA logic
---
### Task 6: Database Clients (Postgres + Redis)
**Files:**
- `backend/shared/infra/database/postgres/client.go`
- `backend/shared/infra/database/redis/client.go`
**Postgres implementation:**
- Add dependency: `github.com/jackc/pgx/v5/pgxpool`
- Replace placeholder client with wrapper around `*pgxpool.Pool`
- Implement `NewClient(ctx, cfg)` with config validation
- Implement `Ping`, `Close`, `HealthCheck`
- Implement `ConfigFromEnv` using `os.Getenv` with defaults
**Redis implementation:**
- Add dependency: `github.com/redis/go-redis/v9`
- Replace placeholder client with wrapper around `*redis.Client`
- Implement `Set`, `Get`, `Delete`, `Exists`, `Incr`, `Expire`
- Implement `ConfigFromEnv` using `os.Getenv` with defaults
**Acceptance criteria:**
- Clients connect successfully via `ConfigFromEnv`
- Health checks are real and return errors on failure
- Redis CRUD methods implemented and tested
---
### Task 7: Observability
**Files:**
- `backend/shared/infra/observability/logging/logger.go`
- `backend/shared/infra/observability/tracing/tracer.go`
- `backend/shared/infra/observability/metrics/prometheus.go`
**Logging:**
- Keep zerolog wrapper and document config options
**Tracing implementation:**
- Add dependencies:
- `go.opentelemetry.io/otel`
- `go.opentelemetry.io/otel/sdk/trace`
- `go.opentelemetry.io/otel/exporters/jaeger`
- `go.opentelemetry.io/otel/sdk/resource`
- Implement `NewTracer`:
1. Build Jaeger exporter with `JaegerEndpoint`
2. Configure sampler with `SampleRate`
3. Set global tracer provider and resource attributes
- Implement `Shutdown`
- Update `StartSpan` to return real spans
- Implement `ConfigFromEnv`
**Metrics:**
- Keep existing metrics definitions
- Add helper to expose `/metrics` using `promhttp.Handler()` in new `metrics/http.go`
- Implement `ConfigFromEnv`
**Acceptance criteria:**
- Tracing works with Jaeger collector endpoint
- Metrics are registerable and exposable via HTTP
- Tests cover tracer init and metrics handler creation
---
### Task 8: Infra Utils
**Files:**
- `backend/shared/infra/utils/httputil/response.go`
- `backend/shared/infra/utils/httputil/errors.go`
- `backend/shared/infra/utils/httputil/pagination.go`
- `backend/shared/infra/utils/validation/validator.go`
**Keep:**
- Response envelope and pagination helpers
- Error mapping to HTTP status
- Validator with custom tags
**Add or confirm:**
- `MapError` covers all domain codes
- Validation errors return `CodeValidationFailed`
**Acceptance criteria:**
- HTTP helpers are consistent across services
- Validation errors are readable and standardized
---
### Task 9: Infra Security
**Files:**
- `backend/shared/infra/security/sanitize.go`
**Keep:**
- Sanitize helpers for player name, answer, question text, theme
**Add or confirm:**
- Document allowed patterns and length limits
- Tests cover dangerous pattern detection
**Acceptance criteria:**
- Sanitization functions are deterministic
- Edge cases are tested
---
## Public API or Interface Changes
- `infra/auth/zitadel.Client.ValidateToken` becomes fully implemented with JWKS validation
- `infra/auth/zitadel.Client.RefreshToken` and `RevokeToken` implemented
- `infra/database/postgres.Client` wraps `*pgxpool.Pool`
- `infra/database/redis.Client` wraps `*redis.Client`
- `infra/observability/tracing.Tracer` uses OpenTelemetry and returns real spans
- New helper in metrics: `metrics.Handler()` or `metrics.PrometheusHandler()`
---
## Test Plan
Add or extend unit tests for:
1. JWT validation with JWKS (mocked discovery)
2. MFA detection via `amr` claim
3. Postgres config validation and connection errors
4. Redis CRUD behavior (use `miniredis` or mocked client)
5. Tracing initialization and shutdown behavior
6. Metrics handler creation
Existing unit tests should remain valid and may be expanded.
---
## Verification Checklist
```bash
cd backend/shared
go test ./...
golangci-lint run ./...
```
---
## Estimated Time Breakdown
| Task | Duration | Cumulative |
|------|----------|------------|
| Domain errors | 2-3 hours | 3 hours |
| Domain events | 2-3 hours | 6 hours |
| Domain types | 2-3 hours | 9 hours |
| Value objects | 2-3 hours | 12 hours |
| Auth (Zitadel + RBAC) | 6-8 hours | 20 hours |
| Database (Postgres + Redis) | 6-8 hours | 28 hours |
| Observability | 6-8 hours | 36 hours |
| Utils | 3-4 hours | 40 hours |
| Security | 2-3 hours | 43 hours |
| Tests/Docs/Review | 4-6 hours | 49 hours |
---
## Next Steps After Completion
- Proceed to Phase 2.1: Question Bank Service
- Use shared packages in service implementations
Loading…
Cancel
Save