Visão geral
Frente de caixa pra desktop (Windows, Linux e Mac) feita pra mercado e loja pequena. Abre e fecha caixa, lê código de barras, aceita pagamento misto com troco, emite cupom de 40 colunas e controla estoque. Tudo funciona sem internet, num banco SQLite na própria máquina.
Como funciona
Venda: número, itens, pagamentos, baixa de estoque e o evento de sincronização entram numa transação só. Se faltar energia no meio, nada fica gravado pela metade e o número da venda não é queimado.
Estoque: dois caixas vendendo a última unidade ao mesmo tempo. A transação trava a escrita desde o começo e a baixa é condicional ("só tira se ainda tiver"). Um vende, o outro recebe "só tem 0".
Desconto: R$ 1,00 de desconto em três itens iguais dá 0,333... por item. Arredondar cada um faz o cupom não fechar com o total. O rateio pelo maior resto distribui os centavos que sobram, e a soma fecha exata. Um teste confere isso em mil carrinhos aleatórios.
Caixa: troco só sai do dinheiro, desconto acima de 10% pede senha de supervisor, e o fechamento é cego (o operador informa quanto contou antes de ver quanto era esperado).
Sincronização: cada venda grava um evento na mesma transação (padrão outbox). Quando tem internet, os eventos vão em ordem pro servidor da loja, com chave de idempotência: se a resposta se perder e o caixa reenviar, o servidor não duplica a venda.
O cupom é simulação e diz isso no próprio texto. NFC-e de verdade exige certificado digital e integração com a SEFAZ, e isso ficou fora do escopo.
Testes
37 testes automatizados, com banco SQLite de verdade, incluindo a disputa pela última unidade com duas threads e a resposta perdida na sincronização. Um dos testes abre a janela real do caixa sem monitor e faz uma venda inteira só pelo teclado, do jeito que um operador com leitor de código de barras faria.
Stack
C# 12, .NET 8, Avalonia 11, CommunityToolkit.Mvvm, Microsoft.Data.Sqlite (SQL escrito à mão, com migrações), xUnit e Avalonia.Headless.