SaaS de agendamento de retirada de encomendas para padarias.
Produto de referência neste repo: Padaria São Marco (demo via slug demo ou o slug que você criar).
Marca da plataforma: FornoSlot.
- Next.js App Router (TypeScript strict) + Tailwind CSS v4
- next-intl (
/pt,/en) - Supabase Auth (e-mail/senha) + Postgres + RLS
- Validação Zod em Server Actions
- RPC
create_bookingcom lock + checagem de capacity (anti-overbooking)
- Timezone padrão:
America/Sao_Paulo - Auth: e-mail + senha (magic link pode ser habilitado no painel Supabase depois)
- CTA “Agendar demo” aponta para
/b/demo/agendar— crie uma padaria com slugdemo(ou troque o link) - Rate limit de booking é in-memory (por instância); em multi-região use Upstash/Redis depois
- Confirmação pública lê resumo via RPC
get_booking_summary(UUID); sem telefone/e-mail
Copie .env.example → .env.local:
NEXT_PUBLIC_SUPABASE_URL=https://xxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...Não coloque SUPABASE_SERVICE_ROLE_KEY em variáveis NEXT_PUBLIC_*.
npm install
cp .env.example .env.local # preencha URL + anon key
npm run devAbra http://localhost:3000 (redireciona para /pt).
- Crie um projeto em supabase.com
- Authentication → Providers → Email habilitado
- SQL Editor → cole e execute
supabase/migrations/20260719120000_initial_schema.sql
npx supabase login
npx supabase link --project-ref SEU_PROJECT_REF
npx supabase db push- Em
/pt/entrar, crie uma conta (ex.:dono@padaria.test/ senha ≥ 8 chars) - Se o projeto exigir confirmação de e-mail, desative “Confirm email” em Auth → Settings para dev, ou confirme pelo inbox
- Complete o onboarding (nome + slug, ex.
demo) - No painel, adicione disponibilidade (ex. Segunda 08:00–12:00, slot 30, capacity 3)
npm run devcom.env.localválido e migration aplicada- Crie conta em
/pt/entrare a padaria no onboarding (slugdemo) - No
/pt/painel, adicione regra de disponibilidade para hoje/amanhã - Abra aba anônima em
/pt/b/demo/agendar - Escolha horário, preencha nome/telefone/itens → confirmar
- Volte ao painel logado: veja o booking → Confirmar / Cancelar
Idiomas: /pt e /en (mesmo fluxo).
| Rota | Quem | Função |
|---|---|---|
/[locale] |
público | Landing FornoSlot |
/[locale]/entrar |
público | Auth padaria |
/[locale]/onboarding |
autenticado | Criar padaria |
/[locale]/painel |
member | Disponibilidade + agenda |
/[locale]/b/[slug]/agendar |
público | Reservar horário |
/[locale]/b/[slug]/agendar/confirmacao |
público | Resumo do agendamento |
bakeries/availability_rules: SELECT público; escrita só memberbookings: SELECT/UPDATE só member; INSERT público somente viacreate_bookingget_slot_occupancy: contagens sem PIIget_booking_summary: resumo por UUID (sem telefone/e-mail)- Nenhuma policy “allow all”
npm run dev
npm run lint
npm run build- Frontend: Vercel (importar repo, setar env vars)
- Banco/Auth: Supabase (migration + Auth redirect URLs:
https://seu-dominio/*ehttp://localhost:3000/*)