pulguinha

Funcional do Pulguinha

App Flutter de gestão e agendamento para o estúdio Funcional do Pulguinha, baseado no protótipo React (pulguinha-app.jsx).

Funcionalidades

Acesso administrativo

O primeiro admin é criado pelo supabase/schema.sql ao configurar o banco. Em modo demo (sem Supabase), use as mesmas credenciais definidas no seed.

Campo Valor inicial
E-mail admin@pulguinha.com
Senha admin123

Na tela de login, selecione o perfil Admin antes de entrar.

Altere a senha no banco (admins) antes de usar em produção. As credenciais não aparecem mais na interface do app.

Executar localmente

flutter pub get
flutter run

Sem variáveis de ambiente, o app roda em modo demo com dados mock locais.

Testes e qualidade

flutter analyze
flutter test
flutter build web --release --base-href "/pulguinha/"

Com Supabase

  1. Crie um projeto em supabase.com
  2. No SQL Editor, execute supabase/schema.sql (estrutura). Dados demo opcionais: supabase/seed.sql. Banco já em produção: supabase/migration_minimal.sql
  3. Copie a Project URL e a anon public key (Settings → API)
  4. (Opcional) Execute com --dart-define para override no build; senão o app usa os defaults em lib/config/supabase_config.dart:
flutter run
# ou com override:
flutter run \
  --dart-define=SUPABASE_URL=https://SEU_PROJETO.supabase.co \
  --dart-define=SUPABASE_ANON_KEY=sua_chave_anon_aqui

A chave anon é pública no modelo Supabase (protegida por RLS). Para o Pulguinha single-tenant, está commitada no código. Nunca commite a service_role key.

Fotos: armazenadas em base64 no campo foto do aluno (demo). Em produção, prefira Supabase Storage.

Mercado Pago (Checkout Pro)

A integração real está implementada em lib/services/mercado_pago_service.dart. O access token nunca vai para o app — apenas para a Edge Function.

  1. Crie links de pagamento no painel Mercado Pago
  2. Execute com --dart-define por produto:
flutter run \
  --dart-define=MP_PUBLIC_KEY=SUA_PUBLIC_KEY \
  --dart-define=MP_LINK_PLANO_MENSAL=https://mpago.la/... \
  --dart-define=MP_LINK_PLANO_TRIMESTRAL=https://mpago.la/... \
  --dart-define=MP_LINK_PLANO_SEMESTRAL=https://mpago.la/... \
  --dart-define=MP_LINK_PLANO_ANUAL=https://mpago.la/...

Opção B — Edge Function Supabase (Checkout Pro dinâmico)

  1. Deploy da function:
supabase functions deploy create-mp-preference
supabase secrets set MP_ACCESS_TOKEN=SEU_ACCESS_TOKEN_MP
  1. Execute com Supabase + public key:
flutter run \
  --dart-define=SUPABASE_URL=https://SEU_PROJETO.supabase.co \
  --dart-define=SUPABASE_ANON_KEY=sua_chave_anon \
  --dart-define=MP_PUBLIC_KEY=SUA_PUBLIC_KEY
  1. (Opcional) Deep link de retorno: --dart-define=MP_BACK_URL=pulguinha://payment/success

Sem credenciais configuradas, a loja usa modo demonstração com aviso explícito.

Check-in QR (fluxo correto)

  1. Admin/Professor — aba Presença → exibe QR da aula ou QR do dia em tela cheia (projetor/TV)
  2. Aluno — botão “Fazer Check-in” → escaneia o QR com a câmera
  3. Web — scanner via mobile_scanner; se a câmera falhar, use entrada manual do código

Deploy no GitHub Pages

O workflow .github/workflows/deploy.yml faz build e deploy automático a cada push na branch main.

Se o site mostra o conteúdo deste README em vez do app, a causa é quase sempre a origem do Pages estar em “Deploy from a branch” em vez de GitHub Actions. Veja a seção abaixo.

