Skip to content

mborges-dev/unreal-docs

Repository files navigation

UNREAL Docs

As tuas faturas entram no sistema sozinhas.

SaaS de processamento automático de faturas para empresas portuguesas. A fatura entra (upload ou email dedicado), a IA lê e estrutura os dados, o utilizador valida numa tela lado a lado, e exporta em CSV/JSON/SAF-T — com fornecedores, estados de pagamento e alertas de vencimento incluídos.

Stack

Camada Tecnologia
Framework Next.js 14 (App Router) + TypeScript
Estilo Tailwind CSS · família UNREAL (Bricolage Grotesque + Hanken Grotesk + JetBrains Mono), papel claro, assinatura teal
Base de dados / Auth / Storage Supabase (PostgreSQL com RLS)
Extração de faturas API Anthropic (Claude com visão)
Pagamentos Stripe (subscrições Lite / Pro / Business)
Email transacional Resend
Deploy Vercel

Setup passo a passo

1. Pré-requisitos

2. Instalar dependências

npm install

3. Configurar variáveis de ambiente

cp .env.example .env.local

Preenche pelo menos:

  • NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY — painel Supabase → Project Settings → API
  • ANTHROPIC_API_KEY — sem isto as faturas ficam no estado «erro» ao processar

As restantes (Stripe, Resend, email inbound) são opcionais em desenvolvimento — a aplicação funciona sem elas.

4. Criar a base de dados

Opção A — Supabase Cloud (mais rápido):

No painel Supabase → SQL Editor, corre por ordem:

  1. supabase/migrations/0001_schema_inicial.sql
  2. supabase/migrations/0002_storage.sql
  3. supabase/migrations/0003_nivel1_robustez.sql (linhas de artigo, IVA por taxa, retenção, fila de email, auditoria)
  4. supabase/migrations/0004_nivel2_memoria.sql (categoria de despesa, memória por fornecedor)
  5. supabase/migrations/0005_nivel3_integracoes.sql (ligações a ERP — credenciais Moloni)
  6. supabase/migrations/0006_memoria_v2.sql (identidade do fornecedor: nome canónico, NIFs e valores aprendidos)
  7. supabase/migrations/0007_dados_fiscais.sql (morada da empresa para o Header do SAF-T)
  8. supabase/migrations/0008_aprovacao_reconciliacao.sql (aprovação de pagamento por admin, referência e comprovativo)
  9. supabase/migrations/0009_equipa_e_politica.sql (equipa por empresa, papel dono, política de aprovação; correções de RLS)
  10. supabase/migrations/0010_role_constraint_defensivo.sql (garantia do constraint de papel)
  11. supabase/migrations/0011_rate_limits.sql (rate limiting com store partilhado)
  12. supabase/migrations/0012_pipeline_custo.sql (dedup por hash, degrau e custo por documento, modo lote)
  13. supabase/migrations/0013_camada_contabilistas.sql (firmas: clientes, operadores, RLS aditiva por acesso)
  14. supabase/migrations/0014_hardening_rpc.sql (guarda de acesso nas RPC de uso/rate-limit)

Opção B — Supabase local:

supabase start
supabase db reset   # aplica migrations + seed automaticamente

Com o seed local ficas com uma conta demo: [email protected] / demo1234, com fornecedores e faturas em vários estados.

O supabase/seed.sql insere diretamente em auth.users — é só para desenvolvimento local, nunca o corras em produção.

5. Arrancar

npm run dev

Abre http://localhost:3000, cria conta (ou entra com a demo), dá o nome e NIF da empresa, e arrasta a primeira fatura.


Configurações de produção

