Primland Devis Traiteur
Traiteur é o tipo de projeto que torna arquitetura concreta: uma ferramenta desktop real para criar, salvar, importar, imprimir e organizar devis traiteur, com storage NAS compartilhado e comportamento local suficiente para manter o trabalho andando.
O problema real
A aplicação não é um gerador genérico de orçamento. Ela foi construída para um workflow interno de traiteur na Primland: operadores criam PDFs comerciais, folhas de preparação, fichas de cliente e índices de produção enquanto vários postos compartilham um NAS.
Isso cria restrições difíceis:
- o preview web não é a superfície real de produção;
- o binário desktop precisa trabalhar com arquivos locais e paths do sistema;
- escritas no NAS precisam de locks, journals e recuperação;
- operadores precisam de referências curtas legíveis em papel e por telefone;
- storage precisa proteger dados sem deixar chaves no NAS;
- updates precisam ser publicados sem travar o posto de trabalho.
Como o pensamento AppCore aparece aqui
Traiteur antecede partes do AppCore como runtime reutilizável, mas carrega os mesmos instintos: schemas de negócio em packages, Rust desktop como autoridade local, validação de input antes do storage, escrita atômica e documentação de falhas operacionais.
| Área | Responsabilidade |
|---|---|
apps/web | interface Next.js App Router e UI de devis |
apps/desktop | shell Tauri v2/Rust, comandos locais, storage, locks e DNTJ |
packages/core | schemas, cálculos HT/TTC/TVA e import/export JSON |
packages/catalog | catálogo inicial |
packages/pdf | PDFs cliente e folhas de preparação |
Storage e segurança
O NAS contém devis por data, rascunhos, clientes, índices, locks, journals e
logs. O desktop valida paths vindos do frontend, rejeita paths absolutos e ..,
e mantém o resultado dentro da raiz de storage.
Escritas críticas usam arquivo temporário único, create_new, write_all,
flush, sync_all, rename e sync do diretório pai quando possível. Conteúdo
idêntico não é regravado para reduzir IO no NAS.
DNTJ
.dntj não é JSON renomeado no desktop. Novos arquivos Rust exigem magic header
DNTJ, versão suportada, app_id, file_type, payload AES-256-GCM e checksum.
A chave DNTJ fica localmente em AppData. O NAS recebe pacotes criptografados, não a chave raiz. A manutenção admin permite exportar/importar a chave ativa quando várias máquinas autorizadas precisam ler o mesmo storage.
Numeração offline
O design evita contador global único no NAS. Cada devis tem ID técnico completo e referência humana curta:
DN-26BA-AB-0042 -> identidade técnica oficial
BB-0042 -> referência curta visível no PDF
O ID técnico combina prefixo do usuário, ano ISO, semana ISO em base 26, código da máquina e sequência local. A referência curta nunca é chave primária; colisões históricas são tratadas como possíveis.
Locks e recuperação
Locks usam criação atômica de diretório:
locks/lock-<sha256(resource)>.lock/owner.dntj
O owner guarda lock id, usuário, device, sessão, hostname, PID, heartbeat e expiração. Heartbeat e release validam sessão atual e ownership local. Locks stale exigem manutenção explícita ou recuperação segura.
Releases
Vercel serve status e endpoints de update. GitHub Releases publica artefatos Tauri assinados para macOS e Windows, com canais stable, rc e canary. Falha de rede no update não bloqueia o uso local.
Limites assumidos
O projeto nomeia riscos restantes: rate limit de login em memória, perda de chave DNTJ impede abrir arquivos gerados com aquela chave, e a manutenção admin ainda não substitui um console completo de auditoria operacional.
Esses limites mostram uma escolha: comportamento limitado e documentado em vez de transformar um app desktop em uma falsa plataforma cloud.
Aprendizado
Traiteur é o contraponto prático do AppCore. Ele mostra por que runtime importa: aplicações reais precisam de garantias pouco glamourosas em paths, locks, storage, updates, PDFs e recuperação. O usuário vê uma ferramenta de devis. A engenharia está no que torna essa ferramenta confiável em filesystem compartilhado.