Svelte Commerce
A standalone open-source storefront built with SvelteKit, headless across 26 commerce backends. MIT licensed.
Manage product expiration dates and inventory in a store
Translation pending
AI summary · website content
CommerceJavaScript · CSSGitHub @NaninhoXOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Dashboard + mapa de calor da loja + coletor com leitura de código de barras pela câmera. Substitui a planilha Controle_Validade_v12.xlsx, que continua sendo entrada (importação) e saída (exportação).
Node 20 ou mais novo.
npm install
npm run import -- "../Controle_Validade_v12.xlsx" # carga inicial (já feita neste PC)
npm start # http://localhost:3000 (o coletor é a aba "Coletor")
npm test # 23 testes contra Postgres
O banco é PostgreSQL nos dois ambientes, com o mesmo SQL:
| Onde | Banco |
|---|---|
| Seu computador | PGlite (um Postgres que roda dentro do Node, guardado em data/pg; não precisa instalar nada) |
| Vercel | Neon, pela variável DATABASE_URL |
Localmente o login fica desligado (só o localhost acessa). Com npm run lan ou REQUIRE_LOGIN=1 ele passa a ser obrigatório.
validade-app:
git remote add origin https://github.com/SEU-USUARIO/validade-app.git
git push -u origin main
O .gitignore já deixa de fora node_modules, data/ e .env.DATABASE_URL; não precisa copiar a senha.SESSION_SECRET com um texto aleatório de 32+ caracteres:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
DATABASE_URL=... e salve num arquivo chamado .env.local dentro da pasta validade-app. O Git ignora esse arquivo e os scripts o leem sozinhos, então a string nunca vai para o chat nem para o repositório. Depois:
npm run import -- "../Controle_Validade_v12.xlsx" # sobe produtos e estoque
npm run usuario -- MICHEL 123456 admin # troque pelo PIN que quiser (6 a 8 números)
npm run usuario -- JOAO 654321 operador # um por pessoa da loja
Na Vercel o login é sempre obrigatório. Depois, novos usuários e PINs se gerenciam em Configurações → Equipe.
PIN com hash (scrypt) e bloqueio de 10 min após 5 erros · sessão em cookie HttpOnly/Secure/SameSite=Lax assinado · o nome do operador nos lançamentos vem da sessão, não do que o aparelho manda · cabeçalho obrigatório contra CSRF · Content-Security-Policy restritiva · câmera liberada só para o próprio site · operador não altera regras, planta, equipe nem importa dados.
GÔNDOLA-LADO-PRATELEIRA, por exemplo 1-B-3.
| Parte | Valores |
|---|---|
| Gôndola | 1 a 40 (hoje 1 a 19; sacaria e aquarismo entram depois) |
| Lado | A esquerda · B direita · F ponta da frente · C ponta das costas |
| Prateleira | 1 a 5. Ponta pode vir sem prateleira: 1-F, 1-C |
Endereços antigos fora disso (19, 4-E-1) continuam no estoque, aparecem em Qualidade dos dados e no mapa como “sem endereço válido”, e se corrigem na próxima ronda. Endereço novo fora do padrão é recusado.
| Prazo | Desconto |
|---|---|
| até 30 dias | 50% em tudo |
| até 90 dias | ração (seca e úmida) 20% · demais itens 30% |
| vencido | retirar da loja |
“Ração” vem da categoria do produto; sem categoria, do nome. Não existe mais a faixa de 10%. Perda potencial = valor × desconto (vencido = 100%).
/coletor só redireciona para ela; operadores já abrem nela) — Entrada (receber soma / contar define), Ronda por endereço, Baixa, Buscar. Atalhos de lado e prateleira por toque, câmera para o EAN e para a etiqueta do endereço, fila offline com reenvio sem duplicar, desfazer do último lançamento, aviso de FEFO.Usa o leitor nativo do Chrome (BarcodeDetector) e, onde ele não existe, o ZXing (public/vendor/zxing.min.js). Para EAN só aceita leitura com dígito verificador correto. Exige HTTPS (ou localhost).
produtos · lotes (EAN + lote + validade + endereço) · eventos (toda entrada, contagem, ajuste, baixa e transferência, com quem/quando/saldo) · usuarios · config.
npm run import.pg) foi testado por rede contra um servidor Postgres local; a conexão com o Neon de verdade só é exercitada no primeiro deploy.npm audit aponta 2 avisos moderados de uuid dentro do exceljs; o trecho afetado não é usado aqui.Cada filial é um projeto próprio na Vercel com o seu Neon (mesmo código, dados separados).
ADMIN_INICIAL com NOME:PIN (ex.: JOAO:123456, tipo Sensitive) e faça o redeploy. Ela cria o administrador no primeiro acesso, só se o banco não tiver nenhum usuário; depois pode ser apagada.DEMO=1 PGLITE_DIR=memory:// npm start mostra o sistema com produtos e lotes de exemplo, sem tocar no estoque real. Na Vercel, DEMO_INICIAL=1 carrega os dados de exemplo uma única vez (só em banco sem estoque); apague a variável depois e limpe os dados antes do uso real.Na Conferência de Recebimento ou de Contagem, o botão Carregar a lista aceita planilha (.xlsx), CSV, TXT ou o XML da NF-e. O app acha sozinho a linha do cabeçalho (EAN, código de barras, quantidade, lote, validade…); sem cabeçalho, entende EAN;quantidade em cada linha. Mostra o que entendeu e o que ficou de fora, e só então carrega as quantidades como "esperado": laranja até chegar, verde quando bate, vermelho quando passa. Bipar a chave da nota (44 números do DANFE) anota o número da NF.
Conferências, entrada e contagem funcionam sem rede. Antes de ficar offline, no Coletor ou em Conferências toque em Preparar para o modo avião: o aparelho guarda o catálogo de produtos (para mostrar o nome de cada EAN), a lista de endereços e os endereços da ronda de hoje. Sem internet, o que for lançado fica numa fila no aparelho e sobe sozinho quando a rede voltar (cada lançamento tem um identificador, então reenviar nunca soma duas vezes). Uma conferência criada e finalizada offline guarda o horário real de abertura e de fechamento. O app só precisa estar instalado e ter sido aberto uma vez com internet.
Precisa de internet: gerar a ronda do dia, carregar a lista da nota, imprimir ou exportar a conferência (isso acontece depois que ela sobe) e a auditoria.