Compare commits
2 Commits
feature/re
...
d64ab02e8b
| Author | SHA1 | Date | |
|---|---|---|---|
| d64ab02e8b | |||
| db09d0ace1 |
243
AGENTS.md
243
AGENTS.md
@@ -1,130 +1,191 @@
|
||||
# dance-lessons-coach — AI Agent Documentation
|
||||
# dance-lessons-coach — Agent Documentation
|
||||
|
||||
This file is the directive document auto-loaded by Mistral Vibe (and Claude Code) when working on `dance-lessons-coach`. It stays short by design (≤ 200 lines, lazy-loading compatible with 128k context). Detailed content lives in `documentation/` and is loaded on demand.
|
||||
AI agent reference for developing, testing, and operating the dance-lessons-coach service.
|
||||
|
||||
> **Restructured 2026-05-02** : the original 1296-line `AGENTS.md` was split into focused guides under `documentation/` (Tâche 6 of the ARCODANGE migration Claude → Mistral Vibe). See [`documentation/HISTORY.md`](documentation/HISTORY.md) for context.
|
||||
|
||||
## 🎯 Project Overview
|
||||
|
||||
**dance-lessons-coach** is a Go-based web service with CLI capabilities, featuring:
|
||||
|
||||
- RESTful JSON API with Chi router
|
||||
- High-performance Zerolog logging
|
||||
- Interface-based architecture
|
||||
- Context-aware services
|
||||
- Comprehensive testing (unit + BDD with Godog)
|
||||
|
||||
## 🛠️ Tools & Technologies
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology | Version |
|
||||
|---|---|---|
|
||||
|-----------|------------|---------|
|
||||
| Language | Go | 1.26.1 |
|
||||
| Router | Chi | v5.2.5 |
|
||||
| Logging | Zerolog | v1.35.0 |
|
||||
| Configuration | Viper | v1.21.0 |
|
||||
| Testing | Godog (BDD) + std lib | v0.15.1 |
|
||||
| Telemetry | OpenTelemetry | v1.43.0 |
|
||||
| Tracing | Jaeger compatible | — |
|
||||
|
||||
## 🗺️ Project Structure
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
dance-lessons-coach/
|
||||
├── adr/ # Architecture Decision Records (25+)
|
||||
├── cmd/ # Entry points (greet, server)
|
||||
├── pkg/ # Core logic (config, greet, server, telemetry, bdd, user, ...)
|
||||
├── features/ # BDD scenarios (.feature files)
|
||||
├── fixtures/ # BDD test fixtures
|
||||
├── adr/ # Architecture Decision Records
|
||||
├── cmd/
|
||||
│ ├── greet/ # CLI application
|
||||
│ └── server/ # Web server entry point
|
||||
├── pkg/
|
||||
│ ├── config/ # Viper-based configuration
|
||||
│ ├── greet/ # Core domain logic + API handlers
|
||||
│ ├── server/ # HTTP server, routing, graceful shutdown
|
||||
│ ├── telemetry/ # OpenTelemetry instrumentation
|
||||
│ ├── user/ # User domain (auth, JWT, repository)
|
||||
│ └── validation/ # Request validation
|
||||
├── scripts/ # Server lifecycle, build, test scripts
|
||||
├── documentation/ # Detailed guides (CLI, API, BDD, etc.)
|
||||
├── .vibe/skills/ # Project-scoped vibe skills
|
||||
├── AGENTS.md # This file (auto-loaded by vibe)
|
||||
├── AGENT_CHANGELOG.md # Trace of structural decisions by AI agents
|
||||
├── CHANGELOG.md # User-facing changelog
|
||||
└── README.md # User documentation
|
||||
├── config.yaml # Configuration file
|
||||
└── config.example.yaml # Configuration template
|
||||
```
|
||||
|
||||
## 📚 Detailed Guides (load on demand)
|
||||
## Server Management
|
||||
|
||||
The directive content is intentionally short. For details, point Mistral / Claude at the relevant guide:
|
||||
```bash
|
||||
# Start / stop / restart
|
||||
./scripts/start-server.sh start
|
||||
./scripts/start-server.sh stop
|
||||
./scripts/start-server.sh restart
|
||||
|
||||
| Topic | Reference |
|
||||
|---|---|
|
||||
| **CLI commands & server lifecycle** | [`documentation/CLI.md`](documentation/CLI.md) |
|
||||
| **REST API endpoints** | [`documentation/API.md`](documentation/API.md) |
|
||||
| **OpenTelemetry / Jaeger** | [`documentation/OBSERVABILITY.md`](documentation/OBSERVABILITY.md) |
|
||||
| **Troubleshooting** | [`documentation/TROUBLESHOOTING.md`](documentation/TROUBLESHOOTING.md) |
|
||||
| **Code patterns & examples** | [`documentation/CODE_EXAMPLES.md`](documentation/CODE_EXAMPLES.md) |
|
||||
| **Roadmap & future enhancements** | [`documentation/ROADMAP.md`](documentation/ROADMAP.md) |
|
||||
| **Development phases (history)** | [`documentation/HISTORY.md`](documentation/HISTORY.md) |
|
||||
| **Agent workflows & best practices** | [`documentation/AGENT_USAGE_GUIDE.md`](documentation/AGENT_USAGE_GUIDE.md) |
|
||||
| **BDD testing** | [`documentation/BDD_GUIDE.md`](documentation/BDD_GUIDE.md) |
|
||||
| **Version management** | [`documentation/version-management-guide.md`](documentation/version-management-guide.md) |
|
||||
| **Local CI/CD testing** | [`documentation/local-ci-cd-testing.md`](documentation/local-ci-cd-testing.md) |
|
||||
| **Gitmoji cheatsheet** | [`documentation/GITMOJI_CHEATSHEET.md`](documentation/GITMOJI_CHEATSHEET.md) |
|
||||
| **User-facing changelog** | [`CHANGELOG.md`](CHANGELOG.md) |
|
||||
| **AI agent decisions log** | [`AGENT_CHANGELOG.md`](AGENT_CHANGELOG.md) |
|
||||
# Status and logs
|
||||
./scripts/start-server.sh status
|
||||
./scripts/start-server.sh logs
|
||||
|
||||
## 📝 Architecture Decision Records (ADRs)
|
||||
# Test all API endpoints
|
||||
./scripts/start-server.sh test
|
||||
```
|
||||
|
||||
The project maintains comprehensive ADRs documenting all major architectural choices. See [`adr/README.md`](adr/README.md) for the index and process.
|
||||
## Configuration
|
||||
|
||||
**Key decisions** (load the corresponding ADR for full context):
|
||||
All settings can be provided via `config.yaml` or environment variables (`DLC_` prefix).
|
||||
|
||||
- **Language**: Go 1.26.1 ([ADR-0001](adr/0001-go-1.26.1-standard.md))
|
||||
- **Routing**: Chi router ([ADR-0002](adr/0002-chi-router.md))
|
||||
- **Logging**: Zerolog ([ADR-0003](adr/0003-zerolog-logging.md))
|
||||
- **Design**: Interface-based ([ADR-0004](adr/0004-interface-based-design.md))
|
||||
- **Shutdown**: Graceful with readiness ([ADR-0005](adr/0005-graceful-shutdown.md))
|
||||
- **Config**: Viper ([ADR-0006](adr/0006-configuration-management.md))
|
||||
- **Observability**: OpenTelemetry ([ADR-0007](adr/0007-opentelemetry-integration.md))
|
||||
- **Testing**: BDD with Godog ([ADR-0008](adr/0008-bdd-testing.md))
|
||||
- **Hybrid testing strategy**: ([ADR-0009](adr/0009-hybrid-testing-approach.md))
|
||||
- **CLI**: Cobra subcommands ([ADR-0015](adr/0015-cli-subcommands-cobra.md))
|
||||
- **CI/CD**: Trunk-based development ([ADR-0017](adr/0017-trunk-based-development-workflow.md))
|
||||
| Option | Env var | Default | Description |
|
||||
|--------|---------|---------|-------------|
|
||||
| Host | `DLC_SERVER_HOST` | `0.0.0.0` | Bind address |
|
||||
| Port | `DLC_SERVER_PORT` | `8080` | Listening port |
|
||||
| Shutdown timeout | `DLC_SHUTDOWN_TIMEOUT` | `30s` | Graceful shutdown window |
|
||||
| JSON logging | `DLC_LOGGING_JSON` | `false` | Structured JSON output |
|
||||
| Log output | `DLC_LOGGING_OUTPUT` | `""` | File path (empty = stderr) |
|
||||
| API v2 | `DLC_API_V2_ENABLED` | `false` | Enable `/api/v2` routes |
|
||||
| Config file | `DLC_CONFIG_FILE` | `./config.yaml` | Override config path |
|
||||
|
||||
To add a new ADR: copy an existing one (`adr/0001-*.md`) as a template, edit, then update `adr/README.md`.
|
||||
Minimal `config.yaml`:
|
||||
```yaml
|
||||
server:
|
||||
host: "0.0.0.0"
|
||||
port: 8080
|
||||
shutdown:
|
||||
timeout: 30s
|
||||
logging:
|
||||
json: false
|
||||
```
|
||||
|
||||
## 🤖 AI Agent Information
|
||||
**Priority**: env var > config file > default.
|
||||
|
||||
**Default agent** (Mistral Vibe CLI):
|
||||
## API Endpoints
|
||||
|
||||
- **Model**: `mistral-medium-3.5` (via alias `mistral-vibe-cli-latest` — devstral-2 lineage)
|
||||
- **Role**: Development assistant
|
||||
- **Capabilities**: code generation, refactoring, test creation, documentation, architecture guidance, best-practices enforcement
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/health` | Liveness — always `{"status":"healthy"}` |
|
||||
| GET | `/api/ready` | Readiness — 200 when ready, 503 during shutdown |
|
||||
| GET | `/api/version` | Version info (`?format=plain\|full\|json`) |
|
||||
| GET | `/api/v1/greet/` | Default greeting |
|
||||
| GET | `/api/v1/greet/{name}` | Personalized greeting |
|
||||
| POST | `/api/v2/greet` | V2 greeting with validation (feature-flagged) |
|
||||
| GET | `/swagger/` | Swagger UI |
|
||||
| GET | `/swagger/doc.json` | OpenAPI spec |
|
||||
|
||||
For agent-specific workflows (programmer agent, product owner agent, BDD test generation), see [`documentation/AGENT_USAGE_GUIDE.md`](documentation/AGENT_USAGE_GUIDE.md).
|
||||
```bash
|
||||
curl http://localhost:8080/api/health
|
||||
curl http://localhost:8080/api/ready
|
||||
curl http://localhost:8080/api/v1/greet/Alice
|
||||
curl -X POST http://localhost:8080/api/v2/greet \
|
||||
-H "Content-Type: application/json" -d '{"name":"Alice"}'
|
||||
```
|
||||
|
||||
For migration context (Claude Code → Mistral Vibe in progress), see `~/.vibe/plans/migration-claude-vers-mistral-phase-1.md`.
|
||||
## Testing
|
||||
|
||||
## 📝 Commit Conventions
|
||||
```bash
|
||||
# Unit + integration tests
|
||||
go test ./...
|
||||
go test -v ./...
|
||||
|
||||
Conventional Commits + gitmoji. Full reference and tooling in the project skill:
|
||||
# Graceful shutdown + JSON logging validation
|
||||
./scripts/test-graceful-shutdown.sh
|
||||
|
||||
- **Skill**: [`.vibe/skills/commit-message/`](.vibe/skills/commit-message/) (auto-loaded by vibe in this project)
|
||||
- **Cheatsheet**: [`documentation/GITMOJI_CHEATSHEET.md`](documentation/GITMOJI_CHEATSHEET.md)
|
||||
# OpenTelemetry end-to-end
|
||||
./scripts/test-opentelemetry.sh
|
||||
```
|
||||
|
||||
Quick rule: every commit starts with a gitmoji + conventional type (e.g., `✨ feat: add user authentication`, `🐛 fix: prevent race condition`, `📝 docs: update API guide`).
|
||||
**Note:** Do not call `go generate` unless editing API endpoint annotations.
|
||||
When needed: `go generate ./pkg/server/`
|
||||
|
||||
## 📋 BDD Feature Structure
|
||||
## Build
|
||||
|
||||
All user stories and BDD features follow the conventions in [ADR-0008 — BDD Testing](adr/0008-bdd-testing.md) and the practical guide [`documentation/BDD_GUIDE.md`](documentation/BDD_GUIDE.md). Scenario isolation pattern is detailed in [ADR-0025](adr/0025-bdd-scenario-isolation-strategies.md).
|
||||
```bash
|
||||
./scripts/build.sh
|
||||
# Produces: ./bin/server ./bin/greet
|
||||
./bin/server --version
|
||||
```
|
||||
|
||||
## 🗑️ Retention Policy
|
||||
Build injects version, commit, and date via `-ldflags`.
|
||||
|
||||
| Domain | Policy |
|
||||
|---|---|
|
||||
| **ADRs** | Review quarterly. Deprecate via `Status: Deprecated`. Remove after 6 months of deprecation. |
|
||||
| **Documentation** | Archive completed projects to `archive/`. Remove after 12 months. |
|
||||
| **Scripts** | Move unused to `scripts/deprecated/`. Remove after 6 months. |
|
||||
| **Skills** | Move unused to `.vibe/skills/deprecated/`. Remove after 6 months. |
|
||||
## Graceful Shutdown
|
||||
|
||||
## 📞 Support
|
||||
On `SIGTERM` / `SIGINT`:
|
||||
1. Readiness context is cancelled → `/api/ready` returns 503.
|
||||
2. 1-second propagation window (load balancer drains).
|
||||
3. `srv.Shutdown()` waits up to `shutdown.timeout` for active requests.
|
||||
4. Process exits cleanly.
|
||||
|
||||
For issues or questions:
|
||||
Health endpoint stays 200 throughout; readiness endpoint goes 503 immediately on signal.
|
||||
|
||||
1. Check the relevant guide above (table "Detailed Guides")
|
||||
2. Review the corresponding ADR
|
||||
3. Examine existing implementations in `pkg/`
|
||||
4. Consult the agent's reasoning trace (sessions in `~/.vibe/logs/session/`) for context-rich help
|
||||
5. As last resort, consult Go / Chi / Zerolog / Viper upstream documentation
|
||||
## OpenTelemetry / Jaeger
|
||||
|
||||
Enable in config or via env:
|
||||
```bash
|
||||
export DLC_TELEMETRY_ENABLED=true
|
||||
export DLC_TELEMETRY_OTLP_ENDPOINT="localhost:4317"
|
||||
```
|
||||
|
||||
Quick Jaeger setup:
|
||||
```bash
|
||||
docker run -d --name jaeger \
|
||||
-e COLLECTOR_OTLP_ENABLED=true \
|
||||
-p 16686:16686 -p 4317:4317 \
|
||||
jaegertracing/all-in-one:latest
|
||||
```
|
||||
|
||||
## Architecture Decision Records
|
||||
|
||||
| ADR | Decision |
|
||||
|-----|----------|
|
||||
| [0001](adr/0001-go-1.26.1-standard.md) | Go 1.26.1 |
|
||||
| [0002](adr/0002-chi-router.md) | Chi router |
|
||||
| [0003](adr/0003-zerolog-logging.md) | Zerolog |
|
||||
| [0004](adr/0004-interface-based-design.md) | Interface-based design |
|
||||
| [0005](adr/0005-graceful-shutdown.md) | Graceful shutdown |
|
||||
| [0006](adr/0006-configuration-management.md) | Viper configuration |
|
||||
| [0007](adr/0007-opentelemetry-integration.md) | OpenTelemetry |
|
||||
| [0008](adr/0008-bdd-testing.md) | BDD with Godog |
|
||||
| [0009](adr/0009-hybrid-testing-approach.md) | Hybrid testing strategy |
|
||||
|
||||
Add a new ADR: copy an existing file, edit it, update `adr/README.md`.
|
||||
|
||||
## Commit Conventions
|
||||
|
||||
[Conventional Commits](https://www.conventionalcommits.org) with optional [gitmoji](https://gitmoji.dev):
|
||||
|
||||
| Emoji | Type | When |
|
||||
|-------|------|------|
|
||||
| ✨ | `feat` | New feature |
|
||||
| 🐛 | `fix` | Bug fix |
|
||||
| 📝 | `docs` | Documentation |
|
||||
| 🎨 | `style` | Formatting only |
|
||||
| ♻️ | `refactor` | Structural change |
|
||||
| 🚀 | `perf` | Performance |
|
||||
| 🔒 | `security` | Security fix |
|
||||
| 📦 | `chore` | Dependencies / build |
|
||||
| 🧪 | `test` | Tests |
|
||||
| 🤖 | `ci` | CI/CD |
|
||||
| 🔥 | `remove` | Delete code/files |
|
||||
|
||||
Examples:
|
||||
```
|
||||
feat: add JWT authentication middleware
|
||||
fix: ensure first log line is JSON when json logging is enabled
|
||||
docs: rewrite AGENTS.md for clarity
|
||||
```
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
# AGENT_CHANGELOG
|
||||
|
||||
Trace ordonnée des décisions et actions structurantes prises par les agents AI (Claude Code, Mistral Vibe, autres) sur le projet `dance-lessons-coach`. Complémentaire au [`CHANGELOG.md`](CHANGELOG.md) qui couvre les changements user-facing du produit.
|
||||
|
||||
**Pourquoi ce fichier** : référencé dans la documentation directrice (cf. AGENTS.md), mais initialement absent du repo. Initialisé dans le cadre de la Tâche 6 du curriculum migration Claude → Mistral Vibe (ARCODANGE Phase 1).
|
||||
|
||||
## Convention
|
||||
|
||||
Une entrée par décision/action structurante prise par un agent AI. Format :
|
||||
|
||||
```
|
||||
## YYYY-MM-DD — <Agent> — <Titre court>
|
||||
|
||||
**Contexte** : 1-3 lignes — pourquoi cette action
|
||||
**Décision/Action** : ce qui a été fait
|
||||
**Conséquence** : impact sur le projet (fichiers, conventions, workflows)
|
||||
**Référence** : commit hash, PR Gitea, ADR, issue (le cas échéant)
|
||||
```
|
||||
|
||||
Les entrées qui ne demandent pas de discussion (typo fixes, formatting, dependency bumps mineurs) ne sont **pas** loguées ici — c'est ce que fait le commit Git. Ce fichier garde uniquement les décisions où le **pourquoi** mérite une trace.
|
||||
|
||||
---
|
||||
|
||||
## 2026-05-02 — Mistral Vibe (intent-router) + Claude Code (Opus 4.7) — Initialisation AGENT_CHANGELOG.md
|
||||
|
||||
**Contexte** : Tâche 6 du curriculum migration ARCODANGE Phase 1 (cf. `~/.vibe/plans/migration-claude-vers-mistral-phase-1.md`). Le fichier `AGENT_CHANGELOG.md` était mentionné dans la documentation directrice projet mais n'existait pas — friction identifiée par l'audit Phase A.
|
||||
|
||||
**Décision/Action** : initialiser le fichier avec convention claire et pointer depuis `AGENTS.md` (Tâche 6 Phase C).
|
||||
|
||||
**Conséquence** : tout agent qui prend une décision structurante sur le projet doit ajouter une entrée datée ici. Permet la traçabilité des choix AI au-delà des commits Git.
|
||||
|
||||
**Référence** : Tâche 6 du plan migration. Voir aussi `~/.vibe/plans/task-6-phase-a-results.md` pour le contexte complet de la restructuration en cours.
|
||||
57
CHANGELOG.md
57
CHANGELOG.md
@@ -1,57 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
Notable user-facing changes to `dance-lessons-coach`. Format inspired by [Keep a Changelog](https://keepachangelog.com/), versioning follows [Semantic Versioning 2.0.0](https://semver.org/) (see [`documentation/version-management-guide.md`](documentation/version-management-guide.md)).
|
||||
|
||||
The historical phases of foundational development (Phase 1 to Phase 9) are documented in [`documentation/HISTORY.md`](documentation/HISTORY.md).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
_(items pending release; move to a versioned section when tagged)_
|
||||
|
||||
### Changed
|
||||
|
||||
### Fixed
|
||||
|
||||
---
|
||||
|
||||
## 2026-04-05 — Architecture Documentation
|
||||
|
||||
- ✅ Added comprehensive ADR directory with 9 decision records
|
||||
- ✅ Enhanced Zerolog vs Zap analysis in logging ADR
|
||||
- ✅ Updated `README.md` and `AGENTS.md` with ADR references
|
||||
- ✅ Documented hybrid testing approach
|
||||
- ✅ Added BDD testing decision record
|
||||
|
||||
## 2026-04-04 — Observability & Testing
|
||||
|
||||
- ✅ OpenTelemetry integration with Jaeger
|
||||
- ✅ Middleware-only tracing approach
|
||||
- ✅ Comprehensive telemetry configuration
|
||||
- ✅ BDD testing framework setup
|
||||
- ✅ Hybrid testing strategy documentation
|
||||
|
||||
## 2026-04-03 — Production Readiness
|
||||
|
||||
- ✅ Graceful shutdown with readiness endpoints
|
||||
- ✅ Configuration management with Viper
|
||||
- ✅ JSON logging configuration
|
||||
- ✅ File output logging support
|
||||
- ✅ Comprehensive error handling
|
||||
|
||||
## 2026-04-02 — Web API Foundation
|
||||
|
||||
- ✅ Chi router integration
|
||||
- ✅ Versioned API endpoints (`/api/v1`)
|
||||
- ✅ Health and readiness endpoints
|
||||
- ✅ JSON responses with proper headers
|
||||
- ✅ Interface-based design patterns
|
||||
|
||||
## 2026-04-01 — Project Foundation
|
||||
|
||||
- ✅ Go 1.26.1 environment setup
|
||||
- ✅ Project structure with `cmd/` and `pkg/`
|
||||
- ✅ Core Greet service implementation
|
||||
- ✅ CLI interface
|
||||
- ✅ Unit tests with table-driven approach
|
||||
@@ -1,8 +1,8 @@
|
||||
# Use Go 1.26.1 as the standard Go version
|
||||
|
||||
* Status: Accepted
|
||||
* Deciders: Gabriel Radureau, AI Agent
|
||||
* Date: 2026-04-01
|
||||
**Status:** Accepted
|
||||
**Authors:** Gabriel Radureau, AI Agent
|
||||
**Date:** 2026-04-01
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Use Chi router for HTTP routing
|
||||
|
||||
* Status: Accepted
|
||||
* Deciders: Gabriel Radureau, AI Agent
|
||||
* Date: 2026-04-02
|
||||
**Status:** Accepted
|
||||
**Authors:** Gabriel Radureau, AI Agent
|
||||
**Date:** 2026-04-02
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Use Zerolog for structured logging
|
||||
|
||||
* Status: Accepted
|
||||
* Deciders: Gabriel Radureau, AI Agent
|
||||
* Date: 2026-04-02
|
||||
**Status:** Accepted
|
||||
**Authors:** Gabriel Radureau, AI Agent
|
||||
**Date:** 2026-04-02
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Adopt interface-based design pattern
|
||||
|
||||
* Status: Accepted
|
||||
* Deciders: Gabriel Radureau, AI Agent
|
||||
* Date: 2026-04-02
|
||||
**Status:** Accepted
|
||||
**Authors:** Gabriel Radureau, AI Agent
|
||||
**Date:** 2026-04-02
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Implement graceful shutdown with readiness endpoints
|
||||
|
||||
* Status: Accepted
|
||||
* Deciders: Gabriel Radureau, AI Agent
|
||||
* Date: 2026-04-03
|
||||
**Status:** Accepted
|
||||
**Authors:** Gabriel Radureau, AI Agent
|
||||
**Date:** 2026-04-03
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Use Viper for configuration management
|
||||
|
||||
* Status: Accepted
|
||||
* Deciders: Gabriel Radureau, AI Agent
|
||||
* Date: 2026-04-03
|
||||
**Status:** Accepted
|
||||
**Authors:** Gabriel Radureau, AI Agent
|
||||
**Date:** 2026-04-03
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Integrate OpenTelemetry for distributed tracing
|
||||
|
||||
* Status: Accepted
|
||||
* Deciders: Gabriel Radureau, AI Agent
|
||||
* Date: 2026-04-04
|
||||
**Status:** Accepted
|
||||
**Authors:** Gabriel Radureau, AI Agent
|
||||
**Date:** 2026-04-04
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
# Adopt BDD with Godog for behavioral testing
|
||||
|
||||
* Status: Accepted
|
||||
* Deciders: Gabriel Radureau, AI Agent
|
||||
* Date: 2026-04-05
|
||||
|
||||
> **⚠️ Structure superseded by ADR-0024.** The framework decision (Godog, in-process test server) remains valid. However, the flat `features/` layout and single `steps.go` file described here were replaced by a modular per-domain structure. See ADR-0024 for the current organisation: `features/{auth,greet,health,jwt,config}/` with domain-specific step files and per-domain `*_test.go` runners. The `cd features && godog` execution pattern is also outdated — each domain now uses `go test`.
|
||||
**Status:** Accepted
|
||||
**Authors:** Gabriel Radureau, AI Agent
|
||||
**Date:** 2026-04-05
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
# BDD Testing with OpenAPI Documentation
|
||||
# Combine BDD and Swagger-based testing
|
||||
|
||||
* Status: Accepted
|
||||
* Deciders: Gabriel Radureau, AI Agent
|
||||
* Date: 2026-04-05
|
||||
* Last Updated: 2026-04-12
|
||||
|
||||
> **⚠️ Title corrected.** This ADR was originally named "Combine BDD and Swagger-based testing" with the intent of eventually adding SDK-generated BDD tests as a second layer ("hybrid"). That second layer was deferred and has no concrete plan. The actual architecture is **BDD direct-HTTP testing + OpenAPI documentation via swaggo** — calling it "hybrid" is misleading. SDK generation remains a possible future enhancement but is not tracked by any open issue.
|
||||
**Status:** Partially Implemented (BDD + Documentation only)
|
||||
**Authors:** Gabriel Radureau, AI Agent
|
||||
**Date:** 2026-04-05
|
||||
**Last Updated:** 2026-04-05
|
||||
**Implementation Status:** BDD testing and OpenAPI documentation completed, SDK generation deferred
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
# 11. Validation Library Selection
|
||||
|
||||
* Status: Accepted
|
||||
* Deciders: Gabriel Radureau, AI Agent
|
||||
* Date: 2026-04-05
|
||||
* Implementation Date: 2026-04-05
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
The dance-lessons-coach application needs input validation for API request bodies and configuration values. We need a library that integrates well with Go structs and provides clear error messages.
|
||||
|
||||
## Decision Drivers
|
||||
|
||||
* Struct-tag-based validation to avoid boilerplate
|
||||
* Good error messages with field-level detail
|
||||
* Active maintenance and wide adoption
|
||||
* Compatibility with existing interface-based design
|
||||
|
||||
## Considered Options
|
||||
|
||||
* `github.com/go-playground/validator/v10` — struct-tag driven, widely adopted
|
||||
* `github.com/asaskevich/govalidator` — tag-based but less expressive
|
||||
* Manual validation — full control, no dependency, high boilerplate
|
||||
|
||||
## Decision Outcome
|
||||
|
||||
Chosen option: **`go-playground/validator/v10`** because it is the de-facto standard in the Go ecosystem, supports struct-tag annotations, provides field-level error detail, and integrates cleanly with our interface-based design.
|
||||
|
||||
## Implementation
|
||||
|
||||
`github.com/go-playground/validator/v10 v10.30.2` is present in `go.mod`.
|
||||
The `pkg/validation/` package wraps the validator for reuse across handlers.
|
||||
|
||||
## Links
|
||||
|
||||
* [go-playground/validator GitHub](https://github.com/go-playground/validator)
|
||||
@@ -1,7 +1,7 @@
|
||||
# 13. OpenAPI/Swagger Toolchain Selection
|
||||
|
||||
**Date:** 2026-04-05
|
||||
**Status:** ✅ Partially Implemented (Documentation only)
|
||||
**Status:** Partially Implemented (Documentation only)
|
||||
**Authors:** Arcodange Team
|
||||
**Implementation Date:** 2026-04-05
|
||||
**Last Updated:** 2026-04-05
|
||||
@@ -378,6 +378,68 @@ Added to `.gitea/workflows/go-ci-cd.yaml` lint-format job:
|
||||
# Format swagger comments manually
|
||||
swag fmt
|
||||
|
||||
# Format is automatically run in:
|
||||
# - pre-commit hook
|
||||
# - CI/CD lint-format job
|
||||
```
|
||||
=======
|
||||
### Final Implementation
|
||||
|
||||
```bash
|
||||
# 1. Install swaggo
|
||||
go install github.com/swaggo/swag/cmd/swag@latest
|
||||
|
||||
# 2. Add swagger metadata to main.go
|
||||
// @title dance-lessons-coach API
|
||||
// @version 1.0
|
||||
// @description API for dance-lessons-coach service
|
||||
// @host localhost:8080
|
||||
// @BasePath /api
|
||||
package main
|
||||
```
|
||||
|
||||
### Swag Formatting Integration
|
||||
|
||||
To ensure consistent swagger comment formatting, we've integrated `swag fmt` into our workflow:
|
||||
|
||||
#### Git Hooks
|
||||
Added to `.git/hooks/pre-commit`:
|
||||
```bash
|
||||
# Run swag fmt to format swagger comments
|
||||
echo "Running swag fmt..."
|
||||
if command -v swag >/dev/null 2>&1; then
|
||||
swag fmt
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: swag fmt failed"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "swag not installed, skipping swag fmt"
|
||||
fi
|
||||
```
|
||||
|
||||
#### CI/CD Integration
|
||||
Added to `.gitea/workflows/go-ci-cd.yaml` lint-format job:
|
||||
```yaml
|
||||
- name: Install swag
|
||||
run: go install github.com/swaggo/swag/cmd/swag@latest
|
||||
|
||||
- name: Run swag fmt
|
||||
run: swag fmt
|
||||
```
|
||||
|
||||
#### Benefits
|
||||
- **Consistent Formatting**: Automatic formatting of swagger comments
|
||||
- **Pre-Commit Validation**: Catches issues before commit
|
||||
- **CI/CD Enforcement**: Ensures formatting in all pull requests
|
||||
- **Team Consistency**: Everyone follows the same rules
|
||||
- **Automatic Fixes**: Issues are fixed automatically
|
||||
|
||||
#### Usage
|
||||
```bash
|
||||
# Format swagger comments manually
|
||||
swag fmt
|
||||
|
||||
# Format is automatically run in:
|
||||
# - pre-commit hook
|
||||
# - CI/CD lint-format job
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
# 14. gRPC Adoption Strategy
|
||||
|
||||
* Status: Rejected / Deferred
|
||||
* Deciders: Gabriel Radureau, AI Agent
|
||||
* Date: 2026-04-05
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
As the API grows, gRPC was evaluated as an alternative or complement to REST for internal service communication. The question was whether to adopt gRPC alongside the existing Chi REST API.
|
||||
|
||||
## Decision Drivers
|
||||
|
||||
* Performance of inter-service communication
|
||||
* Type safety via Protocol Buffers
|
||||
* Streaming support
|
||||
* Team familiarity and operational overhead
|
||||
|
||||
## Considered Options
|
||||
|
||||
* **Hybrid REST/gRPC** — add gRPC endpoints alongside existing REST endpoints
|
||||
* **REST only** — maintain current Chi router approach
|
||||
* **gRPC-first with transcoding** — use bufbuild/connect for unified REST+gRPC
|
||||
|
||||
## Decision Outcome
|
||||
|
||||
Chosen option: **REST only (deferred)**. gRPC adoption is not warranted at the current scale. The application has a small number of endpoints, a single-binary deployment model, and no internal service mesh that would benefit from gRPC's efficiency.
|
||||
|
||||
### Reasons for deferral
|
||||
|
||||
1. **No inter-service communication today** — the application is a single binary; gRPC's main benefit (efficient binary RPC between services) does not apply
|
||||
2. **Complexity cost** — adding Protobuf toolchain, code generation, and a second transport layer would significantly increase cognitive overhead
|
||||
3. **Chi router commitment** — the REST API is well-designed with OpenAPI documentation; introducing gRPC in parallel creates dual-maintenance burden
|
||||
4. **Team capacity** — limited bandwidth for large architectural changes
|
||||
|
||||
## When to reconsider
|
||||
|
||||
* Application evolves into multiple services that need efficient internal RPC
|
||||
* Streaming use cases emerge (real-time lesson progress, etc.)
|
||||
* External consumers explicitly require gRPC endpoints
|
||||
|
||||
## Links
|
||||
|
||||
* [ADR-0002: Chi Router](0002-chi-router.md)
|
||||
* [ADR-0013: OpenAPI/Swagger Toolchain](0013-openapi-swagger-toolchain.md)
|
||||
@@ -1,7 +1,7 @@
|
||||
# 15. CLI Subcommands and Flag Management with Cobra
|
||||
|
||||
**Date:** 2026-04-05
|
||||
**Status:** ✅ Implemented
|
||||
**Status:** Implemented
|
||||
**Authors:** Arcodange Team
|
||||
**Decision Date:** 2026-04-05
|
||||
**Implementation Status:** Phase 1 Complete
|
||||
@@ -222,7 +222,7 @@ dance-lessons-coach config validate
|
||||
|
||||
---
|
||||
|
||||
**Status:** Accepted
|
||||
**Implementation Date:** 2026-04-05
|
||||
**Status:** Proposed
|
||||
**Next Review:** 2026-04-12
|
||||
**Implementation Owner:** Arcodange Team
|
||||
**Approved by:** @gabrielradureau
|
||||
**Approvers Needed:** @gabrielradureau
|
||||
@@ -1,10 +1,10 @@
|
||||
# 16. CI/CD Pipeline Design for Multi-Platform Compatibility
|
||||
|
||||
**Date:** 2026-04-05
|
||||
**Status:** ✅ Accepted
|
||||
**Status:** Accepted
|
||||
**Authors:** Arcodange Team
|
||||
**Decision Date:** 2026-04-08
|
||||
**Implementation Status:** ✅ Completed
|
||||
**Implementation Status:** Completed
|
||||
|
||||
## Context
|
||||
|
||||
@@ -832,7 +832,7 @@ jobs:
|
||||
- ✅ **Coverage reporting**: Badges updating automatically
|
||||
- ✅ **Binary builds**: Scripts executing properly in container environment
|
||||
|
||||
**Status:** ✅ Accepted
|
||||
**Status:** Accepted
|
||||
**Implementation Date:** 2026-04-08
|
||||
**Implementation Owner:** Arcodange Team
|
||||
**Reviewers:** @gabrielradureau
|
||||
@@ -1,10 +1,10 @@
|
||||
# 17. Trunk-Based Development Workflow for CI/CD Safety
|
||||
|
||||
**Date:** 2026-04-05
|
||||
**Status:** 🟢 Approved
|
||||
**Status:** Approved
|
||||
**Authors:** Arcodange Team
|
||||
**Decision Date:** 2026-04-05
|
||||
**Implementation Status:** ✅ Implemented
|
||||
**Implementation Status:** Implemented
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# 18. User Management and Authentication System
|
||||
|
||||
**Date:** 2026-04-06
|
||||
**Status:** Accepted
|
||||
**Implementation Date:** 2026-04-08
|
||||
**Status:** Proposed
|
||||
**Authors:** Product Owner
|
||||
**Decision Drivers:** Security, User Personalization, Admin Functionality
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
# 19. PostgreSQL Database Integration
|
||||
|
||||
**Date:** 2026-04-07
|
||||
**Status:** Accepted (Partial)
|
||||
**Implementation Date:** 2026-04-08
|
||||
**Status:** Proposed
|
||||
**Authors:** Product Owner
|
||||
**Decision Drivers:** Data Persistence, Scalability, Production Readiness
|
||||
|
||||
> **⚠️ Pending cleanup:** `pkg/user/sqlite_repository.go` and `gorm.io/driver/sqlite` still present in the codebase. The ADR requires their removal, but no Gitea issue tracks this yet. The PostgreSQL implementation (`pkg/user/postgres_repository.go`) is complete and in use.
|
||||
|
||||
## Context
|
||||
|
||||
The dance-lessons-coach application currently uses SQLite with GORM for the user management system (ADR 0018), but since there are no existing users or production data, we can implement PostgreSQL directly as our primary database without migration concerns.
|
||||
@@ -362,8 +359,6 @@ The PostgreSQL integration follows established dance-lessons-coach patterns:
|
||||
2. **Configuration Updates:** New database configuration structure
|
||||
3. **Development Workflow:** Docker-based database for local development
|
||||
|
||||
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
### Alternative 1: Keep SQLite with File Persistence
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# ADR 0020: Docker Build Strategy - Traditional vs Buildx
|
||||
|
||||
## Status
|
||||
**Accepted** ✅
|
||||
**Status:** Accepted
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
# 21. JWT Secret Retention Policy
|
||||
# 10. JWT Secret Retention Policy
|
||||
|
||||
## Status
|
||||
**Proposed** 🟡
|
||||
|
||||
> **Note:** Basic JWT multi-secret support and graceful rotation are implemented in `pkg/jwt/jwt_secret_manager.go`. The retention cleanup policy (background job, configurable TTL factor) proposed in this ADR is **not yet implemented**.
|
||||
**Status:** Proposed
|
||||
|
||||
## Context
|
||||
|
||||
The dance-lessons-coach application requires a robust JWT secret management system that balances security and user experience. The system supports multiple JWT secrets for graceful rotation. However, the current implementation lacks a clear policy for secret retention and cleanup.
|
||||
The dance-lessons-coach application requires a robust JWT secret management system that balances security and user experience. As implemented in [ADR-0009](0009-hybrid-testing-approach.md), the system supports multiple JWT secrets for graceful rotation. However, the current implementation lacks a clear policy for secret retention and cleanup.
|
||||
|
||||
### Current State
|
||||
|
||||
@@ -388,8 +385,8 @@ func maskSecret(secret string) string {
|
||||
|
||||
## References
|
||||
|
||||
- [ADR-0009: Hybrid Testing Approach](0009-hybrid-testing-approach.md)
|
||||
- [ADR-0008: BDD Testing](0008-bdd-testing.md)
|
||||
- [ADR-0018: User Management and Auth System](0018-user-management-auth-system.md)
|
||||
- [RFC 7519: JSON Web Tokens](https://tools.ietf.org/html/rfc7519)
|
||||
- [OWASP Key Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Key_Management_Cheat_Sheet.html)
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
# ADR 0022: Rate Limiting and Cache Strategy
|
||||
|
||||
## Status
|
||||
**Proposed** 🟡
|
||||
|
||||
> **⚠️ Not yet implemented.** Gitea issue #13 ("feat: Implement Rate Limiting and Caching Strategy") is open and tracks this work. `go-cache`, `redis`, and `ulule/limiter` are absent from `go.mod`. The phase checkboxes below are corrected to reflect actual status.
|
||||
**Status:** Proposed
|
||||
|
||||
## Context
|
||||
|
||||
@@ -286,38 +283,38 @@ func GetCacheKey(prefix, entityType, entityID string) string {
|
||||
## Implementation Phases
|
||||
|
||||
### Phase 1: In-Memory Cache (Current Sprint)
|
||||
- ❌ Research and select in-memory cache library
|
||||
- ❌ Implement cache interface and in-memory service
|
||||
- ❌ Add cache configuration to config package
|
||||
- ❌ Implement basic cache operations (set, get, delete)
|
||||
- ❌ Add TTL support and automatic cleanup
|
||||
- ❌ Cache JWT validation results
|
||||
- ❌ Add cache metrics and monitoring
|
||||
- ✅ Research and select in-memory cache library
|
||||
- ✅ Implement cache interface and in-memory service
|
||||
- ✅ Add cache configuration to config package
|
||||
- ✅ Implement basic cache operations (set, get, delete)
|
||||
- ✅ Add TTL support and automatic cleanup
|
||||
- ✅ Cache JWT validation results
|
||||
- ✅ Add cache metrics and monitoring
|
||||
|
||||
### Phase 2: Redis-Compatible Cache (Next Sprint)
|
||||
- ❌ Set up Dragonfly/KeyDB in development environment
|
||||
- ❌ Implement Redis cache service
|
||||
- ❌ Add configuration for Redis connection
|
||||
- ❌ Implement cache fallback strategy (Redis → in-memory)
|
||||
- ❌ Add health checks for Redis connection
|
||||
- ❌ Implement distributed cache invalidation
|
||||
- ✅ Set up Dragonfly/KeyDB in development environment
|
||||
- ✅ Implement Redis cache service
|
||||
- ✅ Add configuration for Redis connection
|
||||
- ✅ Implement cache fallback strategy (Redis → in-memory)
|
||||
- ✅ Add health checks for Redis connection
|
||||
- ✅ Implement distributed cache invalidation
|
||||
|
||||
### Phase 3: Rate Limiting (Following Sprint)
|
||||
- ❌ Research and select rate limiting library
|
||||
- ❌ Implement rate limiter service
|
||||
- ❌ Add rate limit configuration
|
||||
- ❌ Implement Chi middleware for rate limiting
|
||||
- ❌ Add rate limit headers to responses
|
||||
- ❌ Implement IP whitelisting
|
||||
- ❌ Add endpoint-specific rate limits
|
||||
- ✅ Research and select rate limiting library
|
||||
- ✅ Implement rate limiter service
|
||||
- ✅ Add rate limit configuration
|
||||
- ✅ Implement Chi middleware for rate limiting
|
||||
- ✅ Add rate limit headers to responses
|
||||
- ✅ Implement IP whitelisting
|
||||
- ✅ Add endpoint-specific rate limits
|
||||
|
||||
### Phase 4: Advanced Features (Future)
|
||||
- ❌ Cache warming for critical data
|
||||
- ❌ Two-level caching (Redis + in-memory)
|
||||
- ❌ Cache compression for large objects
|
||||
- ❌ Rate limit exemptions for admin users
|
||||
- ❌ Dynamic rate limit adjustment
|
||||
- ❌ Cache analytics and usage patterns
|
||||
- ✅ Cache warming for critical data
|
||||
- ✅ Two-level caching (Redis + in-memory)
|
||||
- ✅ Cache compression for large objects
|
||||
- ✅ Rate limit exemptions for admin users
|
||||
- ✅ Dynamic rate limit adjustment
|
||||
- ✅ Cache analytics and usage patterns
|
||||
|
||||
## Configuration
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
# Config Hot Reloading Strategy
|
||||
|
||||
* Status: Proposed
|
||||
* Deciders: Gabriel Radureau, AI Agent
|
||||
* Date: 2026-04-05
|
||||
|
||||
> **⚠️ Not yet implemented.** No `ConfigManager` exists in `pkg/config/` and Viper's `WatchConfig()` is not wired up. However, `features/config/config_hot_reloading.feature` has been written — BDD scenarios exist for a feature that is not yet built. Those tests are expected to fail until implementation begins.
|
||||
**Status:** Proposed
|
||||
**Authors:** Gabriel Radureau, AI Agent
|
||||
**Date:** 2026-04-05
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# ADR 0024: BDD Test Organization and Isolation Strategy
|
||||
|
||||
## Status
|
||||
**Accepted** ✅
|
||||
**Status:** Proposed
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# ADR 0025: BDD Scenario Isolation Strategies
|
||||
|
||||
## Status
|
||||
**Accepted (Partial)** 🟡
|
||||
|
||||
Phase 1 (schema-per-scenario DB isolation + `ScenarioState` manager in `pkg/bdd/steps/scenario_state.go`) is implemented.
|
||||
Phase 2 (cache key prefix strategy, in-memory store `Reset()` methods) is pending — blocked on ADR-0022 (rate limiting/cache) not yet implemented.
|
||||
**Status:** Proposed
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
169
adr/README.md
169
adr/README.md
@@ -1,130 +1,113 @@
|
||||
# Architecture Decision Records (ADRs)
|
||||
|
||||
This directory contains Architecture Decision Records (ADRs) for the dance-lessons-coach project.
|
||||
This directory contains the Architecture Decision Records (ADRs) for the dance-lessons-coach project. Each ADR captures a structurally important decision, its context, and its consequences.
|
||||
|
||||
## Index of ADRs
|
||||
## Index
|
||||
|
||||
| Number | Title | Status |
|
||||
|--------|-------|--------|
|
||||
| 0001 | Go 1.26.1 Standard | ✅ Accepted |
|
||||
| 0002 | Chi Router | ✅ Accepted |
|
||||
| 0003 | Zerolog Logging | ✅ Accepted |
|
||||
| 0004 | Interface-Based Design | ✅ Accepted |
|
||||
| 0005 | Graceful Shutdown | ✅ Accepted |
|
||||
| 0006 | Configuration Management | ✅ Accepted |
|
||||
| 0007 | OpenTelemetry Integration | ✅ Accepted |
|
||||
| 0008 | BDD Testing with Godog | ✅ Accepted (structure superseded by 0024) |
|
||||
| 0009 | BDD Testing with OpenAPI Documentation | ✅ Accepted |
|
||||
| 0010 | API v2 Feature Flag | ✅ Accepted |
|
||||
| 0011 | Validation Library (go-playground/validator) | ✅ Accepted |
|
||||
| 0012 | Git Hooks: Staged-Only Formatting | ✅ Accepted |
|
||||
| 0013 | OpenAPI/Swagger Toolchain (swaggo/swag) | ✅ Accepted |
|
||||
| 0014 | gRPC Adoption Strategy | ❌ Rejected / Deferred |
|
||||
| 0015 | CLI Subcommands with Cobra | ✅ Accepted |
|
||||
| 0016 | CI/CD Pipeline Design | ✅ Accepted |
|
||||
| 0017 | Trunk-Based Development Workflow | ✅ Accepted |
|
||||
| 0018 | User Management and Auth System | ✅ Accepted |
|
||||
| 0019 | PostgreSQL Integration | ✅ Accepted (SQLite cleanup pending) |
|
||||
| 0020 | Docker Build Strategy | ✅ Accepted |
|
||||
| 0021 | JWT Secret Retention Policy | 🟡 Proposed (base JWT done; cleanup job not implemented) |
|
||||
| 0022 | Rate Limiting and Cache Strategy | 🟡 Proposed (not implemented — Gitea issue #13) |
|
||||
| 0023 | Config Hot Reloading | 🟡 Proposed (not implemented) |
|
||||
| 0024 | BDD Test Organization and Isolation | ✅ Accepted |
|
||||
| 0025 | BDD Scenario Isolation Strategies | ✅ Accepted (Partial — Phase 2 pending ADR-0022) |
|
||||
| ADR | Title | Status |
|
||||
|-----|-------|--------|
|
||||
| [0001](0001-go-1.26.1-standard.md) | Use Go 1.26.1 as the standard Go version | Accepted |
|
||||
| [0002](0002-chi-router.md) | Use Chi router for HTTP routing | Accepted |
|
||||
| [0003](0003-zerolog-logging.md) | Use Zerolog for structured logging | Accepted |
|
||||
| [0004](0004-interface-based-design.md) | Adopt interface-based design pattern | Accepted |
|
||||
| [0005](0005-graceful-shutdown.md) | Implement graceful shutdown with readiness endpoints | Accepted |
|
||||
| [0006](0006-configuration-management.md) | Use Viper for configuration management | Accepted |
|
||||
| [0007](0007-opentelemetry-integration.md) | Integrate OpenTelemetry for distributed tracing | Accepted |
|
||||
| [0008](0008-bdd-testing.md) | Adopt BDD with Godog for behavioral testing | Accepted |
|
||||
| [0009](0009-hybrid-testing-approach.md) | Combine BDD and Swagger-based testing | Partially Implemented |
|
||||
| [0010](0010-api-v2-feature-flag.md) | API v2 Feature Flag Implementation | Accepted |
|
||||
| [0012](0012-git-hooks-staged-only-formatting.md) | Git Hooks: Staged-Only Formatting | Accepted |
|
||||
| [0013](0013-openapi-swagger-toolchain.md) | OpenAPI/Swagger Toolchain Selection | Partially Implemented |
|
||||
| [0015](0015-cli-subcommands-cobra.md) | CLI Subcommands and Flag Management with Cobra | Implemented |
|
||||
| [0016](0016-ci-cd-pipeline-design.md) | CI/CD Pipeline Design for Multi-Platform Compatibility | Accepted |
|
||||
| [0017](0017-trunk-based-development-workflow.md) | Trunk-Based Development Workflow for CI/CD Safety | Approved |
|
||||
| [0018](0018-user-management-auth-system.md) | User Management and Authentication System | Proposed |
|
||||
| [0019](0019-postgresql-integration.md) | PostgreSQL Database Integration | Proposed |
|
||||
| [0020](0020-docker-build-strategy.md) | Docker Build Strategy: Traditional vs Buildx | Accepted |
|
||||
| [0021](0021-jwt-secret-retention-policy.md) | JWT Secret Retention Policy | Proposed |
|
||||
| [0022](0022-rate-limiting-cache-strategy.md) | Rate Limiting and Cache Strategy | Proposed |
|
||||
| [0023](0023-config-hot-reloading.md) | Config Hot Reloading Strategy | Proposed |
|
||||
| [0024](0024-bdd-test-organization-and-isolation.md) | BDD Test Organization and Isolation Strategy | Proposed |
|
||||
| [0025](0025-bdd-scenario-isolation-strategies.md) | BDD Scenario Isolation Strategies | Proposed |
|
||||
|
||||
> **Note** : numbers `0011` and `0014` are not currently in use. Reserved for future ADRs or representing previously deleted entries.
|
||||
|
||||
## What is an ADR?
|
||||
|
||||
An ADR is a document that captures an important architectural decision made along with its context and consequences.
|
||||
An ADR is a document capturing one significant architectural decision: the **context** that motivated it, the **decision** itself, and its **consequences**. ADRs are append-only — once published, an ADR is not edited (except for typo / status updates). New decisions that supersede previous ones are recorded as new ADRs that explicitly link back.
|
||||
|
||||
## Format
|
||||
## Canonical Format
|
||||
|
||||
Each ADR follows this structure:
|
||||
All ADRs follow the canonical format below (homogenized 2026-05-03):
|
||||
|
||||
```markdown
|
||||
# [Short title is a few words]
|
||||
# NN. Short title summarising the decision
|
||||
|
||||
* Status: [Proposed | Accepted | Deprecated | Superseded]
|
||||
* Deciders: [List of decision makers]
|
||||
* Date: [YYYY-MM-DD]
|
||||
**Status:** <Proposed | Accepted | Implemented | Partially Implemented | Approved | Rejected | Deferred | Deprecated | Superseded by ADR-NNNN>
|
||||
**Date:** YYYY-MM-DD
|
||||
**Authors:** Name(s)
|
||||
|
||||
[Optional fields, all in `**Field:** value` format:]
|
||||
**Decision Drivers:** ...
|
||||
**Implementation Status:** ...
|
||||
**Implementation Date:** ...
|
||||
**Last Updated:** ...
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
[Describe the context and problem statement]
|
||||
[Describe the context and problem statement.]
|
||||
|
||||
## Decision Drivers
|
||||
|
||||
* [Driver 1]
|
||||
* [Driver 2]
|
||||
* [Driver 3]
|
||||
* Driver 1
|
||||
* Driver 2
|
||||
|
||||
## Considered Options
|
||||
|
||||
* [Option 1]
|
||||
* [Option 2]
|
||||
* [Option 3]
|
||||
* Option 1
|
||||
* Option 2
|
||||
|
||||
## Decision Outcome
|
||||
|
||||
Chosen option: "[Option 1]" because [justification]
|
||||
Chosen option: "Option 1" because [justification].
|
||||
|
||||
## Pros and Cons of the Options
|
||||
|
||||
### [Option 1]
|
||||
### Option 1
|
||||
|
||||
* Good, because [argument a]
|
||||
* Good, because [argument b]
|
||||
* Bad, because [argument c]
|
||||
* Good, because [argument].
|
||||
* Bad, because [argument].
|
||||
|
||||
### [Option 2]
|
||||
### Option 2
|
||||
|
||||
* Good, because [argument a]
|
||||
* Good, because [argument b]
|
||||
* Bad, because [argument c]
|
||||
* Good, because [argument].
|
||||
* Bad, because [argument].
|
||||
|
||||
## Links
|
||||
|
||||
* [Link type] [Link to ADR]
|
||||
* [Link type] [Link to ADR]
|
||||
* Related ADR: [ADR-NNNN](NNNN-slug.md)
|
||||
* Issue: [#NN](https://gitea.arcodange.lab/arcodange/dance-lessons-coach/issues/NN)
|
||||
```
|
||||
|
||||
## ADR List
|
||||
|
||||
* [0001-go-1.26.1-standard.md](0001-go-1.26.1-standard.md) - Use Go 1.26.1 as the standard Go version
|
||||
* [0002-chi-router.md](0002-chi-router.md) - Use Chi router for HTTP routing
|
||||
* [0003-zerolog-logging.md](0003-zerolog-logging.md) - Use Zerolog for structured logging
|
||||
* [0004-interface-based-design.md](0004-interface-based-design.md) - Adopt interface-based design pattern
|
||||
* [0005-graceful-shutdown.md](0005-graceful-shutdown.md) - Implement graceful shutdown with readiness endpoints
|
||||
* [0006-configuration-management.md](0006-configuration-management.md) - Use Viper for configuration management
|
||||
* [0007-opentelemetry-integration.md](0007-opentelemetry-integration.md) - Integrate OpenTelemetry for distributed tracing
|
||||
* [0008-bdd-testing.md](0008-bdd-testing.md) - Adopt BDD with Godog for behavioral testing (structure superseded by 0024)
|
||||
* [0009-hybrid-testing-approach.md](0009-hybrid-testing-approach.md) - BDD testing with OpenAPI documentation (SDK layer deferred)
|
||||
* [0010-api-v2-feature-flag.md](0010-api-v2-feature-flag.md) - API v2 implementation with feature flag control
|
||||
* [0011-validation-library-selection.md](0011-validation-library-selection.md) - Selection of go-playground/validator for input validation
|
||||
* [0012-git-hooks-staged-only-formatting.md](0012-git-hooks-staged-only-formatting.md) - Git hooks format only staged Go files
|
||||
* [0013-openapi-swagger-toolchain.md](0013-openapi-swagger-toolchain.md) - OpenAPI/Swagger documentation with swaggo/swag
|
||||
* [0014-grpc-adoption-strategy.md](0014-grpc-adoption-strategy.md) - gRPC adoption strategy (rejected/deferred)
|
||||
* [0015-cli-subcommands-cobra.md](0015-cli-subcommands-cobra.md) - Cobra CLI framework adoption
|
||||
* [0016-ci-cd-pipeline-design.md](0016-ci-cd-pipeline-design.md) - CI/CD pipeline architecture
|
||||
* [0017-trunk-based-development-workflow.md](0017-trunk-based-development-workflow.md) - Trunk-based development workflow
|
||||
* [0018-user-management-auth-system.md](0018-user-management-auth-system.md) - User management and authentication system
|
||||
* [0019-postgresql-integration.md](0019-postgresql-integration.md) - PostgreSQL database integration
|
||||
* [0020-docker-build-strategy.md](0020-docker-build-strategy.md) - Docker Build Strategy: Traditional vs Buildx
|
||||
* [0021-jwt-secret-retention-policy.md](0021-jwt-secret-retention-policy.md) - JWT Secret Retention Policy (base JWT done; cleanup job proposed)
|
||||
* [0022-rate-limiting-cache-strategy.md](0022-rate-limiting-cache-strategy.md) - Rate Limiting and Cache Strategy (not yet implemented — issue #13)
|
||||
* [0023-config-hot-reloading.md](0023-config-hot-reloading.md) - Config Hot Reloading Strategy (not yet implemented)
|
||||
* [0024-bdd-test-organization-and-isolation.md](0024-bdd-test-organization-and-isolation.md) - BDD test modular organisation by domain
|
||||
* [0025-bdd-scenario-isolation-strategies.md](0025-bdd-scenario-isolation-strategies.md) - Schema-per-scenario isolation for BDD tests (partial)
|
||||
|
||||
## How to Add a New ADR
|
||||
|
||||
1. Create a new file with the next available number (e.g., `0010-new-decision.md`)
|
||||
2. Follow the template format
|
||||
3. Update this README.md with the new ADR
|
||||
4. Commit the changes
|
||||
|
||||
## Status Legend
|
||||
|
||||
* **Proposed**: Decision is being discussed
|
||||
* **Accepted**: Decision has been made and implemented
|
||||
* **Deprecated**: Decision is no longer relevant
|
||||
* **Superseded**: Decision has been replaced by another ADR
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| **Proposed** | Decision is being discussed; no implementation yet. |
|
||||
| **Accepted** | Decision has been made; implementation may be pending or in progress. |
|
||||
| **Approved** | Same as Accepted; alternative term used in some legacy ADRs. |
|
||||
| **Implemented** | Decision is fully implemented and in production. |
|
||||
| **Partially Implemented** | Decision is partly implemented; remainder is deferred or pending. |
|
||||
| **Rejected** | Decision considered and explicitly rejected. The ADR documents why. |
|
||||
| **Deferred** | Decision postponed; revisit later. |
|
||||
| **Deprecated** | Decision is no longer relevant; system has moved on. |
|
||||
| **Superseded by ADR-NNNN** | Decision has been replaced by another ADR. Always include the link. |
|
||||
|
||||
## How to Add a New ADR
|
||||
|
||||
1. Pick the next available number (currently next would be `0026`).
|
||||
2. Copy an existing ADR (e.g., `0001-go-1.26.1-standard.md`) as a starting template.
|
||||
3. Edit the title, status, date, authors, and content.
|
||||
4. Update this `README.md` index with the new ADR.
|
||||
5. Commit using gitmoji convention (e.g., `📝 docs(adr): add ADR-0026 about ...`).
|
||||
6. Open a PR for review.
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
# API Endpoints
|
||||
|
||||
REST API reference for `dance-lessons-coach`. Extracted from the original `AGENTS.md` (Tâche 6 restructure) for lazy-loading compatibility with Mistral Vibe.
|
||||
|
||||
## Base URL
|
||||
|
||||
```
|
||||
http://localhost:8080
|
||||
```
|
||||
|
||||
## OpenAPI Documentation
|
||||
|
||||
- **Swagger UI:** `http://localhost:8080/swagger/`
|
||||
- **OpenAPI Spec:** `http://localhost:8080/swagger/doc.json`
|
||||
|
||||
The API provides interactive documentation using Swagger UI with complete OpenAPI 2.0 specification. All endpoints, request/response models, and validation rules are documented using a **hierarchical tagging system**.
|
||||
|
||||
**Features:**
|
||||
|
||||
- Interactive API exploration with hierarchical organization
|
||||
- Try-it-out functionality for all endpoints
|
||||
- Model schemas with examples
|
||||
- Response examples with validation rules
|
||||
- Hierarchical tag structure for better navigation
|
||||
|
||||
**Generation:** Documentation is auto-generated from code annotations using [swaggo/swag](https://github.com/swaggo/swag) with the command:
|
||||
|
||||
```bash
|
||||
go generate ./pkg/server/
|
||||
```
|
||||
|
||||
**Tag Organization:**
|
||||
|
||||
- `API/v1/Greeting` — Version 1 greeting endpoints
|
||||
- `API/v2/Greeting` — Version 2 greeting endpoints
|
||||
- `System/Health` — Health and readiness endpoints
|
||||
|
||||
**Hierarchical Benefits:**
|
||||
|
||||
- Clear separation between API domains (API vs System)
|
||||
- Version organization within each domain
|
||||
- Natural hierarchy in Swagger UI
|
||||
- Scalable for future API growth
|
||||
|
||||
**Embedded Documentation:** The OpenAPI spec is embedded in the binary using Go's `//go:embed` directive for single-binary deployment.
|
||||
|
||||
---
|
||||
|
||||
## Health Check
|
||||
|
||||
```http
|
||||
GET /api/health
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{"status":"healthy"}
|
||||
```
|
||||
|
||||
## Version Info
|
||||
|
||||
```http
|
||||
GET /api/version
|
||||
GET /api/version?format=plain
|
||||
GET /api/version?format=full
|
||||
GET /api/version?format=json
|
||||
```
|
||||
|
||||
Returns the running binary version (injected at build time via `-ldflags`). The `format` query parameter controls the response shape:
|
||||
|
||||
- `format=plain` (or `?format=short`): plain text version (e.g. `1.0.0`)
|
||||
- `format=full`: detailed multi-line text (Version, Commit, Built date, Go version)
|
||||
- `format=json` (default): structured JSON `{"version": "1.0.0", "commit": "abc1234", "built": "...", "go_version": "go1.26.1"}`
|
||||
|
||||
## Readiness Check
|
||||
|
||||
```http
|
||||
GET /api/ready
|
||||
```
|
||||
|
||||
**Responses:**
|
||||
|
||||
- Normal operation: `{"ready":true}` (HTTP 200)
|
||||
- During shutdown: `{"ready":false}` (HTTP 503 Service Unavailable)
|
||||
|
||||
**Purpose:** Indicates whether the server is ready to accept new requests. Returns false during graceful shutdown to allow existing requests to complete while preventing new ones.
|
||||
|
||||
## Greet Service v1
|
||||
|
||||
```http
|
||||
GET /api/v1/greet/
|
||||
GET /api/v1/greet/{name}
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Default greeting
|
||||
curl http://localhost:8080/api/v1/greet/
|
||||
# Response: {"message":"Hello world!"}
|
||||
|
||||
# Personalized greeting
|
||||
curl http://localhost:8080/api/v1/greet/John
|
||||
# Response: {"message":"Hello John!"}
|
||||
|
||||
# Another example
|
||||
curl http://localhost:8080/api/v1/greet/Alice
|
||||
# Response: {"message":"Hello Alice!"}
|
||||
```
|
||||
|
||||
## Greet Service v2 (Feature-flagged)
|
||||
|
||||
```http
|
||||
POST /api/v2/greet
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "John"
|
||||
}
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Valid request
|
||||
curl -X POST http://localhost:8080/api/v2/greet \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"John"}'
|
||||
# Response: {"message":"Hello my friend John!"}
|
||||
|
||||
# Empty name (valid, returns default)
|
||||
curl -X POST http://localhost:8080/api/v2/greet \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":""}'
|
||||
# Response: {"message":"Hello my friend!"}
|
||||
|
||||
# Missing name field (valid, returns default)
|
||||
curl -X POST http://localhost:8080/api/v2/greet \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{}'
|
||||
# Response: {"message":"Hello my friend!"}
|
||||
|
||||
# Name too long (validation error)
|
||||
curl -X POST http://localhost:8080/api/v2/greet \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"ThisNameIsWayTooLongAndShouldFailValidationBecauseItExceedsTheMaximumAllowedLengthOf100Characters!!!!"}'
|
||||
# Response: {"error":"validation_failed","message":"Invalid request data","details":[{"message":"Name failed validation for 'max' (parameter: 100)"}]}
|
||||
```
|
||||
|
||||
**Validation Rules:**
|
||||
|
||||
- `name`: Maximum length 100 characters (optional field)
|
||||
|
||||
**Feature Flag:** Enable with `DLC_API_V2_ENABLED=true` or in config file with `api.v2_enabled: true`.
|
||||
@@ -1,251 +0,0 @@
|
||||
# CLI Management Guide
|
||||
|
||||
Complete reference for the `dance-lessons-coach` CLI, server lifecycle, and configuration. Extracted from the original `AGENTS.md` (Tâche 6 restructure) for lazy-loading compatibility with Mistral Vibe.
|
||||
|
||||
## Cobra CLI (Recommended)
|
||||
|
||||
`dance-lessons-coach` includes a modern CLI built with Cobra:
|
||||
|
||||
```bash
|
||||
# Show help and available commands
|
||||
./bin/dance-lessons-coach --help
|
||||
|
||||
# Show version information
|
||||
./bin/dance-lessons-coach version
|
||||
|
||||
# Greet someone by name
|
||||
./bin/dance-lessons-coach greet John
|
||||
|
||||
# Start the server
|
||||
./bin/dance-lessons-coach server
|
||||
```
|
||||
|
||||
**Available Commands:**
|
||||
|
||||
- `version` — Print version information
|
||||
- `server` — Start the dance-lessons-coach server
|
||||
- `greet [name]` — Greet someone by name
|
||||
- `help` — Built-in help system
|
||||
- `completion` — Generate shell completion scripts
|
||||
|
||||
**Server Command Flags:**
|
||||
|
||||
- `--config` — Config file path
|
||||
- `--env` — Environment (`dev`, `staging`, `prod`)
|
||||
- `--debug` — Enable debug logging
|
||||
|
||||
## Version Information
|
||||
|
||||
The server provides runtime version information:
|
||||
|
||||
```bash
|
||||
# Check version using new CLI
|
||||
./bin/dance-lessons-coach version
|
||||
|
||||
# Check version using server binary
|
||||
./bin/server --version
|
||||
|
||||
# Output:
|
||||
dance-lessons-coach Version Information:
|
||||
Version: 1.0.0
|
||||
Commit: abc1234
|
||||
Built: 2026-04-05T10:00:00+0000
|
||||
Go: go1.26.1
|
||||
```
|
||||
|
||||
For full version management workflow (bump, release, build with version), see [`version-management-guide.md`](version-management-guide.md).
|
||||
|
||||
## Server Control Script
|
||||
|
||||
A shell script manages the server lifecycle:
|
||||
|
||||
```bash
|
||||
cd /Users/gabrielradureau/Work/Vibe/DanceLessonsCoach
|
||||
|
||||
./scripts/start-server.sh start # Start the server
|
||||
./scripts/start-server.sh status # Check server status
|
||||
./scripts/start-server.sh test # Test API endpoints
|
||||
./scripts/start-server.sh logs # View server logs
|
||||
./scripts/start-server.sh stop # Stop the server
|
||||
./scripts/start-server.sh restart # Restart
|
||||
```
|
||||
|
||||
**Available subcommands:**
|
||||
|
||||
- `start` — Start the server in background with proper logging
|
||||
- `stop` — Stop the server gracefully
|
||||
- `restart` — Restart the server
|
||||
- `status` — Check if server is running
|
||||
- `logs` — Show recent server logs
|
||||
- `test` — Test all API endpoints
|
||||
|
||||
## Manual Server Management
|
||||
|
||||
For direct control:
|
||||
|
||||
```bash
|
||||
cd /Users/gabrielradureau/Work/Vibe/DanceLessonsCoach
|
||||
./scripts/start-server.sh start
|
||||
```
|
||||
|
||||
**Expected output:**
|
||||
|
||||
```
|
||||
Server running on :8080
|
||||
[INF] Starting HTTP server on :8080
|
||||
[TRC] Registering greet routes
|
||||
[TRC] Greet routes registered
|
||||
```
|
||||
|
||||
**Features:**
|
||||
|
||||
- Context-aware server initialization
|
||||
- Graceful shutdown handling
|
||||
- Signal-based termination (`SIGINT`, `SIGTERM`)
|
||||
- 30-second shutdown timeout
|
||||
- Proper resource cleanup
|
||||
|
||||
## Configuration
|
||||
|
||||
Configuration via environment variables with `DLC_` prefix:
|
||||
|
||||
| Option | Environment Variable | Default | Description |
|
||||
|---|---|---|---|
|
||||
| Host | `DLC_SERVER_HOST` | `0.0.0.0` | Server bind address |
|
||||
| Port | `DLC_SERVER_PORT` | `8080` | Server listening port |
|
||||
| Shutdown Timeout | `DLC_SHUTDOWN_TIMEOUT` | `30s` | Graceful shutdown timeout |
|
||||
| JSON Logging | `DLC_LOGGING_JSON` | `false` | Enable JSON format logging |
|
||||
| Log Output | `DLC_LOGGING_OUTPUT` | `""` | Log output file path (empty for stderr) |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Custom port
|
||||
export DLC_SERVER_PORT=9090
|
||||
./scripts/start-server.sh start
|
||||
|
||||
# Custom host and port
|
||||
export DLC_SERVER_HOST="127.0.0.1"
|
||||
export DLC_SERVER_PORT=8081
|
||||
./scripts/start-server.sh start
|
||||
|
||||
# Custom shutdown timeout
|
||||
export DLC_SHUTDOWN_TIMEOUT=45s
|
||||
|
||||
# Enable JSON logging
|
||||
export DLC_LOGGING_JSON=true
|
||||
|
||||
# Log to file
|
||||
export DLC_LOGGING_OUTPUT="server.log"
|
||||
|
||||
# Combined: JSON logging to file
|
||||
export DLC_LOGGING_JSON=true
|
||||
export DLC_LOGGING_OUTPUT="server.json.log"
|
||||
```
|
||||
|
||||
**Configuration File Support:**
|
||||
|
||||
A `config.example.yaml` file is provided as a template. By default, the application looks for `config.yaml` in the current working directory.
|
||||
|
||||
To specify a custom config file path, set the `DLC_CONFIG_FILE` environment variable:
|
||||
|
||||
```bash
|
||||
DLC_CONFIG_FILE="/path/to/config.yaml" go run ./cmd/server
|
||||
```
|
||||
|
||||
Example `config.yaml`:
|
||||
|
||||
```yaml
|
||||
server:
|
||||
host: "0.0.0.0"
|
||||
port: 8080
|
||||
|
||||
shutdown:
|
||||
timeout: 30s
|
||||
|
||||
logging:
|
||||
json: false
|
||||
```
|
||||
|
||||
**Configuration Loading Precedence:**
|
||||
|
||||
1. **File-based configuration** (highest precedence)
|
||||
2. **Environment variables** (override defaults, overridden by config file)
|
||||
3. **Default values** (fallback)
|
||||
|
||||
All configuration is validated on startup. Invalid configurations cause server startup failure. Configuration values and source are logged at startup.
|
||||
|
||||
**Verification:**
|
||||
|
||||
```bash
|
||||
DLC_SERVER_PORT=9090 DLC_SERVER_HOST="127.0.0.1" ./scripts/start-server.sh start
|
||||
|
||||
curl http://127.0.0.1:9090/api/health
|
||||
# Expected: {"status":"healthy"}
|
||||
```
|
||||
|
||||
## Server Status
|
||||
|
||||
```bash
|
||||
# Check health endpoint
|
||||
curl -s http://localhost:8080/api/health
|
||||
|
||||
# Check readiness endpoint
|
||||
curl -s http://localhost:8080/api/ready
|
||||
```
|
||||
|
||||
**Expected responses:**
|
||||
|
||||
- Health: `{"status":"healthy"}`
|
||||
- Readiness (normal): `{"ready":true}`
|
||||
- Readiness (during shutdown): `{"ready":false}` (HTTP 503)
|
||||
|
||||
**Endpoint Differences:**
|
||||
|
||||
- **Health endpoint** (`/api/health`): Indicates if the application is running and functional
|
||||
- **Readiness endpoint** (`/api/ready`): Indicates if the application is ready to accept traffic
|
||||
|
||||
**Use Cases:**
|
||||
|
||||
- **Health**: Used by load balancers to check if the app is alive
|
||||
- **Readiness**: Used by Kubernetes / service meshes to determine if the app can accept new requests
|
||||
|
||||
**During Graceful Shutdown:**
|
||||
|
||||
- Health endpoint continues to return `{"status":"healthy"}`
|
||||
- Readiness endpoint returns `{"ready":false}` with HTTP 503 Service Unavailable
|
||||
- This allows existing requests to complete while preventing new requests
|
||||
|
||||
## Stopping the Server
|
||||
|
||||
To stop the server gracefully:
|
||||
|
||||
```bash
|
||||
# Send SIGTERM for graceful shutdown
|
||||
kill -TERM $(lsof -ti :8080)
|
||||
|
||||
# Or send SIGINT (Ctrl+C equivalent)
|
||||
pkill -INT -f "go run"
|
||||
```
|
||||
|
||||
**Graceful shutdown process:**
|
||||
|
||||
1. Server receives termination signal
|
||||
2. Logs shutdown message
|
||||
3. Stops accepting new connections
|
||||
4. Waits up to 30 seconds for active requests to complete
|
||||
5. Closes all connections cleanly
|
||||
6. Exits with proper cleanup
|
||||
|
||||
For force stop (if graceful shutdown hangs):
|
||||
|
||||
```bash
|
||||
kill -9 $(lsof -ti :8080)
|
||||
```
|
||||
|
||||
**Verification:**
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:8080/api/health
|
||||
# Should return connection refused
|
||||
```
|
||||
@@ -1,59 +0,0 @@
|
||||
# Code Examples
|
||||
|
||||
Snippets and patterns used across the `dance-lessons-coach` codebase. Extracted from the original `AGENTS.md` (Tâche 6 restructure).
|
||||
|
||||
## Adding a New API Endpoint
|
||||
|
||||
```go
|
||||
// 1. Add to interface
|
||||
func (h *apiV1GreetHandler) RegisterRoutes(router chi.Router) {
|
||||
router.Get("/", h.handleGreetQuery)
|
||||
router.Get("/{name}", h.handleGreetPath)
|
||||
router.Post("/custom", h.handleCustomGreet) // New endpoint
|
||||
}
|
||||
|
||||
// 2. Implement handler
|
||||
func (h *apiV1GreetHandler) handleCustomGreet(w http.ResponseWriter, r *http.Request) {
|
||||
// Parse request
|
||||
// Call service
|
||||
// Return JSON response
|
||||
}
|
||||
```
|
||||
|
||||
## Logging with Zerolog
|
||||
|
||||
```go
|
||||
// Trace level logging
|
||||
log.Trace().Ctx(ctx).Str("key", "value").Msg("message")
|
||||
|
||||
// Info level
|
||||
log.Info().Msg("Important event")
|
||||
|
||||
// Error level
|
||||
log.Error().Err(err).Msg("Error occurred")
|
||||
```
|
||||
|
||||
For the full logging strategy (when to use Trace vs Info, performance considerations), see [ADR-0003 — Zerolog Logging](../adr/0003-zerolog-logging.md).
|
||||
|
||||
## Using `context.Context`
|
||||
|
||||
```go
|
||||
// Pass context through calls
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
result := service.Greet(r.Context(), "John")
|
||||
// ...
|
||||
}
|
||||
|
||||
// Create context with values
|
||||
ctx := context.WithValue(r.Context(), "key", "value")
|
||||
|
||||
// Create context with timeout
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
|
||||
defer cancel()
|
||||
```
|
||||
|
||||
For the rationale behind context-aware services, see [ADR-0004 — Interface-Based Design](../adr/0004-interface-based-design.md).
|
||||
|
||||
## Best Practices Reminders
|
||||
|
||||
For higher-level guidance on code organization, error handling, performance, and testing, see [`AGENT_USAGE_GUIDE.md`](AGENT_USAGE_GUIDE.md#best-practices) section "Best Practices".
|
||||
@@ -1,83 +0,0 @@
|
||||
# Development History
|
||||
|
||||
This document records the historical development phases of `dance-lessons-coach`. Extracted from the original `AGENTS.md` (Tâche 6 restructure) for lazy-loading compatibility with Mistral Vibe (128k context).
|
||||
|
||||
All phases below are **completed** ✅. They are kept here for traceability and onboarding context — refer to ADRs (`adr/`) for the technical decisions behind each phase.
|
||||
|
||||
## Phase 1: Foundation
|
||||
|
||||
- Go 1.26.1 environment setup
|
||||
- Project structure with `cmd/` and `pkg/` directories
|
||||
- Core Greet service implementation
|
||||
- CLI interface
|
||||
- Unit tests
|
||||
|
||||
## Phase 2: Web API
|
||||
|
||||
- Chi router integration
|
||||
- Versioned API endpoints (`/api/v1`)
|
||||
- Health endpoint (`/api/health`)
|
||||
- JSON responses with proper headers
|
||||
|
||||
## Phase 3: Logging & Architecture
|
||||
|
||||
- Zerolog integration with Trace level
|
||||
- Context-aware logging
|
||||
- Interface-based design patterns
|
||||
- Dependency injection
|
||||
|
||||
## Phase 4: Documentation & Testing
|
||||
|
||||
- Comprehensive `AGENTS.md`
|
||||
- `README.md` with usage instructions
|
||||
- Server management guide
|
||||
- API endpoint documentation
|
||||
|
||||
## Phase 5: Configuration Management
|
||||
|
||||
- Viper integration for configuration
|
||||
- Environment variable support with `DLC_` prefix
|
||||
- Customizable server host/port
|
||||
- Configurable shutdown timeout
|
||||
- Configuration validation and logging
|
||||
- Example configuration file
|
||||
|
||||
## Phase 6: Graceful Shutdown
|
||||
|
||||
- Context-aware server initialization
|
||||
- Signal-based termination (`SIGINT`, `SIGTERM`)
|
||||
- Configurable shutdown timeout
|
||||
- Readiness endpoint for Kubernetes/service mesh integration
|
||||
- Proper resource cleanup during shutdown
|
||||
- Health endpoint remains healthy during graceful shutdown
|
||||
|
||||
## Phase 7: OpenTelemetry Integration
|
||||
|
||||
- OpenTelemetry Go libraries integration
|
||||
- Jaeger compatibility for distributed tracing
|
||||
- Middleware-only approach using `otelhttp.NewHandler`
|
||||
- Configurable sampling strategies
|
||||
- Graceful shutdown of tracer provider
|
||||
- OTLP exporter with gRPC support
|
||||
|
||||
## Phase 8: Build System & Documentation
|
||||
|
||||
- Build script for binary compilation
|
||||
- Binary output to `bin/` directory
|
||||
- Comprehensive commit conventions with gitmoji reference
|
||||
- Updated documentation with Jaeger integration guide
|
||||
- Cleaned up configuration files
|
||||
- Enhanced logging configuration with file output support
|
||||
|
||||
## Phase 9: Final Refinements
|
||||
|
||||
- Removed unnecessary `time.Sleep` for log flushing
|
||||
- Changed server operational logs from Info to Trace level
|
||||
- Moved all logging setup logic to config package
|
||||
- Simplified server entrypoint to 27 lines
|
||||
- Verified all functionality with comprehensive testing
|
||||
- Updated documentation to reflect final architecture
|
||||
|
||||
## Beyond Phase 9
|
||||
|
||||
Subsequent work (CI/CD, BDD scenarios, ADR audit, JWT, config hot-reloading) is tracked in the [Changelog](../CHANGELOG.md) and the corresponding [ADRs](../adr/).
|
||||
@@ -1,94 +0,0 @@
|
||||
# Observability — OpenTelemetry & Jaeger Integration
|
||||
|
||||
Tracing setup for `dance-lessons-coach`. Extracted from the original `AGENTS.md` (Tâche 6 restructure) for lazy-loading compatibility with Mistral Vibe.
|
||||
|
||||
The application supports OpenTelemetry for distributed tracing with Jaeger compatibility.
|
||||
|
||||
## Configuration
|
||||
|
||||
Enable OpenTelemetry in your `config.yaml`:
|
||||
|
||||
```yaml
|
||||
telemetry:
|
||||
enabled: true
|
||||
otlp_endpoint: "localhost:4317"
|
||||
service_name: "dance-lessons-coach"
|
||||
insecure: true
|
||||
sampler:
|
||||
type: "parentbased_always_on"
|
||||
ratio: 1.0
|
||||
```
|
||||
|
||||
Or via environment variables:
|
||||
|
||||
```bash
|
||||
export DLC_TELEMETRY_ENABLED=true
|
||||
export DLC_TELEMETRY_OTLP_ENDPOINT="localhost:4317"
|
||||
export DLC_TELEMETRY_SERVICE_NAME="dance-lessons-coach"
|
||||
export DLC_TELEMETRY_INSECURE=true
|
||||
export DLC_TELEMETRY_SAMPLER_TYPE="parentbased_always_on"
|
||||
export DLC_TELEMETRY_SAMPLER_RATIO=1.0
|
||||
```
|
||||
|
||||
## Testing with Jaeger
|
||||
|
||||
**1. Start Jaeger in Docker:**
|
||||
|
||||
```bash
|
||||
docker run -d --name jaeger \
|
||||
-e COLLECTOR_OTLP_ENABLED=true \
|
||||
-p 16686:16686 \
|
||||
-p 4317:4317 \
|
||||
jaegertracing/all-in-one:latest
|
||||
```
|
||||
|
||||
**2. Start the server with OpenTelemetry enabled:**
|
||||
|
||||
```bash
|
||||
# Using config file
|
||||
./scripts/start-server.sh start
|
||||
|
||||
# Or with environment variables
|
||||
DLC_TELEMETRY_ENABLED=true ./scripts/start-server.sh start
|
||||
```
|
||||
|
||||
**3. Make API requests:**
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/api/v1/greet/John
|
||||
```
|
||||
|
||||
**4. View traces in Jaeger UI:**
|
||||
|
||||
Open http://localhost:16686 and select the `dance-lessons-coach` service.
|
||||
|
||||
## Sampler Types
|
||||
|
||||
| Sampler | Behavior |
|
||||
|---|---|
|
||||
| `always_on` | Sample all traces |
|
||||
| `always_off` | Sample no traces |
|
||||
| `traceidratio` | Sample based on trace ID ratio |
|
||||
| `parentbased_always_on` | Sample based on parent span (always on) |
|
||||
| `parentbased_always_off` | Sample based on parent span (always off) |
|
||||
| `parentbased_traceidratio` | Sample based on parent span with ratio |
|
||||
|
||||
## Testing Script
|
||||
|
||||
A convenience script is provided:
|
||||
|
||||
```bash
|
||||
./scripts/test-opentelemetry.sh
|
||||
```
|
||||
|
||||
This script:
|
||||
|
||||
1. Starts Jaeger container
|
||||
2. Starts the server with OpenTelemetry
|
||||
3. Makes test API calls
|
||||
4. Shows Jaeger UI URL
|
||||
5. Cleans up on exit
|
||||
|
||||
## ADR Reference
|
||||
|
||||
See [ADR-0007 — OpenTelemetry Integration](../adr/0007-opentelemetry-integration.md) for the full architectural decision and rationale (middleware-only approach, sampling strategy, OTLP/gRPC choice).
|
||||
@@ -1,40 +0,0 @@
|
||||
# Roadmap & Future Enhancements
|
||||
|
||||
Tracking pending features and architectural improvements. Extracted from the original `AGENTS.md` (Tâche 6 restructure). Status updated continuously — items move to "Completed Features" section once shipped.
|
||||
|
||||
## Potential Features
|
||||
|
||||
- [ ] Database integration
|
||||
- [ ] Authentication / Authorization
|
||||
- [ ] Rate limiting
|
||||
- [ ] Metrics and monitoring
|
||||
- [ ] Docker containerization
|
||||
- ✅ CI/CD pipeline ([ADR-0016](../adr/0016-ci-cd-pipeline-design.md), [ADR-0017](../adr/0017-trunk-based-development-workflow.md))
|
||||
- [ ] Configuration hot reload
|
||||
- [ ] Circuit breakers
|
||||
|
||||
## Architectural Improvements
|
||||
|
||||
- [ ] Request validation middleware
|
||||
- ✅ OpenAPI / Swagger documentation with embedded spec
|
||||
- [ ] Enhanced OpenTelemetry instrumentation
|
||||
- [ ] Metrics collection and visualization
|
||||
- [ ] Health check improvements
|
||||
- [ ] Configuration validation enhancements
|
||||
|
||||
## Completed Features
|
||||
|
||||
- ✅ Graceful shutdown with readiness endpoint
|
||||
- ✅ OpenTelemetry integration with Jaeger support
|
||||
- ✅ Configuration management with Viper
|
||||
- ✅ Comprehensive logging with Zerolog
|
||||
- ✅ Build system with binary output
|
||||
- ✅ Complete documentation with commit conventions
|
||||
- ✅ Version management with runtime info
|
||||
|
||||
## How to Propose a New Feature
|
||||
|
||||
1. Open a Gitea issue describing the use case and acceptance criteria
|
||||
2. If the feature implies an architectural decision, draft an ADR (`adr/<NNNN>-<slug>.md`) following the template
|
||||
3. Reference the ADR + issue in any PR introducing the feature
|
||||
4. Update this roadmap (move from "Potential" to "Completed" when shipped)
|
||||
@@ -1,107 +0,0 @@
|
||||
# Troubleshooting
|
||||
|
||||
Common issues and their resolution. Extracted from the original `AGENTS.md` and merged with relevant sections from `AGENT_USAGE_GUIDE.md` and `BDD_GUIDE.md`. Refer back to those guides for context-specific troubleshooting (agent workflows, BDD test failures).
|
||||
|
||||
## Port Already in Use
|
||||
|
||||
```bash
|
||||
# Find and kill process using port 8080
|
||||
kill -TERM $(lsof -ti :8080)
|
||||
|
||||
# Force kill if graceful does not work
|
||||
kill -9 $(lsof -ti :8080)
|
||||
```
|
||||
|
||||
## Server Not Responding
|
||||
|
||||
```bash
|
||||
# Check if running
|
||||
curl -s http://localhost:8080/api/health
|
||||
|
||||
# Restart server using control script
|
||||
./scripts/start-server.sh restart
|
||||
|
||||
# View recent logs
|
||||
./scripts/start-server.sh logs
|
||||
```
|
||||
|
||||
If health endpoint returns connection refused, the server may have crashed. Check logs in `./scripts/start-server.sh logs` for stack traces.
|
||||
|
||||
## Dependency Issues
|
||||
|
||||
```bash
|
||||
# Clean and rebuild
|
||||
go mod tidy
|
||||
go build ./...
|
||||
|
||||
# If dependency version conflicts persist
|
||||
go mod download
|
||||
go mod verify
|
||||
```
|
||||
|
||||
## Tests Failing
|
||||
|
||||
### Unit tests
|
||||
|
||||
```bash
|
||||
# Run with verbose output
|
||||
go test -v ./...
|
||||
|
||||
# Check specific test
|
||||
go test ./pkg/greet/ -run TestName
|
||||
```
|
||||
|
||||
### BDD tests
|
||||
|
||||
See [`BDD_GUIDE.md`](BDD_GUIDE.md) for the full BDD troubleshooting workflow (Godog setup, scenario isolation, step matching). Common BDD issues:
|
||||
|
||||
- **Step not found** → check `pkg/bdd/steps/` for the step definition file
|
||||
- **Scenario state leaking** → review [ADR-0025](../adr/0025-bdd-scenario-isolation-strategies.md) for the isolation pattern
|
||||
- **Database not reset** → ensure the test fixtures cleanup runs (BDD scenario After hooks)
|
||||
|
||||
## Configuration Not Loading
|
||||
|
||||
The application logs the configuration source at startup. Check logs for:
|
||||
|
||||
```
|
||||
[INF] Configuration loaded from: file:config.yaml
|
||||
# or
|
||||
[INF] Configuration loaded from: env
|
||||
# or
|
||||
[INF] Configuration loaded from: defaults
|
||||
```
|
||||
|
||||
If config is not loading as expected:
|
||||
|
||||
1. Verify file exists and is readable: `ls -la config.yaml`
|
||||
2. Verify env vars are exported: `env | grep DLC_`
|
||||
3. Check for typos in keys (case-sensitive)
|
||||
4. Review [`AGENT_USAGE_GUIDE.md`](AGENT_USAGE_GUIDE.md) section "Configuration troubleshooting"
|
||||
|
||||
## OpenTelemetry Not Tracing
|
||||
|
||||
1. Verify Jaeger is running: `docker ps | grep jaeger`
|
||||
2. Check `DLC_TELEMETRY_ENABLED=true` in environment or `telemetry.enabled: true` in config
|
||||
3. Verify OTLP endpoint reachable: `nc -zv localhost 4317`
|
||||
4. Check sampler is not `always_off`
|
||||
5. See [`OBSERVABILITY.md`](OBSERVABILITY.md) for full setup
|
||||
|
||||
## Build Failures
|
||||
|
||||
```bash
|
||||
# Clear caches
|
||||
go clean -cache -modcache
|
||||
go mod download
|
||||
|
||||
# Rebuild
|
||||
go build ./...
|
||||
```
|
||||
|
||||
If errors persist, see [`local-ci-cd-testing.md`](local-ci-cd-testing.md) for the CI/CD pipeline that mirrors the production build.
|
||||
|
||||
## Where to Look Next
|
||||
|
||||
- **Agent-specific issues** (vibe, mistral, programmer agent) → [`AGENT_USAGE_GUIDE.md`](AGENT_USAGE_GUIDE.md)
|
||||
- **BDD-specific issues** → [`BDD_GUIDE.md`](BDD_GUIDE.md)
|
||||
- **Version/release issues** → [`version-management-guide.md`](version-management-guide.md)
|
||||
- **CI/CD issues** → [`local-ci-cd-testing.md`](local-ci-cd-testing.md)
|
||||
Reference in New Issue
Block a user