first commit

This commit is contained in:
2026-05-04 09:43:36 +01:00
commit dfae1b5335
37 changed files with 10343 additions and 0 deletions

139
docs/03-arquitectura.md Normal file
View File

@@ -0,0 +1,139 @@
# 3. Arquitectura do Sistema
## 3.1 Visão Geral
A arquitectura da PawLink segue o padrão de aplicação web moderna com separação clara entre frontend, backend e serviços externos. Adoptamos uma abordagem **server-first** com Next.js, que permite renderização no servidor (SSR) para melhor SEO e desempenho inicial, combinada com componentes interactivos no cliente onde necessário.
```
┌─────────────────────────────────────────────────────────────┐
│ CLIENTE (Browser) │
│ React 18 · Tailwind CSS · TanStack Query │
└───────────────────────┬─────────────────────────────────────┘
│ HTTPS
┌───────────────────────▼─────────────────────────────────────┐
│ VERCEL (Edge Network) │
│ Next.js 14 — SSR · API Routes · Middleware │
├──────────────┬──────────────┬───────────────────────────────┤
│ Auth Layer │ API Routes │ Static Assets (CDN) │
│ NextAuth.js │ Prisma ORM │ Cloudflare │
└──────┬───────┴──────┬───────┴───────────────────────────────┘
│ │
┌──────▼──────┐ ┌─────▼──────────────────────────────────────┐
│ Supabase │ │ Serviços Externos │
│ PostgreSQL │ │ Stripe · Resend · Anthropic · Upstash │
│ + Storage │ │ │
└─────────────┘ └──────────────────────────────────────────────┘
```
---
## 3.2 Camadas da Arquitectura
### Camada de Apresentação (Frontend)
| Tecnologia | Função |
|---|---|
| **Next.js 14+ (App Router)** | Framework principal — SSR, routing, optimização de imagens |
| **TypeScript** | Tipagem estática para reduzir bugs em desenvolvimento |
| **Tailwind CSS** | Estilos utilitários responsivos e consistentes |
| **shadcn/ui** | Componentes acessíveis (ARIA) e personalizáveis |
| **TanStack Query** | Cache de dados do servidor, loading/error states |
| **Zustand** | Estado global da aplicação (sessão, preferências UI) |
| **React Hook Form + Zod** | Formulários com validação type-safe |
### Camada de Lógica de Negócio (Backend)
| Tecnologia | Função |
|---|---|
| **Next.js API Routes** | Endpoints serverless co-localizados com o frontend |
| **NextAuth.js** | Autenticação completa com middleware de protecção de rotas |
| **Prisma ORM** | Acesso type-safe à base de dados com migrações automáticas |
| **Zod** | Validação rigorosa de todos os dados de entrada |
| **bcryptjs** | Hash seguro de palavras-passe |
### Camada de Dados
| Tecnologia | Função |
|---|---|
| **PostgreSQL via Supabase** | Base de dados relacional principal |
| **Supabase Storage** | Armazenamento de imagens de animais e documentos |
| **Upstash Redis** | Cache de sessões e rate limiting |
### Serviços Externos
| Serviço | Função |
|---|---|
| **Stripe** | Processamento de pagamentos (Cartão, MBWay via Payment Element) |
| **Resend + react-email** | Envio de emails transaccionais com templates profissionais |
| **Anthropic Claude API** | IA para match inteligente e chatbot de suporte |
| **Cloudflare** | CDN global, protecção DDoS, cache de assets |
| **Sentry** | Monitorização de erros em produção |
| **Vercel Analytics** | Core Web Vitals e métricas de performance |
---
## 3.3 Fluxo de Dados — Adopção
```
Utilizador
[1] GET / → Next.js SSR → Prisma query → PostgreSQL
│ Renderiza lista de animais no servidor
[2] Aplica filtros → TanStack Query → GET /api/animals?district=Lisboa&species=DOG
[3] API Route valida params (Zod) → Prisma query com WHERE clause
[4] Resposta JSON → React actualiza componentes AnimalGrid
[5] Clica "Adoptar" → Middleware Next.js verifica sessão JWT
│ (sem sessão → redirect /login)
[6] Selecciona data → POST /api/reservations { animalId, date }
[7] API Route valida (Zod) → Prisma: UPDATE animal SET status='RESERVED'
→ Prisma: CREATE reservation
[8] Resend envia email de confirmação com template react-email
[9] Resposta 201 → TanStack Query invalida cache → UI actualiza estado do animal
```
---
## 3.4 Fluxo de Dados — Doação Monetária
```
[1] Utilizador selecciona canil e montante
[2] POST /api/donations/intent → Stripe cria PaymentIntent
[3] Frontend renderiza Stripe Payment Element (dados do cartão tratados pelo Stripe)
[4] Stripe processa pagamento → webhook POST /api/payments/webhook
[5] API Route verifica assinatura HMAC do webhook
[6] Prisma: UPDATE donation SET status='COMPLETED'
[7] Resend envia recibo de doação
```
---
## 3.5 Decisões de Arquitectura
### Porque Next.js e não SPA pura (Vite/React)?
O SEO é crítico para uma plataforma de adopção — os animais devem aparecer nos resultados de pesquisa do Google. Com SSR, a página `/animals/bobi-labrador-lisboa` renderiza HTML completo no servidor, indexável pelos motores de busca. Uma SPA devolveria apenas HTML vazio.
### Porque Supabase e não base de dados gerida manualmente?
O Supabase oferece PostgreSQL gerido, storage de ficheiros, autenticação e realtime numa única plataforma com free tier generoso. Reduz a complexidade operacional para uma equipa pequena sem comprometer escalabilidade.
### Porque Stripe e não Paypal?
O Stripe tem suporte nativo a MBWay (método de pagamento dominante em Portugal), SEPA Direct Debit e MB Multibanco através do Stripe Payment Element. Tem a melhor integração com o ecossistema Node.js/TypeScript e é PCI DSS Level 1.