Primland Devis Traiteur
Traiteur rend l'architecture concrète: un outil desktop réel pour créer, sauvegarder, importer, imprimer et organiser des devis traiteur, avec stockage NAS partagé et comportement local suffisant pour continuer à travailler.
Le problème réel
L'application n'est pas un générateur générique de devis. Elle vise un workflow interne Primland: opérateurs, PDFs commerciaux, feuilles de préparation, clients et indexes de production sur plusieurs postes qui partagent un NAS.
Contraintes principales:
- le preview web n'est pas la surface de production réelle;
- le binaire desktop doit gérer fichiers locaux et chemins OS;
- les écritures NAS demandent locks, journaux et récupération;
- les opérateurs ont besoin de références courtes lisibles sur papier;
- le stockage doit protéger les données sans placer les clés sur le NAS;
- les mises à jour doivent être publiées sans bloquer l'usage local.
Le lien avec AppCore
Traiteur précède une partie d'AppCore comme runtime réutilisable, mais porte les mêmes instincts: schemas métier isolés en packages, Rust desktop comme autorité locale, validation avant stockage, écritures atomiques et documentation des modes de panne.
| Zone | Responsabilité |
|---|---|
apps/web | interface Next.js App Router et UI devis |
apps/desktop | shell Tauri v2/Rust, commandes locales, stockage, locks et DNTJ |
packages/core | schemas, calculs HT/TTC/TVA et import/export JSON |
packages/catalog | catalogue initial |
packages/pdf | PDFs client et feuilles de préparation |
Stockage et sécurité
Le NAS contient devis datés, brouillons, clients, indexes, locks, journaux et
logs. Le desktop valide les chemins reçus du frontend, rejette les chemins
absolus et .., et maintient le résultat dans la racine de stockage.
Les écritures critiques passent par fichier temporaire unique, create_new,
write_all, flush, sync_all, rename et sync du dossier parent quand
possible. Le contenu identique n'est pas réécrit pour réduire l'IO NAS.
DNTJ
.dntj n'est pas du JSON renommé dans le desktop. Les nouveaux fichiers Rust
exigent magic header DNTJ, version supportée, app_id, file_type, payload
AES-256-GCM et checksum.
La clé DNTJ reste localement dans AppData. Le NAS reçoit des packages chiffrés, pas la clé racine. La maintenance admin permet export/import pour les machines autorisées qui doivent lire le même stockage.
Numérotation offline
Le design évite un compteur global unique sur le NAS. Chaque devis possède une identité technique complète et une référence humaine courte:
DN-26BA-AB-0042 -> identité technique officielle
BB-0042 -> référence courte visible sur le PDF
La référence courte n'est jamais une clé primaire; les collisions historiques sont considérées possibles.
Locks et récupération
Les locks utilisent la création atomique de dossier:
locks/lock-<sha256(resource)>.lock/owner.dntj
L'owner stocke lock id, utilisateur, device, session, hostname, PID, heartbeat et expiration. Heartbeat et release valident la session et l'ownership local.
Releases
Vercel sert le statut et les endpoints update. GitHub Releases publie des artefacts Tauri signés pour macOS et Windows, avec canaux stable, rc et canary. Un échec réseau d'update ne bloque pas l'usage local.
Limites assumées
Le projet nomme ses risques: rate limit de login en mémoire, perte de clé DNTJ bloquante pour les fichiers concernés, maintenance admin encore limitée comme console d'audit.
Ces limites montrent un choix: comportement borné et documenté plutôt qu'une fausse plateforme cloud dans une application desktop.
Ce que cela montre
Traiteur est le pendant pratique d'AppCore. Les applications réelles ont besoin de garanties sur chemins, locks, stockage, updates, PDFs et récupération. L'utilisateur voit un outil de devis; l'ingénierie est ce qui le rend fiable sur filesystem partagé.