Aller au contenu

Architecture du temps et de la météo

La migration 0026_time_weather crée le singleton time_weather_config et les créneaux weather_schedule. L'API est la source de vérité. ensure_schedule supprime les heures passées et complète de manière déterministe l'horizon jusqu'à 168 heures futures. Le créneau précédent est conservé une heure supplémentaire pour fournir la source de la transition du créneau courant.

Le générateur pondère les états selon la saison australe puis choisit uniquement dans le graphe TRANSITIONS. Une édition vérifie à la fois précédent → cible et cible → suivant. Le créneau courant, défini par l'heure UTC tronquée, ne peut jamais être modifié. Chaque WeatherEntryRead expose allowed_weather, intersection ordonnée des états accessibles depuis le créneau précédent et capables d'atteindre le suivant. Les deux administrations utilisent directement cette liste ; l'API conserve la même validation sous verrou comme protection contre une modification concurrente.

La ressource medusa-time-weather récupère l'état toutes les 5 secondes et le diffuse à tous les clients. Le client utilise le temps Unix synchronisé pour calculer une horloge continue : facteur 30 en mode GTA, facteur 1 plus le décalage Europe/Paris en temps réel. Le changement météo utilise SetWeatherTypeOvertimePersist durant les 600 premières secondes du créneau, puis SetWeatherTypeNowPersist. Le client mémorise l'identifiant du créneau appliqué afin qu'une resynchronisation périodique ne redémarre pas la transition en cours. Une fois par minute en jeu, il publie la date, l'heure et le mode via l'événement client local medusa:hud:datetime. Il ne possède plus de page NUI : le rendu appartient à medusa-hud. L'écoulement entre deux synchronisations est mesuré avec GetGameTimer à partir de l'instant de réception du paquet. Le client ne dépend donc pas de l'horloge cloud locale pour choisir le créneau météo ou calculer l'heure. Les rafraîchissements concurrents côté serveur sont regroupés dans une promesse unique ; une mutation depuis F10 attend sa diffusion avant d'annoncer son succès. Le client FiveM n'exposant pas os, la date réelle est dérivée du timestamp Unix par une conversion arithmétique vers le calendrier grégorien. Le jour de semaine conserve la convention 1 = dimanche attendue par le HUD. Aucun appel à os.date n'est effectué côté client.

Les routes web sont sous /admin/time-weather; les routes internes sous /internal/v1/time-weather. Les mutations F10 sont réautorisées à partir des rôles Discord et auditées avant de demander une diffusion immédiate à la ressource.

Les deux clients d'administration transforment la liste horaire renvoyée par l'API en matrice jour/heure dans le fuseau Europe/Paris. Le rendu est volontairement borné aux sept dates locales allant de la date serveur courante à J+6. Les cellules sans créneau API, notamment les heures déjà passées du premier jour, sont affichées comme indisponibles et ne produisent aucune mutation. À chaque rendu, les clients calculent la clé jour/heure de server_time dans Europe/Paris et appliquent aria-current="time" ainsi que la classe visuelle active à l'unique cellule associée.

Le bootstrap serveur autorise un retry transitoire borné ; les polls de cinq secondes restent à une seule tentative. Une promesse unique empêche les chevauchements, le dernier cache valide est conservé et les journaux n'émettent qu'une transition de panne puis de rétablissement.