Added fonts
Added license file and updated README
This commit is contained in:
418
README.fr.md
Normal file
418
README.fr.md
Normal file
@@ -0,0 +1,418 @@
|
||||
# Pardis
|
||||
|
||||
PWA hors ligne de suivi des heures de chantier. Tant que l’application est ouverte,
|
||||
elle peut démarrer automatiquement la journée et proposer sa clôture. Chaque tâche
|
||||
commence là où la précédente s’est terminée. Les journées clôturées ont un
|
||||
récapitulatif concis, prêt à être recopié dans un registre papier.
|
||||
|
||||
Conçue pour l’extérieur : contraste élevé, grandes zones tactiles et utilisable
|
||||
avec des gants. Les données sont enregistrées localement dans IndexedDB. Une
|
||||
synchronisation facultative chiffrée de bout en bout les partage entre appareils
|
||||
autorisés, sans inscription par e-mail ni mot de passe.
|
||||
|
||||
Version anglaise : [README.md](README.md).
|
||||
|
||||
## Développement
|
||||
|
||||
```sh
|
||||
npm install
|
||||
npm run dev # http://localhost:5173
|
||||
npm test # tests unitaires et de régression IndexedDB
|
||||
npm run check # vérification Svelte
|
||||
npm run build # build de production dans dist/
|
||||
npm run validate # tests, vérification Svelte et build complet de la PWA
|
||||
npx playwright install chromium # installer le navigateur pour les tests UI
|
||||
npm run test:e2e # profils vierges, données synthétiques et test PWA hors ligne
|
||||
npm run validate:all # inclure les tests navigateur dans la validation complète
|
||||
```
|
||||
|
||||
## Exporter et importer les données
|
||||
|
||||
Dans **Réglages → Gérer les données et sauvegardes**, l’écran **Données et
|
||||
sauvegardes** regroupe l’export, l’import, la vérification des sauvegardes et la
|
||||
durée de conservation. Le rappel **Sauvegarder** ouvre aussi cet écran.
|
||||
|
||||
Les données restent disponibles dans le navigateur sur cet appareil. La synchronisation
|
||||
chiffrée peut être activée séparément pour les partager avec vos autres appareils.
|
||||
Effacer les données du site ou perdre l’appareil peut faire perdre l’historique :
|
||||
gardez une copie vérifiée du fichier exporté sur un autre support.
|
||||
|
||||
**Exporter les données** télécharge un fichier
|
||||
`pardis-AAAA-MM-JJ.json`. Il contient toutes les journées conservées, leurs postes
|
||||
et les réglages enregistrés. L'export fonctionne hors ligne et ne modifie pas les
|
||||
données de l'appareil. Les identifiants internes des postes sont recréés à l'import.
|
||||
|
||||
Pour restaurer une sauvegarde, choisissez **Importer un fichier…** puis vérifiez
|
||||
le nom du fichier, les compteurs et les éventuels ajustements signalés. Deux modes
|
||||
sont disponibles :
|
||||
|
||||
- **Fusionner** ajoute seulement les dates absentes. Une date déjà présente est
|
||||
conservée intégralement, même si le fichier contient une autre version de ses
|
||||
postes. Les réglages locaux sont conservés. Importer deux fois le même fichier
|
||||
ne crée pas de doublons.
|
||||
- **Remplacer tout** demande une confirmation, puis remplace toutes les journées,
|
||||
tous les postes et les réglages, y compris une journée locale en cours. Si le
|
||||
fichier ne contient pas de réglages, les valeurs par défaut sont rétablies.
|
||||
|
||||
Les journées importées sont enregistrées comme terminées. Pour une journée
|
||||
exportée en cours, le dernier poste est arrêté à l'heure de l'export : le temps
|
||||
écoulé est conservé. Les intervalles sans travail déjà présents sont conservés.
|
||||
Une sauvegarde vide est valide et peut servir à restaurer un appareil vide.
|
||||
|
||||
Le format JSON est identifié par `format: "timelog-export"` et `version: 2`. Le format v1 reste importable. Les anciennes applications refusent le format v2 pour éviter de transformer les pauses en travail.
|
||||
Les fichiers étrangers, versions non prises en charge, dates en double et réglages
|
||||
invalides sont refusés. Les postes inutilisables et les corrections de plages
|
||||
horaires sont signalés avant confirmation. La limite de taille est de 20 Mo.
|
||||
L'écriture est transactionnelle : un échec annule le remplacement ou la fusion
|
||||
dans son intégralité. Le récapitulatif, le thème et les suggestions sont ensuite
|
||||
actualisés sans recharger la page.
|
||||
|
||||
Dans **Durée de conservation**, **Conserver (jours)** détermine les journées
|
||||
anciennes proposées à la purge. Modifier cette durée ne supprime rien ; la purge
|
||||
automatique est désactivée. L’historique conservé alimente les suggestions et les
|
||||
statistiques. La dernière journée terminée et les journées actives sont conservées.
|
||||
|
||||
**Purger maintenant** présente les dates concernées et demande confirmation.
|
||||
Une sauvegarde locale est conservée avant la suppression ; **Récupérer la
|
||||
sauvegarde avant purge** permet de la fusionner ou de remplacer les données,
|
||||
puis de l’exporter après restauration. Cette copie est remplacée à la prochaine
|
||||
purge et disparaît si les données du site sont effacées : un fichier externe
|
||||
reste nécessaire.
|
||||
|
||||
Les tests d'import/export couvrent le format, les réglages, la fidélité des durées,
|
||||
les fichiers invalides, la fusion, le remplacement et l'annulation transactionnelle
|
||||
sur une IndexedDB simulée. `src/lib/fixtures/backup.json` est le jeu d'essai fourni ;
|
||||
il n'est pas publié avec l'application.
|
||||
|
||||
## Journées, reprise et historique
|
||||
|
||||
- Une journée oubliée est clôturée au retour dans l'application, à son heure de
|
||||
fin prévue (prolongations comprises), sans jamais précéder la dernière activité
|
||||
enregistrée. Cette heure est une estimation : l'application ne mesure pas le
|
||||
travail lorsqu'elle est fermée. Le dernier poste conserve ainsi sa durée jusqu'à
|
||||
cette limite, au lieu d'être ramené à zéro.
|
||||
- Une journée terminée aujourd’hui propose **Reprendre la journée** avec confirmation : prolonger le dernier poste, ou créer une pause jusqu’à maintenant (choix initial). Un dernier repas ou une pause garde sa nature ; le travail reprend dans un nouveau poste. Les journées passées se corrigent par **Voir les détails → Corriger cette journée**.
|
||||
- La création, la clôture et la reprise sont transactionnelles. Les actions
|
||||
simultanées sur le même poste ne créent pas de doublons ; une journée clôturée
|
||||
ne peut pas recevoir un nouveau poste actif. La purge épargne les journées
|
||||
actives et conserve toujours la dernière journée terminée.
|
||||
- Les horaires de déjeuner affichent un rappel puis une heure indicative de
|
||||
reprise. Les transitions restent manuelles sauf si l'option **Pause déjeuner**
|
||||
est activée dans les automatismes.
|
||||
- Dans **Récap**, le sélecteur **Journée à consulter** permet d'afficher et de copier
|
||||
chaque journée terminée encore conservée, y compris les journées importées.
|
||||
|
||||
Les tests couvrent notamment les clôtures oubliées, les reprises, les appels
|
||||
concurrents, les retours d'horloge, les échecs transactionnels et la conservation.
|
||||
|
||||
## Automatismes
|
||||
|
||||
Dans **Réglages → Automatismes**, chaque comportement a son interrupteur :
|
||||
|
||||
| Option | Comportement |
|
||||
| --- | --- |
|
||||
| Ouverture | Démarrer aux horaires et jours prévus. Activée par défaut, comme auparavant. |
|
||||
| Début de journée | Au bouton « Arrivé sur site », proposer la dernière tâche de travail de la précédente journée enregistrée, hors repas et transport. |
|
||||
| Pause déjeuner | Ouvrir la pause à l'heure habituelle et reprendre la tâche précédente après la durée réglée. Reprendre le type de repas et le restaurant de la précédente journée enregistrée. |
|
||||
| Arrivée sur chantier | Lors du repas automatique, transformer un transport initial non renseigné en un transport de 1/5/15/30 minutes, selon l'arrondi, suivi de la tâche précédente. |
|
||||
| Fin de demi-journée | À la pause ou à la clôture, remplacer une plage automatique non renseignée par la dernière tâche de travail connue. Conserver tout poste manuel. |
|
||||
| Fin de journée | Clôturer à l'heure prévue sans confirmation. |
|
||||
|
||||
Les cinq nouvelles options sont désactivées par défaut. Elles sont conservées
|
||||
dans les sauvegardes et rétablies lors d'un import en remplacement. L'option
|
||||
**Arrivée sur chantier** intervient seulement avec un repas automatique.
|
||||
Sans cette estimation de transport, **Fin de demi-journée** peut remplacer le
|
||||
transport initial non renseigné par du travail sur toute la plage. Une tâche de
|
||||
travail déjà présente suffit : aucun doublon n'est ajouté à la demi-journée.
|
||||
|
||||
« Précédente » désigne la dernière journée terminée enregistrée avant la date
|
||||
courante, y compris après un week-end. La complétion utilise la dernière tâche
|
||||
de travail connue ; sans historique de travail, elle utilise **Travaux sur site**.
|
||||
Les postes produits automatiquement portent la mention **Auto**. Les corriger
|
||||
les rend manuels et les protège des déductions suivantes. Les saisies anciennes
|
||||
sans cette information sont considérées comme manuelles.
|
||||
|
||||
Une pause commencée ou corrigée manuellement n'est pas terminée par l'automatisme
|
||||
de déjeuner. Un choix manuel du type ou du restaurant est conservé. Une pause
|
||||
supprimée n'est pas recréée. Désactiver l'option arrête les transitions suivantes ;
|
||||
cela ne supprime pas les postes déjà enregistrés. Une durée de déjeuner nulle
|
||||
n'ajoute aucune pause automatique. La durée d'une pause automatique déjà commencée
|
||||
est conservée si le réglage change ensuite.
|
||||
|
||||
L'app vérifie l'horloge toutes les 30 secondes et au retour à l'écran. Une PWA
|
||||
fermée ou suspendue ne peut pas exécuter du code à heure fixe : à la réouverture,
|
||||
les étapes manquées sont rattrapées avec leurs horaires prévus, sans écraser une
|
||||
action manuelle plus tardive. Les journées déjà clôturées restent intactes et les
|
||||
dates entièrement absentes ne sont pas créées. Pour une journée sans intervention,
|
||||
activer les options voulues et ouvrir l'app au moins une fois pour cette journée.
|
||||
|
||||
Les prolongations et la reprise d'une journée sont respectées. Un démarrage
|
||||
manuel laisse au moins une heure avant une clôture automatique. Les transitions
|
||||
automatiques sont transactionnelles : une erreur annule toute l'opération et
|
||||
des appels simultanés ne créent pas de doublons.
|
||||
|
||||
## Jours non travaillés
|
||||
|
||||
Dans **Réglages → Jours non travaillés**, ajouter les dates à bloquer à l'avance.
|
||||
La liste est triée par date ; chaque date peut être modifiée ou supprimée.
|
||||
Les doublons sont refusés. Ces exceptions priment sur les jours de semaine
|
||||
habituellement travaillés et empêchent l'ouverture automatique, y compris lors
|
||||
du rattrapage à la réouverture de l'app ou hors ligne.
|
||||
|
||||
Aucune journée ni aucun poste n'est créé pour une date bloquée. Les journées
|
||||
déjà commencées ou terminées restent conservées. Dans **Journée**, le bouton
|
||||
**Démarrer quand même** permet un démarrage manuel exceptionnel.
|
||||
Retirer une date rétablit les règles habituelles de démarrage automatique.
|
||||
|
||||
La liste est enregistrée avec les réglages et incluse dans l'export des données.
|
||||
Un import en remplacement rétablit la liste de la sauvegarde ; un import en
|
||||
fusion conserve la liste locale, comme les autres réglages. Une ancienne
|
||||
sauvegarde sans cette liste la réinitialise à vide lors d'un remplacement.
|
||||
|
||||
## Corriger les postes et les journées terminées
|
||||
|
||||
Le **Total des heures de présence** exclut les pauses et le repas. Le repas reste affiché
|
||||
séparément dans le récapitulatif et le texte copié. Les totaux suivent le réglage
|
||||
d’arrondi existant.
|
||||
|
||||
Dans **Journée**, touchez un poste dans **Postes de la journée** pour modifier
|
||||
son début, sa fin, sa tâche ou son client. Les boutons **Poste ordinaire**,
|
||||
**Repas** et **Pause** permettent de choisir la nature du poste. Le type interne
|
||||
d'un transport déjà enregistré est conservé quand on corrige ses horaires ou
|
||||
son libellé.
|
||||
Les sélecteurs d'heure ne proposent pas de date : ils conservent la date du
|
||||
poste. Les minutes et les boutons d'ajustement suivent l'arrondi choisi dans
|
||||
les réglages (1, 5, 15 ou 30 minutes). Les tâches, clients et restaurants utilisent
|
||||
les mêmes suggestions et la même saisie libre que l'écran de la journée.
|
||||
Les corrections sont enregistrées ensemble avec **Enregistrer**. Annuler ne
|
||||
modifie rien ; ouvrir puis valider un horaire inchangé conserve sa valeur
|
||||
enregistrée. Le début du premier
|
||||
poste et la fin du dernier définissent les bornes de la journée. Modifier une
|
||||
limite intermédiaire ajuste la limite du poste voisin, sans chevauchement.
|
||||
La fin d'un poste encore en cours reste pilotée par les boutons de changement
|
||||
de tâche ou de clôture.
|
||||
|
||||
**Ajouter un poste oublié** permet de choisir une plage existante puis les
|
||||
horaires du poste à insérer dans cette plage. Le début et la fin sont préremplis
|
||||
avec les deux bornes connues (jusqu'à l'heure actuelle pour un poste en cours).
|
||||
Il suffit de changer une seule borne pour corriger le début ou la fin de la plage.
|
||||
Les portions avant et après sont
|
||||
conservées avec leur tâche et leur client. Par exemple, un poste 08:00–12:00
|
||||
peut devenir 08:00–09:00, une tâche oubliée 09:00–10:00, puis 10:00–12:00.
|
||||
Le bouton **Repas** permet aussi d’ajouter un déjeuner oublié et de renseigner
|
||||
panier ou restaurant ; **Pause** ajoute une pause hors repas. Pour ajouter juste
|
||||
après une frontière existante, choisissez le poste qui commence à cette frontière.
|
||||
|
||||
Dans **Récap**, choisissez la date puis **Voir les détails → Corriger cette
|
||||
journée** : les mêmes actions sont disponibles sans réouverture, même si une autre journée est en
|
||||
cours. Le récapitulatif et son texte à copier sont recalculés après chaque
|
||||
enregistrement. La suppression d'un poste demande confirmation ; le voisin
|
||||
absorbe sa durée, et le dernier poste d'une journée ne peut pas être supprimé.
|
||||
Supprimer un repas réaffecte sa durée au poste voisin et peut donc changer le
|
||||
total des heures de présence.
|
||||
|
||||
Chaque correction est transactionnelle. Les horaires inversés, les insertions
|
||||
hors de la plage choisie et les formulaires devenus périmés après une autre
|
||||
modification sont refusés sans écriture partielle.
|
||||
|
||||
## Statistiques
|
||||
|
||||
Ouvrez **Réglages → Consulter les statistiques**. Le bouton **Stats** de la barre
|
||||
du bas n'apparaît que sur cette page ; les autres écrans gardent leurs trois
|
||||
boutons habituels. La page fonctionne hors ligne. Les calculs de statistiques restent sur l’appareil ;
|
||||
la synchronisation facultative peut partager leur historique source chiffré.
|
||||
|
||||
Les filtres couvrent tout l'historique, le mois, l'année, les 30 derniers jours
|
||||
ou une plage de dates inclusive. Les journées en cours sont exclues par défaut.
|
||||
L'option pour les inclure affiche des cumuls et détails provisoires. Les moyennes
|
||||
de « Repères et observations », la médiane, les extrêmes et les profils par jour
|
||||
de semaine restent calculés sur les seules journées terminées enregistrées.
|
||||
|
||||
Les statistiques présentent :
|
||||
|
||||
- Les heures de présence hors repas et pauses, les pauses, le transport identifié, les nombres de
|
||||
journées, postes, tâches et clients.
|
||||
- Les heures de présence par client et par tâche, leurs parts des heures de présence, les nombres de
|
||||
journées concernées et les détails croisés, accessibles en ouvrant une ligne.
|
||||
- L'évolution par mois ou semaine, sans inventer des heures pour les jours absents.
|
||||
- Les journées avec repas panier ou restaurant, les restaurants fréquentés,
|
||||
les durées de pause et les journées sans pause enregistrée. Plusieurs fragments
|
||||
de repas le même jour ne créent pas plusieurs journées de repas.
|
||||
- Les moyennes, la médiane, les journées extrêmes, les principales concentrations
|
||||
de temps par client et tâche, et le détail quotidien.
|
||||
- Les clients ou restaurants non renseignés, les postes à zéro après arrondi,
|
||||
les journées vides, les plages non couvertes et les chevauchements éventuels.
|
||||
|
||||
Le calcul reprend l'arrondi du récapitulatif et exclut toujours le repas et les pauses des heures de présence.
|
||||
Seules les données encore conservées sont analysées : les jours absents ou purgés
|
||||
ne permettent pas de conclure à une absence de travail. Le transport identifié
|
||||
repose sur le type enregistré, pas sur une déduction à partir du nom de la tâche.
|
||||
|
||||
En développement, la console expose `timelog.seed()` pour générer 20 jours
|
||||
d’historique réaliste (utile pour tester le moteur de suggestions) et
|
||||
`timelog.wipe()` pour l’effacer.
|
||||
|
||||
## Déploiement
|
||||
|
||||
La pile comprend l’application statique servie par Caddy et une API de synchronisation
|
||||
facultative adossée à SQLite dans un volume persistant. Caddy obtient et renouvelle
|
||||
le certificat HTTPS. La synchronisation reste désactivée dans chaque client jusqu’à
|
||||
son activation explicite. Voir [SYNC.md](SYNC.md) pour l’association, le chiffrement,
|
||||
la récupération, les quotas et les sauvegardes du serveur.
|
||||
|
||||
```sh
|
||||
cp .env.example .env
|
||||
$EDITOR .env # renseigner SITE_ADDRESS, ACME_EMAIL et TRUST_PROXY
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Prérequis :
|
||||
|
||||
- `SITE_ADDRESS` doit déjà pointer vers le serveur.
|
||||
- `ACME_EMAIL` est obligatoire et doit être une adresse de contact valide.
|
||||
- Les ports **80 et 443** doivent être accessibles depuis Internet. Le port 80 est
|
||||
obligatoire : le défi ACME l’utilise pour vérifier la propriété du domaine.
|
||||
|
||||
Les certificats sont stockés dans le répertoire monté `./caddy/data`. Conservez-le :
|
||||
sans lui, Caddy redemande un certificat à chaque recréation et atteindra la limite
|
||||
de requêtes de Let's Encrypt après quelques redémarrages.
|
||||
|
||||
Pour mettre à jour, récupérez les changements et reconstruisez l’image :
|
||||
|
||||
```sh
|
||||
git pull && docker compose up -d --build
|
||||
```
|
||||
|
||||
Les clients déjà ouverts ne se rechargent pas seuls. Chaque application vérifie
|
||||
toutes les heures si une nouvelle version est disponible et affiche une bannière
|
||||
**« Installer »**, uniquement lorsqu’aucune journée n’est en cours, afin qu’une
|
||||
mise à jour n’interrompe jamais une journée de travail.
|
||||
|
||||
### HTTPS est obligatoire
|
||||
|
||||
Les navigateurs n’enregistrent un service worker que dans un contexte sécurisé. En
|
||||
`http://` simple, sur une adresse IP ou un nom d’hôte, l’application se charge mais
|
||||
n’a **pas de fonctionnement hors ligne, ne peut pas être installée et ne se met jamais
|
||||
à jour** - ce qui annule l’intérêt de sa conception. `localhost` est la seule
|
||||
exception, d’où le fonctionnement de `npm run dev` sans certificat.
|
||||
|
||||
### Derrière un reverse proxy existant
|
||||
|
||||
La configuration Caddy actuelle termine elle-même TLS et accepte le protocole PROXY
|
||||
depuis l’adresse ou le CIDR défini dans `TRUST_PROXY`. Indiquez l’adresse réelle du
|
||||
proxy amont ; `192.0.2.10/32` dans `.env.example` est une valeur fictive de documentation.
|
||||
`LISTEN_IP` sélectionne l’interface locale des ports publiés et vaut `0.0.0.0` par
|
||||
défaut. Un déploiement qui termine TLS ailleurs doit disposer de sa propre configuration
|
||||
Caddy et de ports ; modifier `SITE_ADDRESS` seul ne configure pas ce mode.
|
||||
|
||||
L’application doit être servie à la racine de son domaine. `start_url` et la portée
|
||||
du service worker valent tous deux `/` : un hébergement dans un sous-répertoire ne
|
||||
fonctionnera pas sans modifier le manifeste et `base` dans Vite.
|
||||
|
||||
## Architecture
|
||||
|
||||
Deux décisions structurent le reste de l’application.
|
||||
|
||||
**Les horodatages bruts sont enregistrés ; l’arrondi n’est appliqué qu’à l’affichage.**
|
||||
Modifier l’arrondi corrige donc aussi les journées passées. Deux postes adjacents
|
||||
partagent le même instant enregistré - la fin du poste *N* est le début du poste
|
||||
*N+1* - afin que l’arrondi ne puisse jamais créer de trou entre eux. Les sélecteurs
|
||||
d’heure suivent la grille d’arrondi choisie ; ouvrir puis valider un horaire inchangé
|
||||
préserve son horodatage. Les récapitulatifs appliquent le même arrondi à l’affichage.
|
||||
|
||||
**Les suggestions sont déduites de l’historique, pas de tables de compteurs.** Rien
|
||||
n’est à synchroniser : le modèle est reconstruit en mémoire à partir des postes.
|
||||
En contrepartie, une durée de conservation courte dégrade les prédictions ; c’est
|
||||
pourquoi elle est de deux ans par défaut.
|
||||
|
||||
```
|
||||
src/lib/
|
||||
time.js dates locales, arrondi, formatage (pur)
|
||||
predict.js moteur de suggestions (pur)
|
||||
resume.js génération du texte du registre (pur)
|
||||
db.js schéma Dexie et invariant de chaîne
|
||||
day.svelte.js machine à états du cycle de journée
|
||||
```
|
||||
|
||||
Les fonctions pures et les opérations de base de données et de cycle de vie ont des
|
||||
tests de régression. `db.js` regroupe les modifications des journées et des postes
|
||||
dans des transactions communes, notamment la création, la clôture, la reprise et la
|
||||
correction des bornes.
|
||||
|
||||
## Pauses et nouveaux parcours
|
||||
|
||||
**Journée → Commencer une pause** ferme le poste courant. **Reprendre le travail**
|
||||
propose la dernière tâche de travail et son client, immédiatement modifiables.
|
||||
Une pause a ses propres horaires et son libellé, sans client ni type de repas.
|
||||
Le détail montre tous les postes ; la consultation reste séparée de la correction.
|
||||
Le récapitulatif et sa copie excluent les pauses. Le transport entre dans le total
|
||||
des heures de présence, les repas et pauses en sont exclus. Seules les statistiques montrent le
|
||||
cumul des pauses, séparément des repas. Les intervalles vides importés sont préservés.
|
||||
|
||||
**Réglages → Gérer les automatismes** et **Gérer les jours non travaillés** ouvrent
|
||||
des pages dédiées ; le bouton Retour du navigateur fonctionne via les routes hash.
|
||||
**Gérer les données et sauvegardes** ouvre aussi une page dédiée, avec retour aux
|
||||
réglages, conservation de la durée après rechargement et accès hors ligne.
|
||||
Les réglages sont écrits par transaction sur la dernière valeur persistée pour
|
||||
préserver les modifications d’autres onglets. Les erreurs de démarrage et
|
||||
actualisation sont affichées avec une action Réessayer.
|
||||
|
||||
La checklist avant production et les validations restant à exécuter sont suivies
|
||||
dans [PRODUCTION.md](PRODUCTION.md).
|
||||
|
||||
## Sauvegarde vérifiée et validation navigateur
|
||||
|
||||
**Exporter les données** prépare le fichier et enregistre son empreinte complète.
|
||||
**Vérifier le fichier exporté…** relit le fichier téléchargé, contrôle qu’il est
|
||||
importable et compare son contenu à l’export. La date de la dernière sauvegarde
|
||||
vérifiée est distincte de celle du dernier export préparé. Après sept jours sans
|
||||
export vérifié, Pardis affiche un rappel pendant son utilisation. L’export reste local ; conservez le fichier hors de cet appareil. La synchronisation
|
||||
facultative utilise un coffre distinct et ne remplace pas cette sauvegarde.
|
||||
|
||||
La purge affiche une liste figée de journées. Sauvegarde et suppression partagent
|
||||
une transaction ; une correction concurrente bloque la purge et demande une
|
||||
nouvelle consultation. Les autres journées récemment importées restent intactes.
|
||||
|
||||
Les tests Playwright utilisent des contextes neufs et des données synthétiques,
|
||||
à 320 px. Ils vérifient consultation/correction, focus, Retour, reprise à deux
|
||||
onglets, export vérifié, purge/restauration et rechargement hors ligne. Ils couvrent
|
||||
aussi le nouvel écran Données, le retour du champ de conservation à sa valeur
|
||||
persistée après un échec, le refus d’un export modifié et l’annulation complète
|
||||
d’une purge en erreur, avec préservation de la sauvegarde précédente. Traces,
|
||||
vidéos et captures sont désactivées. Pour un Chrome déjà installé, définir
|
||||
`PARDIS_CHROME_PATH` avec son chemin ; sinon installer Chromium avec Playwright.
|
||||
La CI installe Chromium Headless Shell et ses dépendances avant de lancer ces
|
||||
tests. Elle télécharge uniquement la variante utilisée par les tests sans interface
|
||||
et accorde 180 secondes à chaque connexion de téléchargement, avec les nouvelles
|
||||
tentatives intégrées à Playwright. L’installation dispose de 20 minutes et le job
|
||||
de validation de 30 minutes. Une erreur d’installation bloque le déploiement.
|
||||
|
||||
|
||||
## Synchronisation facultative entre appareils
|
||||
|
||||
**Données et sauvegardes → Synchronisation et appareils** permet de créer un coffre
|
||||
chiffré sans e-mail ni mot de passe, puis de lier des appareils avec un code temporaire
|
||||
ou un QR code et une confirmation sur l’écran dédié. La saisie reste locale et
|
||||
fonctionne hors ligne. Les journées concurrentes sont conservées pour résolution.
|
||||
Un document de secours permet de retrouver l’accès après perte des appareils.
|
||||
|
||||
Les règles métier sont partagées ; le thème et le suivi des sauvegardes restent
|
||||
locaux. Un appareil est responsable des automatismes, avec proposition de transfert
|
||||
à l’ouverture sur un appareil secondaire. Les demandes d’association ne produisent
|
||||
aucune alerte ailleurs dans l’application.
|
||||
|
||||
Le protocole, les limites de sécurité, le fonctionnement des suppressions et les
|
||||
commandes de sauvegarde/restauration du serveur sont documentés dans [SYNC.md](SYNC.md).
|
||||
Pour le développement, lancer aussi `npm run sync:server` avec Node.js 24.
|
||||
|
||||
## Licence et crédits typographiques
|
||||
|
||||
Le code source de Pardis est distribué sous la licence GNU General Public License,
|
||||
version 3 uniquement (GPL-3.0-only). Le texte intégral se trouve dans
|
||||
[LICENSE.md](LICENSE.md). Les fichiers de polices fournis sont des œuvres distinctes,
|
||||
distribuées sous la SIL Open Font License, version 1.1. Leurs mentions de droits
|
||||
d’auteur et le texte de cette licence figurent dans [public/fonts/OFL.txt](public/fonts/OFL.txt).
|
||||
Copyright (C) 2026 EI Adrien Weiskopff.
|
||||
|
||||
- **Bebas Neue**, par Ryoichi Tsunekawa - SIL Open Font License 1.1.
|
||||
- **Charis SIL** - SIL Open Font License 1.1. Voir le [site officiel de Charis SIL](https://software.sil.org/fr/charis/).
|
||||
Reference in New Issue
Block a user