# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview RoadWave is a geo-localized audio social network for road users (drivers, pedestrians, tourists). Users listen to audio content (podcasts, audio guides, ads, live radio) based on their geographic location and interests. **Tech Stack**: - Backend: Go 1.21+ with Fiber framework - Mobile: Flutter (see [ADR-014](docs/adr/014-frontend-mobile.md)) - Database: PostgreSQL 16+ with PostGIS extension - Cache: Redis 7+ with geospatial features - Auth: Zitadel (self-hosted IAM) - Data Access: sqlc for type-safe SQL code generation - Streaming: HLS protocol with Opus codec ## Monorepo Structure This is a monorepo organized as follows: ``` /backend → Go backend API (modular monolith) /mobile → Flutter mobile app /features → Shared BDD Gherkin features (test specs) /docs/adr → Architecture Decision Records /shared → Shared code and API contracts /docker → Docker configuration files ``` **Important**: BDD test features (`.feature` files) are shared in `/features`, but each component implements its own step definitions: - Backend step definitions: `backend/tests/bdd/` - Mobile step definitions: `mobile/tests/bdd/` See [ADR-016](docs/adr/016-organisation-monorepo.md) for monorepo organization rationale. ## Backend Architecture **Modular monolith** with clear module separation ([ADR-012](docs/adr/012-architecture-backend.md)): ``` backend/internal/ ├── auth/ # JWT validation, Zitadel integration ├── user/ # User profiles, interest gauges ├── content/ # Content CRUD, metadata ├── geo/ # Geospatial search, recommendation algorithm ├── streaming/ # HLS generation, transcoding ├── moderation/ # Content moderation, reporting workflow ├── payment/ # Mangopay integration └── analytics/ # Listening metrics, interest gauge evolution ``` **Module pattern**: Each module follows `handler.go` → `service.go` → `repository.go`. **Database access**: Uses `sqlc` ([ADR-013](docs/adr/013-orm-acces-donnees.md)) for type-safe Go code generation from SQL queries. This allows writing complex PostGIS spatial queries while maintaining compile-time type safety. ## Development Commands **IMPORTANT**: Always use `docker compose` (not `docker-compose`) as per user preferences. All commands must be run from the **monorepo root**: ### Development ```bash make init # Initialize project (install tools, setup .env) make dev # Start backend with hot reload (Air) make docker-up # Start all services (API, PostgreSQL, Redis, Zitadel, Adminer) make docker-down # Stop all Docker services make docker-logs # Show Docker logs ``` Services after `make docker-up`: - API: http://localhost:8080 - Zitadel: http://localhost:8081 - Adminer: http://localhost:8082 ### Testing **Test Strategy** ([ADR-015](docs/adr/015-strategie-tests.md)): - Unit tests: Testify (80%+ coverage target) - Integration tests: Testcontainers (for PostGIS queries) - BDD tests: Godog/Gherkin (user stories validation) ```bash make test # Run all tests (unit + integration + BDD) make test-unit # Unit tests only (fast, ~30s) make test-integration # Integration tests with Testcontainers make test-bdd # BDD tests with Godog (Gherkin features) make test-coverage # Generate coverage report (coverage.html) ``` **Running a single test**: ```bash cd backend go test -v -run TestFunctionName ./path/to/package ``` **Running a single BDD feature**: ```bash godog run features/path/to/feature.feature ``` ### Database ```bash make migrate-up # Apply all migrations make migrate-down # Rollback last migration make migrate-create name=add_users # Create new migration make migrate-version # Show current migration version make sqlc-generate # Generate Go code from SQL queries ``` **After modifying SQL queries** in `backend/queries/*.sql`, always run `make sqlc-generate` to regenerate Go code. ### Build & Code Quality ```bash make build # Build production binary (backend/bin/api) make lint # Run golangci-lint make format # Format Go code (gofmt) make deps # Download and tidy Go dependencies make clean # Clean build artifacts ``` ### Documentation ```bash make docs-serve # Generate BDD docs and serve MkDocs (http://localhost:8000) make bdd-docs # Same as docs-serve make docs-pdf # Generate PDF of all documentation make docs-clean # Remove generated docs and PDF ``` ## Working with sqlc When adding or modifying database queries: 1. Write SQL query in `backend/queries/*.sql`: ```sql -- name: GetContentNearby :many SELECT id, title, ST_Distance(location, $1::geography) as distance FROM contents WHERE ST_DWithin(location, $1::geography, $2) ORDER BY distance LIMIT $3; ``` 2. Run code generation: ```bash make sqlc-generate ``` 3. Use generated type-safe Go code: ```go contents, err := q.GetContentNearby(ctx, location, radius, limit) ``` ## Writing BDD Tests BDD features use Gherkin syntax ([ADR-007](docs/adr/007-tests-bdd.md)): 1. Write feature in `/features//.feature` 2. Implement step definitions in `backend/tests/bdd/` for API testing 3. Run with `make test-bdd` Example feature: ```gherkin Feature: Geolocalised recommendation Scenario: Tourist near a monument Given a user with "tourism" interest at 80% And a GPS position 100m from the Eiffel Tower When the system calculates recommendations Then the audio guide "Histoire de la Tour Eiffel" is in first position ``` ## Key Architectural Decisions All technical decisions are documented in Architecture Decision Records (ADRs) in `/docs/adr/`: - [ADR-001](docs/adr/001-langage-backend.md): Backend language (Go) - [ADR-002](docs/adr/002-protocole-streaming.md): Streaming protocol (HLS) - [ADR-005](docs/adr/005-base-de-donnees.md): Database (PostgreSQL + PostGIS) - [ADR-008](docs/adr/008-authentification.md): Authentication (Zitadel) - [ADR-012](docs/adr/012-architecture-backend.md): Backend architecture (modular monolith) - [ADR-013](docs/adr/013-orm-acces-donnees.md): Data access (sqlc) - [ADR-016](docs/adr/016-organisation-monorepo.md): Monorepo organization **When making architectural decisions**, check if there's an existing ADR or create a new one following the established pattern. ## Recommendation Algorithm Core feature combining geolocation and interest matching: - **Geographic priority**: GPS point > city > department > region > country - **Interest gauges**: Dynamic scores per category (automobile, travel, music, etc.) - **Combined scoring**: Distance + interest matching - **Cache**: Redis geospatial for performance (`GEORADIUS`) The algorithm is implemented in `backend/internal/geo/` and uses PostGIS functions like `ST_DWithin`, `ST_Distance`. ## Common Patterns ### Module Structure Each backend module follows this pattern: ``` internal/modulename/ ├── handler.go # HTTP handlers (Fiber routes) ├── service.go # Business logic ├── repository.go # Database access (sqlc generated code) └── models.go # Domain models (if needed) ``` ### Error Handling Use the custom error package in `backend/pkg/errors/` for consistent error handling across the application. ### Configuration Environment variables are loaded via `backend/pkg/config/`. Development config is in `backend/.env` (copied from `.env.example` during `make init`). ## PostGIS Spatial Queries Example patterns for geospatial operations: ```sql -- Find content within radius WHERE ST_DWithin(location::geography, ST_MakePoint($lon, $lat)::geography, $radius_meters) -- Calculate distance SELECT ST_Distance(location::geography, ST_MakePoint($lon, $lat)::geography) as distance -- Order by proximity ORDER BY location <-> ST_MakePoint($lon, $lat)::geography ``` ## Testing with Testcontainers Integration tests that require PostGIS use Testcontainers to spin up a real PostgreSQL+PostGIS instance: ```go // backend/tests/integration/geo_test.go // Uses testcontainers to validate complex spatial queries ``` This ensures PostGIS queries work correctly without mocking. ## Authentication Flow Zitadel handles authentication ([ADR-008](docs/adr/008-authentification.md)): - Self-hosted on OVH (France data sovereignty) - OAuth2 PKCE for mobile apps - JWT validation in backend using zitadel-go SDK - Shares PostgreSQL database with RoadWave (separate schema) ## Performance Targets See [TECHNICAL.md](TECHNICAL.md) for detailed metrics: - API latency p99: < 100ms - Audio start time: < 3s - Target availability: 99.9% - Concurrent connections/server: 100K+