Configuração obrigatória no GitHub (UI)

  1. Abra Settings → Pages → Build and deployment
    • Source: selecione GitHub Actions (não use “Deploy from a branch” / main / (root))
  2. Em Settings → Pages → Custom domain
    • Deixe vazio até configurar o DNS no Registro.br (veja seção abaixo)
    • Depois informe o domínio completo (ex.: app.seudominio.com.br)
  3. Em Settings → Secrets and variables → Actions → Variables, adicione:
    • PAGES_CUSTOM_DOMAIN — domínio completo (ex.: app.seudominio.com.br)
      Quando preenchida, o deploy usa base-href / e gera o arquivo CNAME automaticamente.
  4. (Opcional, para Supabase em produção) Settings → Secrets and variables → Actions → Secrets — adicione:
    • SUPABASE_URL — URL do projeto Supabase
    • SUPABASE_ANON_KEY — chave anon pública
      Sem esses secrets o app publica em modo demo (comportamento esperado).
  5. Dispare o deploy:
    • Actions → Deploy GitHub Pages → Run workflow, ou
    • faça push para main

Aguarde o workflow terminar com sucesso (check verde). O app ficará em:

https://jracingdev.github.io/pulguinha/

Domínio personalizado (Registro.br)

Recomendamos um subdomínio (ex.: app.funcionaldopulguinha.com.br) — configuração mais simples e estável.

1. DNS no Registro.br

  1. Acesse registro.brMeus domínios → seu domínio → DNS
  2. Se o modo for “Página de redirecionamento”, altere para Modo avançado / DNS
  3. Crie o registro conforme o tipo desejado:

Opção A — Subdomínio (recomendado) — ex.: app.seudominio.com.br

Tipo Nome Destino
CNAME app jracingdev.github.io

Opção B — Domínio raiz (apex) — ex.: seudominio.com.br

Tipo Nome Destino
A @ 185.199.108.153
A @ 185.199.109.153
A @ 185.199.110.153
A @ 185.199.111.153

(Opcional, IPv6 — adicione também 4 registros AAAA com os valores oficiais do GitHub Pages.)

Para www.seudominio.com.br, adicione CNAME wwwjracingdev.github.io.

A propagação DNS pode levar de alguns minutos até 24 horas.

2. GitHub

  1. Settings → Pages → Custom domain → informe o domínio (ex.: app.seudominio.com.br) → Save
  2. Aguarde o DNS check ficar verde e o certificado HTTPS ser emitido
  3. Settings → Secrets and variables → Actions → Variables → crie PAGES_CUSTOM_DOMAIN com o mesmo domínio
  4. Rode o workflow Deploy GitHub Pages (ou push em main)

O app passará a abrir em https://app.seudominio.com.br/ (sem /pulguinha/ no final).

Mercado Pago / Supabase: se usar callbacks ou URLs de retorno, atualize-as para o novo domínio.

APK (Android) — zero configuração no celular

O APK já vem com URL e chave anon do Supabase embutidas em lib/config/supabase_config.dart. Qualquer celular conecta automaticamente — não é necessário colar credenciais em Configurações.

Onde Configuração necessária
Cada celular Nenhuma — instalar e usar
GitHub Actions (web) Secrets SUPABASE_URL + SUPABASE_ANON_KEY (opcional para APK; obrigatório só se quiser override no CI)
Build local .\scripts\build_apk.ps1 — usa credenciais embutidas

Tela Conexão Supabase (avançado): só para trocar de projeto (white-label) ou ambiente de teste. O admin normal não precisa abrir essa tela.

# Build local (credenciais já no código)
.\scripts\build_apk.ps1

# Override opcional no build
$env:SUPABASE_URL="https://....supabase.co"
$env:SUPABASE_ANON_KEY="eyJ..."
.\scripts\build_apk.ps1

Build web manual

flutter build web --release --base-href "/pulguinha/"

Com Supabase:

flutter build web --release --base-href "/pulguinha/" \
  --dart-define=SUPABASE_URL=https://SEU_PROJETO.supabase.co \
  --dart-define=SUPABASE_ANON_KEY=sua_chave_anon_aqui

Estrutura

lib/
├── app.dart                      # Roteamento principal
├── config/
│   ├── supabase_config.dart      # URL e chave via --dart-define
│   └── mercado_pago_config.dart  # MP public key, payment links
├── services/
│   ├── supabase_service.dart     # CRUD Supabase
│   └── mercado_pago_service.dart # Checkout Pro / Payment Links
├── screens/                      # Telas por módulo
├── theme/                        # Cores e tema escuro neon
└── widgets/                      # Componentes reutilizáveis

supabase/
├── schema.sql                              # Tabelas, RLS e dados iniciais (seed)
└── functions/create-mp-preference/index.ts # Cria preferência MP (access token no secret)

Roadmap (fora do escopo atual)