Stripe (planos e subscrições)

  1. Cria três produtos com preço mensal recorrente (Lite, Pro, Business) e copia os Price IDs para STRIPE_PRICE_LITE, STRIPE_PRICE_PRO, STRIPE_PRICE_BUSINESS. Os valores de montra mostrados na aplicação configuram-se em lib/plans.ts.
  2. Cria um webhook apontado a https://<o-teu-dominio>/api/webhooks/stripe com os eventos checkout.session.completed, customer.subscription.* e invoice.payment_failed; copia o segredo para STRIPE_WEBHOOK_SECRET.
  3. O período de teste (14 dias) configura-se em STRIPE_TRIAL_DAYS.

Para testar localmente: stripe listen --forward-to localhost:3000/api/webhooks/stripe.

Email inbound (faturas@<org>.unrealdocs.pt)

Cada organização recebe um slug único (email_slug). O webhook /api/webhooks/email-inbound?segredo=<INBOUND_EMAIL_SECRET> aceita:

  • multipart/form-data — SendGrid Inbound Parse, Mailgun
  • JSON com anexos base64 — Postmark, CloudMailin

Configura no teu fornecedor de email inbound um catch-all para *.unrealdocs.pt (ou o domínio que definires em INBOUND_EMAIL_DOMAIN) a apontar para esse endpoint. A organização é identificada pelo destinatário (faturas@<slug>.<domínio>).

Deploy na Vercel

  1. Importa o repositório na Vercel (framework: Next.js, sem configuração extra).
  2. Define todas as variáveis do .env.example no projeto.
  3. Atualiza NEXT_PUBLIC_APP_URL para o domínio final.
  4. No Supabase, adiciona https://<o-teu-dominio>/auth/callback aos Redirect URLs (Authentication → URL Configuration).

Estrutura do projeto

app/
  page.tsx                  Landing page
  (auth)/login, registo     Autenticação (password + magic link)
  onboarding/               Criação da organização (nome + NIF)
  (app)/
    dashboard/              Métricas, alertas de vencimento, evolução mensal
    faturas/                Lista com filtros e pesquisa
    faturas/[id]/           Tela de validação lado a lado (o coração do produto)
    fornecedores/           Lista e histórico por fornecedor
    exportar/               CSV / JSON / SAF-T com seleção múltipla
    integracoes/            Email dedicado, pasta vigiada, conectores ERP
    definicoes/             Empresa, plano, utilização, Stripe
  api/
    invoices/upload         Upload + processamento IA
    invoices/[id]           Correções, validação, pagamento, remoção
    invoices/[id]/reprocessar
    exports/                Geração de ficheiros de exportação
    stripe/checkout, portal
    webhooks/stripe         Sincronização de subscrições
    webhooks/email-inbound  Entrada de faturas por email
    onboarding/             Criação de organização (service role)
lib/
  extraction.ts             Prompt e chamada à API Claude (visão)
  processing.ts             Pipeline: storage → IA → validações → usage
  validation.ts             NIF (dígito de controlo), totais, anomalias
  exporters.ts              CSV, JSON e esqueleto SAF-T
  plans.ts                  Planos, limites e preços (configuráveis)
  integrations.ts           Registo de conectores ERP plugáveis
supabase/
  migrations/               Schema + RLS + storage
  seed.sql                  Dados de exemplo (apenas local)

Segurança

  • RLS em todas as tabelas, isolada por org_id via função current_org_id().
  • Storage privado com políticas por organização; pré-visualizações servidas por URLs assinadas com validade de 1 hora.
  • A chave de service role é usada apenas no servidor (onboarding e webhooks).
  • Webhook de email protegido por segredo partilhado; webhook Stripe verificado por assinatura.

Limites de plano

Plano Faturas/mês Preço de montra
Lite 100 29 €/mês
Pro 400 79 €/mês
Business 1000 179 €/mês

A contagem vive na tabela usage (por organização e mês) e é incrementada atomicamente a cada processamento. Ao atingir 90% o utilizador é avisado; a 100% o processamento é bloqueado até mudar de plano.

About

SaaS de processamento automático de faturas para empresas portuguesas. Upload ou email → Claude Vision extrai e estrutura → validação lado a lado → exportação CSV/JSON/SAF-T.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors