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.
Translation pending
Gestão, pagamentos, treinos, relacionamento e bem-estar em um único ecossistema.
Translation pending
BusinessTypeScript · PLpgSQLGitHub @BrazZ7OnlineOwner 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
Loading the full README. The saved excerpt is shown below.
Saúde em equilíbrio com o seu futuro. Painel de gestão das academias do ecossistema Synse — alunos, planos, mensalidades, treinos, check-in e pagamentos em um único produto. O projeto sobe sem nenhuma configuração. Sem credenciais de Supabase ele entra em modo de demonstração, com uma academia completa em memória: 520 alunos, 12 meses de mensalidades, check-ins, treinos e avaliações. Requer Node 22 ou mais recente, disponível em nodejs.org. Abra http://localhost:3000 e escolha um perfil na tela de login.Read the full README ↗
Saúde em equilíbrio com o seu futuro.
Painel de gestão das academias do ecossistema Synse — alunos, planos, mensalidades, treinos, check-in e pagamentos em um único produto.
O projeto sobe sem nenhuma configuração. Sem credenciais de Supabase ele entra em modo de demonstração, com uma academia completa em memória: 520 alunos, 12 meses de mensalidades, check-ins, treinos e avaliações.
Requer Node 22 ou mais recente, disponível em nodejs.org.
git clone -b claude/kind-goldberg-c16nsx https://github.com/BrazZ7/SynseHUB.git
cd SynseHUB
npm install
npm run dev
Abra http://localhost:3000 e escolha um perfil na tela de login.
docker build -t synsehub .
docker run -p 3000:3000 synsehub
Ou, para publicar o seu próprio repositório: em vercel.com → Add New → Project,
importe BrazZ7/SynseHUB e selecione o branch claude/kind-goldberg-c16nsx.
O Next.js é detectado automaticamente e nenhuma variável de ambiente é
necessária para o modo de demonstração.
| Perfil | O que vale a pena olhar |
|---|---|
| Emerson Braz (Proprietário) | Dashboard, financeiro, inadimplentes, Synse Pay |
| Rafael Nunes (Professor) | O mesmo dashboard sem receita nem inadimplência — o RBAC em ação |
| Lucas Ferraz (Recepção) | Check-in: busque um aluno e registre a presença |
| Aluno Synse App | A experiência do aluno: treino do dia, check-in, progresso, PIX |
| Synse Plataforma (Super admin) | /synse-admin: GMV, comissão e organizações |
Vale testar também: cadastrar um aluno em Alunos → Novo aluno (ele nasce com Synse ID e primeira mensalidade), dar baixa numa cobrança em Inadimplentes → Cobrar → Registrar pagamento e ver o painel recalcular, e reduzir a janela do navegador até a largura de um celular.
O Synse é um ecossistema de saúde, fitness e bem-estar operando em B2B2C: a academia contrata a plataforma, e os alunos dela ganham acesso gratuito ao app. A Synse também pode vender diretamente a esses usuários.
| Produto | O que é | Estado |
|---|---|---|
| SynseHub | Painel administrativo da academia | Fase 1 implementada |
| Synse App | Área do aluno (PWA responsiva) | Primeira versão |
| Synse Pay | Cobranças, split e conciliação | Arquitetura + provedor simulado |
| Synse+ | Assinatura premium do consumidor | Página de venda |
| Synse Pro | Profissionais independentes | Papel e permissões prontos |
| Synse Market / AI / Corporate | Marketplace, IA e corporativo | Arquitetura preparada |
Cada pessoa tem um identificador vitalício no formato SYN-XXXXXXXX
(Crockford base32, sem I, L, O e U). Ele é não sequencial por decisão de
segurança: um ID não permite inferir outro nem estimar o tamanho da base.
A conta sobrevive ao vínculo com a academia. Um aluno que treina dois anos na Academia Alpha e sai continua com a conta Synse, o histórico e o progresso — respeitando consentimentos e regras de acesso.
src/
app/
(auth)/ Login e escolha de perfil
(hub)/ SynseHub — painel da academia
(student)/ Synse App — experiência do aluno
synse-admin/ Painel da plataforma (SUPER_ADMIN)
api/ Webhooks e health check
components/
ui/ Primitivas (Radix + CVA), estilo shadcn/ui
synse/ Componentes da marca: MetricCard, DataTable, ProgressRing…
charts/ Gráficos Recharts com paleta validada
features/ Um módulo por domínio: actions, services e telas
auth/ students/ payments/ checkin/ workouts/ dashboard/ organizations/
lib/
auth/ Sessão, guardas de rota e server actions de acesso
database/ Data sources (demo e Supabase) + clientes
payments/ Interface PaymentProvider e adapters
permissions/ RBAC e guarda de servidor
validations/ Schemas Zod
db/migrations/ SQL versionado: schema, índices, RLS
types/ Modelo de domínio
config/ Configuração pública e navegação
Multi-tenancy em duas camadas. Toda consulta filtra por organization_id
explicitamente, e o Postgres aplica Row Level Security por cima. A redundância é
intencional: se uma policy for afrouxada por engano, a aplicação continua isolada.
Autorização no servidor. O front-end usa can() apenas para esconder UI.
Cada server action passa por requirePermission() antes de tocar em dados.
Esconder um botão nunca é o controle de acesso.
Gateway atrás de uma interface. Nenhum código específico de gateway existe fora
de lib/payments/providers/. O resto do sistema conhece apenas PaymentProvider,
e isso já se provou na prática: o Asaas foi removido sem que uma linha de regra de
negócio, tela ou migration precisasse mudar.
Dinheiro só muda por confirmação externa. O status de um pagamento muda a partir de um webhook validado ou de uma consulta ao provedor. Nunca a partir do navegador.
Lógica fora dos componentes. Componentes React renderizam. Regra de negócio vive
em features/*/service.ts, acesso a dados em data sources, validação em schemas Zod.
As APIs já estão desenhadas para servir também um app React Native no futuro.
Next.js 15 (App Router) · React 19 · TypeScript strict · Tailwind CSS 3 Radix UI · Lucide Icons · Recharts · Zod · React Hook Form · TanStack Query Supabase (Postgres, Auth, Storage, RLS)
git clone https://github.com/BrazZ7/SynseHUB.git
cd SynseHUB
npm install
cp .env.example .env.local
npm run dev
Abra http://localhost:3000.
Sem nenhuma configuração o projeto já sobe funcionando. Sem credenciais de Supabase, o SynseHub usa um data source em memória com uma academia completa: 520 alunos, 12 meses de mensalidades, check-ins, treinos e avaliações. O dataset é determinístico — os mesmos números em qualquer máquina.
Na tela de login você escolhe o perfil com que quer entrar:
| Perfil | O que enxerga |
|---|---|
| Emerson Braz — Proprietário | Tudo na organização |
| Marina Duarte — Gerente | Operação, alunos e financeiro |
| Rafael Nunes — Professor | Treinos, avaliações e alunos; sem financeiro |
| Lucas Ferraz — Recepção | Check-in, matrículas e cobranças |
| Aluno Synse App | A experiência do aluno |
| Synse Plataforma — Super admin | Todas as organizações e o GMV |
Não existe senha em modo demonstração: a persona escolhida vira uma sessão em cookie, e as permissões de cada papel valem normalmente — inclusive as restrições. O modo só existe quando não há Supabase configurado.
O dataset base é determinístico e nunca é alterado: ele é reconstruído idêntico em qualquer processo. O que o visitante muda — matricular um aluno, dar baixa numa cobrança, registrar presença — vira uma entrada num diário guardado em cookie, reaplicada sobre o dataset base a cada leitura.
Essa separação resolve dois problemas de uma vez:
O diário guarda no máximo 40 alterações e 3,5 KB. Ao estourar, as mais antigas saem. O botão Reiniciar demonstração, no topo do painel, apaga o diário e devolve tudo ao estado inicial.
Copie .env.example para .env.local. Nenhum segredo é versionado.
| Variável | Obrigatória | Descrição |
|---|---|---|
NEXT_PUBLIC_APP_URL | sim | URL pública (links de cobrança, webhooks) |
NEXT_PUBLIC_SYNSE_ENV | sim | development · staging · production |
NEXT_PUBLIC_SUPABASE_URL | não¹ | URL do projeto Supabase |
NEXT_PUBLIC_SUPABASE_ANON_KEY | não¹ | Chave anônima (sujeita à RLS) |
SUPABASE_SERVICE_ROLE_KEY | não² | Somente servidor. Ignora RLS |
PAYMENT_PROVIDER | sim | mock — é o único hoje. Nome desconhecido cai no simulado e aparece em /api/health?deep=1 |
SYNSE_DEFAULT_PLATFORM_FEE_PERCENTAGE | não | Comissão padrão (o valor efetivo vem do banco) |
¹ Sem as duas, a aplicação entra em modo demonstração. ² Necessária para processar webhooks e rodar o seed.
Arquivos versionados em src/db/migrations, aplicados em ordem:
| Arquivo | Conteúdo |
|---|---|
0001_core.sql | Perfis, organizações, equipe, planos, alunos, matrículas |
0002_payments.sql | Contas, cobranças, pagamentos, split, webhooks, régua |
0003_training_health_content.sql | Check-in, treinos, avaliações, nutrição, conteúdo, CRM, LGPD |
0004_rls.sql | Row Level Security em todas as tabelas |
0005_student_profile_visibility.sql | Equipe lê o perfil de quem tem matrícula |
0006_unique_profile_email.sql | E-mail único por perfil |
0007_organization_signup.sql | Cadastro de academia pela própria dona |
0008_rls_performance.sql | Políticas em forma de conjunto: 997 ms → 23 ms |
0009_payment_marketplace.sql | Subconta por academia e segredo do provedor |
0010_organization_fiscal_address.sql | Dados fiscais exigidos pelo provedor |
0011_self_signup.sql | Código de convite, entrada do aluno, tipo da organização |
0012_notification_events.sql | Gatilhos que enchem o sino |
0013_synse_solo.sql | Organização reservada: treinar sem academia vinculada |
0014_baseline_experience.sql | Plano da conta, desafios base, progresso e medalhas |
0015_professional_unlock.sql | Perfil profissional como assinatura, não como tipo de cadastro |
0016_synse_run.sql | SynseRun: atividades, rota, parciais e recordes |
npm run db:migrate # lista as migrations e como aplicá-las
npm run db:migrate -- --print > db.sql # SQL consolidado
# Aplicar via Supabase CLI
supabase link --project-ref <project-ref>
supabase db push
npm run db:seed
Cria uma academia, seis profissionais, cinco planos, 534 alunos com mensalidades, check-ins e avaliações — volume suficiente para as consultas revelarem o que uma academia de vinte alunos esconde.
Nenhuma senha é gerada. As contas nascem no Supabase Auth com e-mail confirmado e sem senha — o acesso previsto é por link no e-mail. Não existe credencial fixa no repositório nem no banco.
Enquanto não houver SMTP próprio, o link do e-mail não chega a lugar nenhum. Para entrar sem depender de e-mail:
npm run db:set-password -- --gerar # sorteia a senha e mostra uma vez
npm run db:set-password # ou digite a sua
npm run db:set-password -- [email protected] # em outra conta
O script exige SUPABASE_SERVICE_ROLE_KEY no .env.local, mostra o estado da
conta (e-mail confirmado, provedores, último acesso) e testa o login de
verdade antes de dizer que deu certo. Se a tela recusar depois de o teste
passar, o problema não é a senha.
A senha nunca vai por argumento — isso a gravaria no histórico do shell.
| Papel | Escopo |
|---|---|
SUPER_ADMIN | Plataforma Synse: organizações, GMV, assinaturas, webhooks |
OWNER | Controle completo da sua organização |
MANAGER | Administrativo, sem alterar configurações nem estornar |
RECEPTIONIST | Alunos, pagamentos, check-in e agenda |
TRAINER | Treinos, avaliações e alunos atribuídos |
NUTRITIONIST | Área nutricional dos pacientes autorizados |
PROFESSIONAL | Profissional independente (Synse Pro) |
STUDENT | Synse App |
A matriz completa está em src/lib/permissions/permissions.ts e é visível na
interface em Configurações → Permissões.
Três camadas independentes protegem cada acesso:
requireHubSession(permission) barra a rota antes de renderizar.requirePermission(session, permission) barra cada server action.// Todo o sistema depende apenas disto:
const provider = getPaymentProvider()
await provider.createPix({ ... })
Para adicionar um gateway, implemente PaymentProvider
(src/lib/payments/provider.ts) e registre na fábrica em
src/lib/payments/index.ts. Nenhuma tela muda.
A comissão da Synse nunca está fixa no código. Ela vem de
organization_billing_settings (percentual, taxa fixa e quem absorve a tarifa do
provedor) e é alterável apenas pela plataforma — a própria academia não edita a
própria comissão. O cálculo vive em src/lib/payments/split.ts e garante que a
soma feche com o valor cobrado, sem centavo perdido.
Sem provedor, não há rota de webhook — ela nasce junto com o adapter. O mecanismo que recebe o evento continua de pé e vale para quem vier:
webhook_events tem UNIQUE (provider, event_id).
O mesmo evento reenviado falha no INSERT, é reconhecido e ignorado. Não existe
liquidação em duplicidade.Não há provedor de pagamento conectado. O Asaas foi removido por causa da taxa e o substituto ainda não foi escolhido, então o único provedor é o simulado: nenhum centavo se move, em nenhum ambiente. O Synse Pay — o marketplace em que a academia cobra o aluno e a plataforma retém a comissão — está engavetado junto, e as telas dizem isso em vez de fingir que operam.
Quem for ligar o próximo provedor escreve um adapter em lib/payments/providers/
e uma rota de webhook. O que a interface exige é o que restringe a escolha: além de
PIX, boleto, cartão e assinatura recorrente, ela pede createPaymentAccount
(subconta por academia) e configureSplit. Provedor sem marketplace atende a
assinatura do Synse+ e não atende o Synse Pay.
Dados de saúde (avaliações físicas e planos nutricionais) recebem tratamento próprio:
author_staff_id é NOT NULL com ON DELETE RESTRICT. O sistema não emite
prescrição clínica nem interpreta medidas automaticamente.INSERT WITH CHECK (false) na chave anônima).npm run dev # desenvolvimento
npm run build # build de produção
npm run start # servidor de produção
npm run lint # ESLint
npm run typecheck # TypeScript strict
npm run format # Prettier
npm run db:migrate # migrations
npm run db:seed # dados de demonstração
Os tokens vivem em src/app/globals.css e são consumidos pelo Tailwind. O tema
escuro redefine apenas as variáveis — nenhuma classe de componente muda.
| Token | Claro | Escuro |
|---|---|---|
--synse-bg | #F5FAF8 | #041D1B |
--synse-surface | #FFFFFF | #082925 |
--synse-primary | #00A98F | #17C4A5 |
--synse-cyan | #22C7D8 | #35D6E6 |
--synse-text | #102B29 | #E6F5F1 |
O gradiente da marca (#00A98F → #22C7D8) é reservado para áreas estratégicas:
logo, CTA principal, indicadores de progresso e banners.
As paletas dos gráficos foram validadas para banda de luminosidade, piso de
croma, separação sob daltonismo (protanopia, deuteranopia, tritanopia) e contraste
contra a superfície do card — nos dois temas, com passos próprios em cada um.
Os valores estão em src/components/synse/charts/chart-theme.ts.
O SynseHub é executivo; o Synse App é inspiracional. Ambos pertencem visivelmente à mesma marca.
Autenticação · Multi-tenancy com RLS · Layout e navegação por papel · Dashboard com métricas derivadas · Gestão de alunos com filtros e paginação · Perfil do aluno em abas · Planos · Mensalidades · Financeiro · Inadimplentes com régua · Synse Pay simulado · Check-in por QR Code e recepção · Treinos · Synse App · Painel da plataforma · Landing page
Integração real de pagamento · Webhooks em produção · Split ao vivo · Assinaturas recorrentes · Régua automatizada com disparo · Avaliações com registro pelo profissional · Biblioteca de conteúdo · Receitas · Programas Synse 21/30/60/90 · Synse+
Nutrição profissional · Synse Pro · Gamificação e desafios · CRM avançado · Marketplace · Wearables · Synse AI
Synse AI não é construída agora, mas a arquitetura já a acomoda: ela responderá apenas sobre dados que o usuário autorizou e não substitui diagnóstico médico.
npm test # tudo
npm run test:unit # lógica pura, sem banco
npm run test:db # RLS e schema, exige PostgreSQL
Os testes de banco constroem o schema a partir das migrations reais — não há schema duplicado no diretório de testes, porque um schema paralelo divergiria justamente nos detalhes que os testes existem para proteger. Sem PostgreSQL disponível eles pulam com aviso, e a suíte de lógica pura continua rodando.
Para rodar a suíte completa, aponte TEST_DATABASE_URL para um banco vazio:
TEST_DATABASE_URL=postgresql://postgres@localhost:5432/synse_test npm run test:db
O que a suíte cobre, e por quê:
| Arquivo | Protege |
|---|---|
unit/split | o cálculo do dinheiro: soma exata, arredondamento, as três estratégias de tarifa |
unit/permissions | quem enxerga o quê, incluindo o professor que não vê o financeiro |
db/rls | isolamento entre academias, acesso anônimo, nome dos alunos visível para a equipe |
db/schema | RLS ligada em toda tabela, e-mail único, formato do Synse ID, comissão vinda do banco |
db/signup | cadastro de academia: anônimo recusado, duplicidade recusada, isolamento preservado |
db/rls-performance | a forma do plano de execução, para a RLS não voltar a ser avaliada linha a linha |
Cada teste de banco corresponde a uma falha que já aconteceu. O de desempenho verifica o plano, não o relógio: o que importa é a política ser avaliada uma vez por consulta, e não o número de milissegundos numa máquina específica.
Credenciais a rotacionar, ambiente de desenvolvimento separado, plano da Vercel
e a verificação do Synse Pay ponta a ponta estão em
docs/pre-producao.md, e o roteiro para publicar nas
lojas — do Supabase ao envio — em
docs/publicar-passo-a-passo.md.
Durante a construção é comum
adiar esses itens — a lista existe para que adiar não vire esquecer.
Honestidade sobre o estado atual, revisada em 12/09/2026.
consents
existe desde a 0003 e não é lida nem escrita por lugar nenhum. É a única tela
do produto que afirma algo falso sobre dado do usuário, e por ser matéria de
LGPD deveria sair ou virar verdade antes de qualquer cliente./workouts é somente leitura. É a lacuna mais cara do produto — o gatilho de
"novo treino disponível" nunca dispara porque nada atribui treino.createPlan existe no data source e não
tem tela nem ação.public. Num PostgreSQL fora do Supabase é preciso
conceder na mão.Disciplina hoje. Liberdade sempre.
Saúde é a base de tudo.