# AGENTS.md Ce fichier fournit des directives et des consignes pour les agents d'intelligence artificielle et assistants de développement (multi-modèles et multi-fournisseurs) travaillant sur ce dépôt. Pour une présentation complète de l'architecture, de la configuration et du guide de démarrage, se référer à [docs/onboarding.md](docs/onboarding.md). ## Commands ```bash # Setup (first time) python -m venv .venv .venv/bin/pip install -r requirements.txt # Run dev server .venv/bin/python run.py # Run all tests .venv/bin/python -m pytest # Run a single test file .venv/bin/python -m pytest tests/test_time_calc.py -v # Run a single test .venv/bin/python -m pytest tests/test_routes.py::test_create_entry -v # Production (systemd) — déployé dans /var/www/tableau-de-bord-pro/ sudo systemctl edit --full tableau-de-bord-pro # configurer SECRET_KEY sudo systemctl restart tableau-de-bord-pro # Qualité du code (Ruff) .venv/bin/ruff check . .venv/bin/ruff format --check . .venv/bin/ruff format . # Découverte des modèles OpenCode (configuration environnementale hors dépôt) grep -A 1 -B 1 subagent /home/antoine/.config/opencode/opencode.json ``` ## Variables d'environnement - `SECRET_KEY` : requis en production (défaut `dev-secret-change-in-prod` en dev) ## Git & Conventions de Commit - **Politique Git** : Les commits intermédiaires générés par les agents d'IA doivent être non signés en utilisant l'option `git -c commit.gpgsign=false commit -m "..."` (car pinentry est inaccessible dans cet environnement). L'utilisateur effectuera un amend signé (`git commit --amend -S`) du commit final lorsqu'il sera disponible. - **Convention de trailers** : Chaque commit réalisé par un agent d'IA doit inclure le trailer suivant à la fin du message de commit pour identifier le modèle utilisé : ```text Co-authored-by: Fournisseur/Modèle ``` *Exemple :* `Co-authored-by: Anthropic/Claude-3.5-Sonnet ` ou `Co-authored-by: Google/Gemini-3.5-Flash `. ## Architecture Flask app using the factory pattern (`create_app()` in `app/__init__.py`). The DB is SQLite via SQLAlchemy, stored in `instance/worklog.db`. All vehicle/journey/tax configuration lives in `config.toml` (loaded at startup into `app.config["TOML"]`), not in the database. **Data flow:** - `config.toml` → `app/config_loader.py` → accessed via `get_vehicles()`, `get_journeys()`, `get_bareme(year, cv)` - `app/models.py` defines `WorkEntry` (one row per day), `TimeSlot` (N plages horaires per entry), `LeaveBalance` (annual quotas) - `app/business/` contains pure functions with no Flask dependencies: `time_calc.py` (minutes/reference), `travel_calc.py` (km, CO2, frais réels), `leave_calc.py` (solde congés/RTT) - Routes in `app/routes/` use business functions and config_loader, then render Jinja2 templates **Key domain rules:** - Day types: `WORK | TT | GARDE | ASTREINTE | FORMATION | RTT | CONGE | MALADE | FERIE` - Types without journey: `TT, MALADE, CONGE, RTT, FERIE` (see `day_types_without_journey()`) - Work reference: 7h45 (465 min) for WORK/TT/FORMATION, 10h (600 min) for GARDE, 0 for absences - `total_minutes()` on `WorkEntry` sums `TimeSlot` durations, handles midnight crossing - Frais réels: uses `bareme_kilometrique` tranches from config.toml; `km_max = 0` means "no upper limit". Keys: `cv_3`, `cv_4`, `cv_5`, `cv_6`, `cv_7plus`. Vehicles with `fuel = "electric"` get +20% applied in `compute_frais_reels(..., electric=True)`. **Frontend:** Tailwind CSS CDN + HTMX in `base.html`. No build step. Design system defined via CSS variables (`--ink`, `--amber`, `--sage`, `--rust`, `--cream`) and custom classes (`.card`, `.card-*`, `.btn-primary`, `.field-input`, `.font-display`, `.font-data`) — all in `base.html