urn:ietf:params:jmap:calendars), avec des événements en objets JSCalendar (RFC 8984). Les mêmes données sont servies en CalDAV : un stockage, deux protocoles.
Objets et méthodes
CalendarEvent/counter est un ajout OxiMail pour le comptage d’occurrences.
La récurrence
- La propriété est
recurrenceRules(au pluriel, RFC 8984), toujours. - Les événements récurrents se développent par une seule autorité d’énumération des occurrences, partagée par les requêtes JMAP, les filtres
time-rangeCalDAV, le libre/occupé et les alarmes : une occurrence existe à l’identique partout, y compris à travers les changements d’heure (le développement est ancré au fuseau local de l’événement). - Les exceptions par occurrence sont indexées par l’heure civile locale ; une exception créée dans un protocole est honorée (et protégée par des ETag en empreinte de contenu) dans l’autre.
- Une
RRULEimportée que le modèle ne peut pas représenter est conservée telle quelle et signaléehasUnmodeledRecurrenceen lecture : jamais de règle à moitié convertie.
Les fuseaux horaires
start est un LocalDateTime ; le fuseau vit dans timeZone (un instant UTC est stocké comme heure locale + Etc/UTC, jamais un start suffixé Z). Les événements journée entière utilisent showWithoutTime. Un événement flottant se résout par la chaîne de repli fuseau de l’événement → fuseau de l’utilisateur → défaut de l’organisation → UTC (travail collaboratif).
La planification (iTIP)
Créer un événement avec des participants déclenche le courrier d’invitation, sous deux règles dures : seulement quand l’organisateur se résout vers un compte local (RFC 5546 : seul le serveur de l’organisateur envoie), et seulement après la validation de la transaction (unstateMismatch n’émet rien). REPLY et CANCEL suivent la même discipline ; les invitations et réponses entrantes sont traitées à l’ingestion et produisent des objets CalendarEventNotification. La modification d’un bénéficiaire sur un agenda partagé notifie le propriétaire de la même façon.
La disponibilité
Principal/getAvailability compose le temps occupé depuis les agendas auxquels le sujet est abonné et dont includeInAvailability vaut all ou attending, en renvoyant des objets BusyPeriod. La confidentialité est étagée : les événements secret cachent entièrement leur temps occupé, les événements private donnent leur temps mais jamais leurs détails, et les détails ne sont fournis que sous showDetails et un vrai droit de lecture. Un appelant sans droit de libre/occupé sur aucun agenda du sujet reçoit un forbidden par identifiant, pas une réponse vide.
Les alertes
alerts accepte des déclencheurs relatifs (relativeTo: "start"/"end") et absolus (when). Elles sonnent côté serveur (push / notification), une fois par occurrence. Les VALARM font l’aller-retour avec les clients CalDAV ; les exports de flux ICS publics n’en portent volontairement aucun.
Les règles de rigueur (identifiants inconnus dans notFound, invalidProperties plutôt qu’une coercition, stateMismatch sur ifInState) sont identiques à la surface courrier.