Corrections des numéros d'ADR décalés : - ADR-014 → ADR-012 (Frontend Mobile) - ADR-016 → ADR-014 (Organisation Monorepo) - ADR-012 → ADR-010 (Architecture Backend) - ADR-013 → ADR-011 (ORM et Accès Données) - ADR-015 → ADR-013 (Stratégie Tests) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
261 lines
8.8 KiB
Markdown
261 lines
8.8 KiB
Markdown
# 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-012](docs/adr/012-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-014](docs/adr/014-organisation-monorepo.md) for monorepo organization rationale.
|
|
|
|
## Backend Architecture
|
|
|
|
**Modular monolith** with clear module separation ([ADR-010](docs/adr/010-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-011](docs/adr/011-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-013](docs/adr/013-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/<domain>/<feature>.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-010](docs/adr/010-architecture-backend.md): Backend architecture (modular monolith)
|
|
- [ADR-011](docs/adr/011-orm-acces-donnees.md): Data access (sqlc)
|
|
- [ADR-014](docs/adr/014-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+
|