Skip to content

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

CamadaTecnologia
FrameworkNext.js 14 (App Router) + TypeScript
EstiloTailwind CSS · família UNREAL (Bricolage Grotesque + Hanken Grotesk + JetBrains Mono), papel claro, assinatura teal
Base de dados / Auth / StorageSupabase (PostgreSQL com RLS)
Extração de faturasAPI Anthropic (Claude com visão)
PagamentosStripe (subscrições Lite / Pro / Business)
Email transacionalResend
DeployVercel

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: demo@unrealdocs.pt / 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

PlanoFaturas/mêsPreço de montra
Lite10029 €/mês
Pro40079 €/mês
Business1000179 €/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

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages