Files
pointeuse-optimisator/README.md
Antoine c1c063da51 Réglages: base_url documentée, boutons copier pour les URLs Tasker, saisie horaire native
Documente la clé base_url (schéma/domaine) déjà supportée par config.json pour les
liens email et URLs de présence, et ajoute un bouton "Copier" à côté de chaque URL
arrivée/départ. Passe aussi les champs horaires du tableau hebdomadaire en <input
type="time"> et journalise l'IP source des appels de présence Tasker.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 17:13:18 +02:00

135 lines
4.7 KiB
Markdown

# pointeuse-optimisator
Saisie des horaires de travail avec calcul en temps réel de l'heure de sortie optimale pour finir la semaine à **exactement 0h d'heures supplémentaires**.
![Interface principale](docs/screenshot.png)
---
## Démarrage rapide
Avant le premier lancement, copie et adapte le fichier de config (voir
[Configuration](#configuration) plus bas) :
```bash
cp data/config.example.json data/config.json
```
Pour surcharger `compose.yml` localement (ports, variables d'env, volumes...) sans
modifier le fichier versionné, crée un `compose.override.yml` — il est chargé
automatiquement par `docker compose` et déjà ignoré par git.
---
## Principe
La semaine cible est **39h** (7h48 / jour). Les directives imposent des plages de présence minimum :
| Demi-journée | Plage minimale |
|---|---|
| Matin | 09:00 → 12:00 |
| Après-midi | 14:00 → 17:00 |
Ces horaires sont réglables par utilisateur depuis la page **Réglages** de l'app (voir
[Configuration](#configuration)).
Quand un écart apparaît, l'outil ne le reporte pas d'un coup sur la fin de la journée en
cours : il **répartit le manque à parts égales sur toutes les demi-journées restantes**
de la semaine (matin et après-midi, aujourd'hui compris), pour un rattrapage progressif
et confortable plutôt qu'un rush le soir même. Si le rythme normal suffit déjà à rentrer
dans les clous, aucune préconisation n'est affichée.
---
## Ce que tu vois dans le tableau
| Colonne | Ce qu'elle dit |
|---|---|
| **Travaillé** | Heures effectivement saisies ce jour |
| **Δ jour** | Écart par rapport aux 7h48 dus (affiché dès qu'une heure est enregistrée) |
| **Δ sem.** | Solde cumulé depuis lundi — visible uniquement quand la journée est complète et sans jour manquant |
| **Fin cible** | Préconisation de sortie **M** (matin) et/ou **A** (après-midi) pour cette demi-journée — vide si le rythme normal suffit |
Les plages qui ne respectent pas les minimums sont signalées en rouge dès la saisie.
Le bandeau au-dessus du tableau ajoute, quand il reste du retard à rattraper, une ligne
**Reste à faire** : le total encore dû, le nombre de demi-journées restantes, et la part
supplémentaire moyenne à ajouter sur chacune.
---
## Lancement
```bash
docker compose up -d
```
Ouvre [http://localhost:8000](http://localhost:8000).
Les données (pointages, congés, comptes) sont stockées dans `data/` et ignorées par git.\
Seul `data/config.example.json` est versionné.
---
## Configuration
`data/config.json` (voir `data/config.example.json`) :
```json
{
"heures_semaine": 39.0,
"jours_par_semaine": 5,
"log_level": "DEBUG",
"allowed_email_domain": "exemple.fr",
"base_url": "https://pointeuse.exemple.fr",
"mail_from": "no-reply@exemple.fr",
"smtp": {
"host": "smtp.exemple.fr",
"port": 587,
"user": "no-reply@exemple.fr",
"password": "change-moi",
"use_tls": true
}
}
```
- `heures_semaine` — heures hebdomadaires visées (ex: `39.0`).
- `jours_par_semaine` — nombre de jours travaillés dans la semaine (ex: `5`). Le quota quotidien est calculé : `heures_semaine ÷ jours_par_semaine` (39h / 5 = 7h48/jour).
- `log_level` — `DEBUG`, `INFO`, `WARNING` ou `ERROR`. Contrôle la verbosité des logs (`docker logs`).
- `allowed_email_domain` — seules les adresses de ce domaine peuvent se connecter.
- `base_url` — schéma + domaine (ex: `https://pointeuse.exemple.fr`, sans `/` final) utilisés
pour construire les liens envoyés par email (magic link) et les URLs Tasker/Automation
affichées dans Réglages. Si vide, ces URLs sont dérivées de la requête entrante (Host header)
quand celui-ci correspond à `localhost` ou à `allowed_email_domain` ; sinon l'envoi d'email est
refusé par sécurité (anti open-redirect). **Toujours renseigner `base_url` en production.**
- `mail_from` — adresse expéditrice des emails de connexion.
- `smtp` — serveur relais utilisé pour l'envoi (host, port, identifiants, TLS).
Les rappels ntfy (topic, serveur, plage horaire) et les **plages horaires** (bornes de
présence obligatoire matin/après-midi, voir [Principe](#principe), et heure de reprise
par défaut de l'après-midi) se règlent **par utilisateur** depuis la page **Réglages**
de l'app, pas dans `config.json`. Modifier ses plages change, pour ce compte uniquement,
les avertissements de saisie, les stats de conformité et les préconisations de rattrapage.
---
## Tests
```bash
docker compose run --rm pointeuse pytest -v
```
---
## Congés
Trois boutons par ligne : **MA** (matin), **AM** (après-midi), **J** (journée entière).\
Ils réduisent les heures dues et recalculent les préconisations **Fin cible** pour les
demi-journées restantes.
---
## Stack
`FastAPI` · `HTMX` · `Jinja2` · fichiers JSON · `Docker`