Lalabase
Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
翻译准备中
Ingressos impressos, numerados e com QR code único, com check-in offline.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Ingressos impressos e numerados, com QR code assinado, e check-in na porta pelo navegador do celular, mesmo sem internet.
Para bandas independentes, festas de escola, igrejas e pequenos produtores que vendem ingresso na mão.
Site · Status · Novidades · Histórico de versões · Arquitetura · Decisões (ADRs) · Implantação
Quem organiza um show na garagem, uma festa junina ou um culto especial costuma vender ingresso de papel, um a um, por vários vendedores. Na porta, ninguém sabe se aquele papel é original, se já entrou ou quem vendeu. O Ingresso Impresso resolve isso sem exigir internet nem equipamento:
Para quem organiza
{evento}, {data}…).Na porta
Para quem administra a plataforma
flowchart LR
subgraph Painel["Painel (Next.js)"]
E[Editor e lotes]
end
subgraph API["API (Rust · Axum)"]
S[Assina os números<br/>Ed25519]
R[Gera PDFs e imagens<br/>Typst]
end
DB[(PostgreSQL)]
subgraph Porta["Portaria (navegador do celular)"]
W[WASM: confere a assinatura<br/>e decide offline]
I[(IndexedDB)]
end
E -- lote pago --> S --> R
S <--> DB
R -- A4, gráfica, WhatsApp, link --> Papel[Ingresso]
Papel -- QR --> W
W <--> I
I -. sincroniza quando há rede .-> API
(evento, número), nunca pelos bytes do QR: a cópia de um ingresso que já
entrou é barrada como "já entrou".testdata/vectors) rodam em Rust e no WebAssembly, garantindo que
servidor e portaria decidem igual.Os detalhes estão em docs/arquitetura.md e nas
45 decisões registradas.
| Parte | Tecnologia |
|---|---|
| Núcleo do ingresso | Rust (ticket-core): formato do QR, base45, Ed25519, decisão da portaria; sem IO, compila para wasm32 |
| Portaria | ticket-wasm (wasm-bindgen) + zxing-wasm para ler o QR, IndexedDB, service worker |
| Geração de arquivos | Typst embutido (ticket-render), QR vetorial, PDF de gráfica com sangria |
| API | Rust, Axum 0.8, sqlx 0.9 (consultas verificadas em compilação), PostgreSQL |
| Painel e site | Next.js 16, React, TanStack Query, Tailwind CSS 4, TypeScript estrito |
| Tipos | gerados do Rust para TypeScript com ts-rs (nunca escritos à mão) |
| Serviços | Render (API), Vercel (site), Neon (Postgres), Resend (e-mail), Stripe (Pix e cartão), Cloudflare Turnstile |
crates/
ticket-core/ formato v1, base45, Ed25519, decisão da portaria (puro, sem IO)
ticket-wasm/ bindings WebAssembly para a portaria (só verifica, nunca assina)
render/ ingressos em PDF e imagem com Typst; fontes OFL
server/ API (Axum + sqlx), migrações, worker de arquivos, testes de integração
cli/ binário `ii`: vetores, render e verificação locais
apps/web/ site, painel, portaria e ingresso digital (Next.js)
packages/
api-types/ tipos da API gerados do Rust
ticket-core-wasm/ wrapper TypeScript do WASM
e2e/ portaria ponta a ponta com 5 "celulares" e câmeras falsas (Playwright)
docs/ arquitetura, ADRs, implantação e ensaio geral
Pré-requisitos: rustup (a versão vem de rust-toolchain.toml),
Node.js ≥ 22.13 com pnpm 12, just, Docker (para o Postgres) e
wasm-bindgen-cli 0.2.129:
cargo install wasm-bindgen-cli --version 0.2.129 --locked
Passo a passo:
git clone https://github.com/allansomensi/ingressoimpresso
cd ingressoimpresso
cp .env.example .env
# Gere a chave mestra e cole em TICKET_KEY_ENCRYPTION_KEY no .env:
openssl rand -base64 32
just db-up # Postgres em Docker
pnpm install
just wasm # compila a portaria para WebAssembly
just api # API em http://localhost:8080 (cria as tabelas ao subir)
just web-dev # site e painel em http://localhost:3000 (em outro terminal)
Sem RESEND_API_KEY, nenhum e-mail sai: o código de login aparece no log da API. Use o e-mail de
ADMIN_EMAILS e ligue a verificação em duas etapas em Minha conta para ver o painel de
administração (ADR 0047). Stripe, Google, Turnstile e Cloud Vision são opcionais; sem eles, o
admin marca lotes como pagos e o login é só por código.
Testar a impressão sem a API:
cargo run -p ii-cli -- job init --name "Meu Show"
cargo run -p ii-cli -- render --job job.json --seed event.seed # out/: A4, gráfica, controle, ZIP
cargo run -p ii-cli -- verify --job job.json --seed event.seed "<texto lido do QR>"
just # exatamente o que o CI roda: fmt, clippy, testes Rust, tipos gerados, WASM, lint, Vitest e build
just e2e # a portaria ponta a ponta: API + site + 5 navegadores com câmera falsa
proptest e vetores compartilhados Rust ↔ WASM.sqlx::test em Postgres real.pedantic, sem unwrap fora de testes, TypeScript estrito sem any.#), que não
chega ao servidor.Encontrou uma vulnerabilidade? Não abra uma issue pública: siga a Política de Segurança (relato privado pelo GitHub ou por [email protected]). Respondemos em até 5 dias.
Contribuições são bem-vindas! Leia o guia de contribuição antes de abrir um pull request. Em resumo:
just e deixe tudo verde. Os pull requests vão para o branch staging (o ambiente de
testes) antes do main, que é a produção.CLAUDE.md: código e commits em inglês, interface e
documentação em português, e commits no formato
Conventional Commits com gitmoji
(feat(server): ✨ ..., fix(web): 🐛 ...).CHANGELOG.md.
As versões seguem o Versionamento Semântico e são publicadas
como tags vX.Y.Z (como lançar).CLAUDE.md. A principal: o formato QR v1 é imutável.Ao participar, você concorda com o Código de Conduta. Precisa de ajuda com a sua conta ou o seu evento? Veja o Suporte.
Código sob a licença MIT. As fontes em crates/render/fonts e
apps/web/public/fonts/ticket seguem a SIL Open Font License; cada uma acompanha o seu arquivo
-OFL.txt.