Pular para o conteúdo
Voltar para projetos

Stockium

Entregue
Laravel 13PHP 8.4Inertia.jsVue 3TypeScriptPostgreSQL 18Tailwind CSSDockerPest
Em uso pelo cliente · demo em breve
Stockium

Visão geral

SaaS multi-tenant para gestão de lojas de eletrônicos: cada aparelho é uma unidade física serializada, com histórico append-only do primeiro recebimento até a venda, o reparo ou a troca.

01

Problema

Lojas de eletrônicos controlam aparelhos em planilhas — o IMEI se perde, o histórico é reescrito, uma venda cancelada simplesmente some e os dados de várias lojas se misturam. Sem identidade por unidade física não há como auditar de onde veio o aparelho, quanto custou o reparo ou por onde ele passou.

02

Solução

Um modelo Categoria → Produto → Variação → Item de Estoque em que cada item é serializado (IMEI, número de série) e percorre uma máquina de status fechada: disponível, reservado, em reparo, aguardando retirada, vendido. Toda transição grava um movimento imutável; cancelar uma venda é estorno com restauração do status anterior, nunca delete; excluir um cliente é anonimização, preservando as FKs e o histórico exigido pela LGPD.

03

Arquitetura

Monólito Laravel com camada de serviços explícita e SPA Vue servida por Inertia — sem API REST/GraphQL. Controllers ficam finos (props Inertia e delegação), FormRequests validam com exists escopado ao tenant, e treze services concentram transação, lock, movimentos e audit log. O isolamento multi-tenant vive em scopes globais (TenantScope / UnitScope) aplicados por traits que também preenchem tenant_id e unit_id na criação. O front consome rotas tipadas geradas pelo Laravel Wayfinder; os PDFs vão para um disco S3 — MinIO em desenvolvimento, Cloudflare R2 em produção.

04

Desafios

Tornar o histórico realmente imutável: movimentos de estoque e audit logs lançam ImmutableRecordException em qualquer update ou delete. Garantir que o isolamento entre lojas não vaze em nenhuma consulta, e que operações concorrentes — duas vendas do mesmo item, dois cadastros com o mesmo convite — nunca produzam estado inconsistente, resolvido com transações e locks pessimistas. Permissões são dados, não código: novas abilities entram no seeder e no middleware can:, sem checks espalhados pelo código.

05

Resultados

Em produção e em uso pelo primeiro cliente, com deploy automatizado (VPS Docker + Caddy + GitHub Actions) e gate de qualidade único no CI — Pest, Vitest, PHPStan nível 7, Pint, ESLint e Prettier reunidos em composer ci:check. Quarenta e cinco models, treze services de domínio e vinte permissions seedadas. O cadastro público é fechado: um tenant só nasce por convite one-shot (token de 32 bytes gravado apenas como SHA-256) ou por comando Artisan. Uma demo pública está a caminho.

Galeria

Clique na imagem para ver em tela cheia

1 / 5

Painel do período e saúde do estoque