Primland Devis Traiteur
Traiteur is the kind of project that makes architecture concrete: a real desktop tool for creating, saving, importing, printing and organizing catering quotes, with shared NAS storage and enough local behavior to keep work moving.
The real problem
The application is not a generic quote builder. It was built for an internal Primland catering workflow where operators need to create commercial PDFs, preparation sheets, customer records and production indexes while several workstations share a NAS.
That environment creates awkward constraints:
- the web preview is not the real production surface;
- the desktop binary must work with local files and OS paths;
- NAS writes need locks, journals and recovery;
- users still need short references that make sense on paper and by phone;
- storage has to protect business data without putting encryption keys on the NAS;
- updates must be published without breaking the workstation flow.
How AppCore thinking appears here
Traiteur predates parts of AppCore as a reusable runtime, but it contains the same instincts: isolate business schemas in packages, keep the desktop Rust side responsible for local authority, validate frontend input before storage, write critical files atomically and document operational failure modes.
The repository is split into:
| Area | Responsibility |
|---|---|
apps/web | Next.js App Router interface and quote UI |
apps/desktop | Tauri v2/Rust shell, local commands, storage, locks and DNTJ |
packages/core | schemas, HT/TTC/TVA calculations and JSON import/export |
packages/catalog | initial product catalog |
packages/pdf | customer PDFs and preparation sheets |
Storage and safety
The NAS layout contains dated quotes, unfinished drafts, customers, indexes,
locks, journals and logs. The desktop validates paths coming from the frontend,
rejects absolute paths and .., and keeps final paths inside the storage root.
Critical writes use a defensive sequence: unique temporary file, create_new,
write_all, flush, sync_all, rename and parent-directory sync where
possible. If the content hash has not changed, the write is skipped to reduce
NAS IO.
DNTJ
.dntj is not JSON with a different extension in the desktop system. New Rust
DNTJ files require:
- magic header
DNTJ; - supported version;
app_idandfile_type;- AES-256-GCM encrypted payload;
- integrity checksum.
The DNTJ key lives locally in AppData by default. The NAS receives encrypted packages, not the root key. Admin maintenance can export/import the active key when several authorized machines need to share the same storage.
Offline numbering
The quote ID design avoids a single global NAS counter. Each quote has a full technical ID and a short human reference. Example:
DN-26BA-AB-0042 -> official technical identity
BB-0042 -> short reference visible in the PDF
The technical ID combines user prefix, ISO year, ISO week encoded in base 26, machine code and local sequence. The short reference is intentionally not a primary key; the system treats collisions as possible in historical search.
Locks and recovery
Locks use atomic directory creation:
locks/lock-<sha256(resource)>.lock/owner.dntj
The owner records lock id, user, device, session, hostname, PID, heartbeat and expiry. Heartbeat and release verify the current session and local ownership. Stale locks require explicit maintenance or safe recovery.
Releases
Vercel serves status and update endpoints. GitHub releases publish signed Tauri
artifacts for macOS and Windows, with release channels for stable, rc and canary.
The updater can return 204 No Content when no manifest is configured; update
network failure does not block local use.
What went wrong or stayed limited
The project names its remaining risks instead of hiding them: login rate limit is in memory, DNTJ key loss prevents opening files created with that key, and admin maintenance is not a complete operational audit console.
Those limitations are useful. They show an engineer choosing bounded behavior, documenting operational responsibility and refusing to turn a desktop app into a fake cloud platform.
What I learned
Traiteur is the practical counterpart to AppCore. It shows why runtime work matters: real applications need boring guarantees around paths, locks, storage, updates, PDF generation and recovery. The user sees a quote tool. The engineering work is everything that keeps the quote tool trustworthy on a shared filesystem.