4 Commits

Author SHA1 Message Date
5907c9aeaf fix(M8): corrections d'audit FIXME_M8 — appariement, date, déterminisme, validateur
Quatre corrections bloquantes/majeures de l'audit FIXME_M8 :
- Appariement un-à-un déterministe (consommation du candidat sélectionné) ;
  1 réel / 2 théoriques → 1 REMOVED, 2 réels / 1 théorique → 1 ADDED.
- Filtrage strict par date : les cours réels hors target_date sont exclus
  du matching avec un warning logé (décision architecte : pas d'exception).
- Déterminisme des détails : formatage via sorted(set(...)) au lieu de
  set(...) brut, indépendant de PYTHONHASHSEED.
- Validateur AgendaChange strict : ADDED = lesson seule, REMOVED =
  theoretical_lesson seule, MODIFIED = les deux requis.
- Comparaison à la minute près dans _is_modified (cohérent avec _matches).
- Documentation §8.4/§8.5 alignée avec l'implémentation (tolérance 15 min,
  API compare(), normalize_subject référencé, appariement consommé).

Co-authored-by: opencode/coder <coder@agents.invalid>
Co-authored-by: opencode/tech-writer <tech-writer@agents.invalid>
2026-09-07 15:59:17 +02:00
292aef4f5b fix(M3): immuabilité et validation des modèles — correction des écarts FIXME_M3
Immuabilité :
- Collections des modèles frozen : list → tuple (Lesson, TheoreticalLesson,
  SchoolEvent, AgendaDiff, Homework, XmppMessage, ExternalInfo)
- Gel de HomeworkBlock et ExternalInfo (sous-modèles imbriqués dans contrats)
- Valeurs par défaut immuables : Field(default=(), ...)

Validation de domaine :
- TheoreticalLesson.day_of_week : Field(ge=0, le=6)
- Lesson/TheoreticalLesson : start < end (validateur de modèle)
- SchoolEvent : from_date <= to_date
- AgendaChange : cohérence type/payload (ADDED/MODIFIED → lesson,
  REMOVED → theoretical_lesson)
- CalDAVSyncResult : compteurs Field(ge=0) sur added/updated/removed

Tests : 66 tests (construction/sérialisation, immuabilité, invariants)
couvrant le gel, la mutabilité légitime, et les cas invalides par invariant.

Co-authored-by: opencode/coder <coder@agents.invalid>
Co-authored-by: opencode/test-engineer <test-engineer@agents.invalid>
2026-09-06 12:36:27 +02:00
2e7dfe6e46 feat(M3): modèles de données Pydantic (22 modèles, 10 modules)
Modèles créés :
- models/agenda.py : Status, LessonStatus, HomeworkBlock, Lesson (frozen),
  SchoolEventKind, SchoolEvent (frozen), TheoreticalLesson (frozen)
- models/homework.py : Homework (frozen)
- models/message.py : MessageType, Message (frozen)
- models/blog.py : BlogArticle (frozen), ExternalInfo (mutable)
- models/diff.py : AgendaChangeType, AgendaChange (frozen), AgendaDiff (frozen)
- models/pronote.py : PronoteData (mutable)
- models/sync.py : CalDAVSyncStatus, CalDAVSyncPlan, CalDAVSyncResult (mutable)
- models/synthesis.py : SynthesisInput, SynthesisResult (mutable)
- models/xmpp.py : XmppMessage (frozen, external_info: ExternalInfo | None)
- models/__init__.py : ré-export des 22 modèles via __all__

Conventions appliquées :
- Pydantic v2 : model_config = ConfigDict(frozen=True), pas de json_encoders
- StrEnum au lieu de (str, Enum) (ruff UP042)
- Alias _date/_time pour éviter collision champ date/type date
- Sphinx/reST docstrings sur toutes les classes
- TODO.md : 11 items M3 cochés

Validations (@verifier) :
- ruff check : PASS (0 error)
- ruff format --check : PASS (10 fichiers)
- mypy strict : PASS (10 fichiers)
- bandit : PASS (0 issue)
- import 22 modèles : OK
- sérialisation JSON (frozen + mutable) : OK
- frozen immuable, PronoteData/CalDAVSyncResult mutable : OK
- StrEnum isinstance str : OK
- pytest : 0 test (infrastructure OK)

Co-authored-by: OpenCode/orchestrator <opencode-orchestrator@agents.invalid>
2026-09-05 23:21:39 +02:00
a2efd61c4e Scaffold: préparation du projet pronote-sync
- Guide de développement (GUIDE_DEV_PYTHON.md) : spécification complète
- TODO.md : 15 jalons de développement (M1-M15) avec étapes et critères d'acceptation
- AGENTS.md : guide de contribution pour agents et développeurs
- pyproject.toml : configuration projet (dépendances, ruff, mypy strict, pytest)
- .gitignore : exclusion venv, bytecode, .env, caches, state files
- .env.example : template des variables d'environnement (placeholders)
- Structure du package pronote_sync/ (14 sous-packages avec __init__.py)
- tests/ avec conftest.py et fixtures/
- Environnement virtuel .venv/ (Python 3.14)
2026-09-05 18:45:43 +02:00