318 lines
8.8 KiB
Markdown
318 lines
8.8 KiB
Markdown
# Backoffice API - NestJS
|
|
|
|
[](https://nestjs.com/)
|
|
[](https://typescriptlang.org/)
|
|
[](https://fastify.io/)
|
|
|
|
GoHorse Jobs SaaS Administration, Subscription Management, and Email Worker API.
|
|
|
|
---
|
|
|
|
## 🏗️ Arquitetura
|
|
|
|
```mermaid
|
|
C4Container
|
|
title Container Diagram - Backoffice Architecture
|
|
|
|
Person(admin, "Admin System", "Platform Administrator")
|
|
System_Ext(go_api, "Go Backend API", "Core Business Logic")
|
|
|
|
Container_Boundary(backoffice_boundary, "Backoffice") {
|
|
Container(backoffice, "Backoffice API", "NestJS", "Admin Dashboard, Worker & Integration Layer")
|
|
}
|
|
|
|
System_Ext(db, "PostgreSQL", "Shared Database (Templates, Settings)")
|
|
System_Ext(mq, "LavinMQ", "Email/Job Queue")
|
|
System_Ext(stripe, "Stripe", "Payment Gateway")
|
|
System_Ext(fcm, "Firebase FCM", "Push Notifications")
|
|
System_Ext(smtp, "SMTP Service", "Email Delivery")
|
|
|
|
Rel(admin, backoffice, "Views Stats/Revenue", "HTTPS")
|
|
Rel(go_api, mq, "Publishes Email Jobs", "AMQP")
|
|
|
|
Rel(backoffice, mq, "Consumes Jobs", "AMQP")
|
|
Rel(backoffice, db, "Read/Write", "SQL")
|
|
Rel(backoffice, stripe, "Syncs Payments", "HTTPS")
|
|
Rel(backoffice, fcm, "Sends Notifications", "HTTPS")
|
|
Rel(backoffice, smtp, "Sends Emails", "SMTP")
|
|
```
|
|
|
|
```
|
|
backoffice/
|
|
├── src/
|
|
│ ├── admin/ # Dashboard e estatísticas
|
|
│ │ ├── admin.controller.ts
|
|
│ │ ├── admin.service.ts
|
|
│ │ └── admin.module.ts
|
|
│ │
|
|
│ ├── auth/ # Autenticação JWT
|
|
│ │ ├── jwt-auth.guard.ts
|
|
│ │ ├── jwt-strategy.ts
|
|
│ │ └── auth.module.ts
|
|
│ │
|
|
│ ├── email/ # Email Worker (LavinMQ Consumer)
|
|
│ │ ├── email.service.ts
|
|
│ │ ├── email.module.ts
|
|
│ │ └── entities/
|
|
│ │ ├── email-setting.entity.ts
|
|
│ │ └── email-template.entity.ts
|
|
│ │
|
|
│ ├── external-services/ # Gestão de credenciais
|
|
│ │ ├── external-services.controller.ts
|
|
│ │ ├── external-services.service.ts
|
|
│ │ └── external-services.module.ts
|
|
│ │
|
|
│ ├── fcm-tokens/ # Firebase Cloud Messaging
|
|
│ │ ├── fcm-tokens.controller.ts
|
|
│ │ ├── fcm-tokens.service.ts
|
|
│ │ └── fcm-tokens.module.ts
|
|
│ │
|
|
│ ├── plans/ # Planos de assinatura
|
|
│ │ ├── plans.controller.ts
|
|
│ │ ├── plans.service.ts
|
|
│ │ └── plans.module.ts
|
|
│ │
|
|
│ ├── stripe/ # Integração Stripe
|
|
│ │ ├── stripe.controller.ts
|
|
│ │ ├── stripe.service.ts
|
|
│ │ └── stripe.module.ts
|
|
│ │
|
|
│ ├── app.module.ts # Módulo raiz
|
|
│ └── main.ts # Bootstrap
|
|
```
|
|
|
|
---
|
|
|
|
## 🔧 Módulos
|
|
|
|
| Módulo | Descrição |
|
|
|--------|-----------|
|
|
| **AdminModule** | Dashboard stats, revenue analytics, subscription metrics |
|
|
| **AuthModule** | JWT validation (Bearer + Cookie), guards |
|
|
| **EmailModule** | LavinMQ consumer, Nodemailer sender, template rendering (Handlebars) |
|
|
| **ExternalServicesModule** | RSA encryption, credentials storage |
|
|
| **FcmTokensModule** | Firebase Admin SDK, push notifications |
|
|
| **PlansModule** | Subscription plans CRUD |
|
|
| **StripeModule** | Checkout sessions, webhooks, billing portal |
|
|
|
|
---
|
|
|
|
## 📧 Email Worker
|
|
|
|
O módulo `EmailModule` atua como **consumer** do LavinMQ:
|
|
|
|
### Fluxo
|
|
|
|
```
|
|
1. Go Backend → Publica job em `mail_queue`
|
|
2. NestJS → Consome job da fila
|
|
3. NestJS → Busca template do banco (email_templates)
|
|
4. NestJS → Renderiza com Handlebars
|
|
5. NestJS → Envia via SMTP (Nodemailer)
|
|
```
|
|
|
|
### Entidades (TypeORM)
|
|
|
|
```typescript
|
|
// email_settings
|
|
{
|
|
id: UUID,
|
|
provider: string,
|
|
smtp_host: string,
|
|
smtp_port: number,
|
|
smtp_user: string,
|
|
smtp_pass: string,
|
|
smtp_secure: boolean,
|
|
sender_name: string,
|
|
sender_email: string,
|
|
amqp_url: string,
|
|
is_active: boolean
|
|
}
|
|
|
|
// email_templates
|
|
{
|
|
id: UUID,
|
|
slug: string,
|
|
subject: string,
|
|
body_html: string,
|
|
variables: string[]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 💳 Stripe Integration
|
|
|
|
### Endpoints
|
|
|
|
| Método | Endpoint | Descrição |
|
|
|--------|----------|-----------|
|
|
| `POST` | `/stripe/checkout` | Criar Checkout Session |
|
|
| `POST` | `/stripe/portal` | Criar Billing Portal |
|
|
| `POST` | `/stripe/webhook` | Webhook handler |
|
|
|
|
### Webhooks Suportados
|
|
|
|
- `checkout.session.completed` - Pagamento concluído
|
|
- `customer.subscription.created` - Nova assinatura
|
|
- `customer.subscription.updated` - Assinatura atualizada
|
|
- `customer.subscription.deleted` - Assinatura cancelada
|
|
- `invoice.payment_failed` - Pagamento falhou
|
|
|
|
---
|
|
|
|
## 📊 API Reference (Endpoints)
|
|
|
|
### 📈 Dashboard & Analytics (Admin)
|
|
| Método | Endpoint | Descrição |
|
|
|--------|----------|-----------|
|
|
| `GET` | `/admin/stats` | Estatísticas gerais (Empresas, Receita, Assinaturas) |
|
|
| `GET` | `/admin/revenue` | Receita mensal detalhada |
|
|
| `GET` | `/admin/subscriptions-by-plan` | Distribuição de assinaturas por plano |
|
|
|
|
### 📦 Plans Management (SaaS)
|
|
| Método | Endpoint | Descrição |
|
|
|--------|----------|-----------|
|
|
| `GET` | `/plans` | Listar todos os planos |
|
|
| `GET` | `/plans/{id}` | Detalhes de um plano |
|
|
| `POST` | `/plans` | Criar novo plano |
|
|
| `PATCH` | `/plans/{id}` | Atualizar plano |
|
|
| `DELETE` | `/plans/{id}` | Remover plano |
|
|
|
|
### 🔑 Credentials & Integrations
|
|
| Método | Endpoint | Descrição |
|
|
|--------|----------|-----------|
|
|
| `POST` | `/admin/credentials/stripe` | Salvar Chave API Stripe (Criptografado) |
|
|
| `GET` | `/system/credentials` | Listar serviços com credenciais configuradas |
|
|
| `POST` | `/system/credentials` | Salvar credencial genérica (Service Payload) |
|
|
| `DELETE` | `/system/credentials/{serviceName}` | Remover credencial de serviço |
|
|
|
|
### 📲 Push Notifications (FCM)
|
|
| Método | Endpoint | Descrição |
|
|
|--------|----------|-----------|
|
|
| `POST` | `/fcm-tokens` | Registrar token de dispositivo (iOS/Android/Web) |
|
|
|
|
### 💳 Stripe & Billing
|
|
| Método | Endpoint | Descrição |
|
|
|--------|----------|-----------|
|
|
| `POST` | `/stripe/checkout` | Criar Checkout Session |
|
|
| `POST` | `/stripe/portal` | Gerar Link do Billing Portal |
|
|
| `POST` | `/stripe/webhook` | Webhook Event Handler |
|
|
|
|
---
|
|
|
|
## 🔒 Autenticação
|
|
|
|
O backoffice suporta **dois métodos**:
|
|
|
|
1. **Bearer Token** - `Authorization: Bearer <token>`
|
|
2. **JWT Cookie** - `jwt=<token>` (fallback)
|
|
|
|
Implementado em `src/auth/jwt-auth.guard.ts`.
|
|
|
|
---
|
|
|
|
## 🔐 External Services Credentials
|
|
|
|
Gerenciamento seguro de credenciais com criptografia RSA:
|
|
|
|
```typescript
|
|
// Fluxo de criptografia
|
|
1. Frontend envia credencial
|
|
2. Backoffice criptografa com RSA public key
|
|
3. Armazena criptografada no banco (external_services_credentials)
|
|
4. Go Backend descriptografa com private key quando necessário
|
|
```
|
|
|
|
### Services Suportados
|
|
|
|
- Stripe
|
|
- Firebase (FCM)
|
|
- Cloudflare
|
|
- SMTP (Email)
|
|
- S3/R2 (Storage)
|
|
|
|
---
|
|
|
|
## 🔧 Environment Variables
|
|
|
|
```bash
|
|
# Server
|
|
PORT=3001
|
|
|
|
# Database (compartilhado com Go)
|
|
DATABASE_URL=postgres://user:pass@host:5432/dbname
|
|
|
|
# Stripe
|
|
STRIPE_SECRET_KEY=sk_test_xxx
|
|
STRIPE_WEBHOOK_SECRET=whsec_xxx
|
|
|
|
# Firebase
|
|
FIREBASE_ADMIN_SDK_PATH=/path/to/service-account.json
|
|
# OU
|
|
FIREBASE_SERVICE_ACCOUNT={"type":"service_account",...}
|
|
|
|
# JWT (mesmo do Go backend)
|
|
JWT_SECRET=your-secret-key
|
|
```
|
|
|
|
---
|
|
|
|
## 🚀 Desenvolvimento Local
|
|
|
|
### Pré-requisitos
|
|
- **Node.js 20+**
|
|
- **pnpm 9+**
|
|
- **Podman** (para containerizar)
|
|
|
|
### Executar (Nativo)
|
|
```bash
|
|
# Instalar dependências
|
|
pnpm install
|
|
|
|
# Desenvolvimento (Hot Reload)
|
|
pnpm start:dev
|
|
|
|
# Produção
|
|
pnpm build
|
|
pnpm start:prod
|
|
```
|
|
|
|
### Executar com Podman (Container)
|
|
```bash
|
|
# Build da imagem
|
|
podman build -t gohorse-backoffice .
|
|
|
|
# Rodar container
|
|
# --net host recomendado para acessar DB local em desenvolvimento
|
|
podman run --name backoffice -p 3001:3001 --env-file .env gohorse-backoffice
|
|
```
|
|
|
|
> **Nota:** Não utilizamos `docker-compose`. Para orquestração em produção, utilizamos **Quadlet**.
|
|
|
|
---
|
|
|
|
## 📦 Tech Stack
|
|
|
|
| Tecnologia | Versão | Uso |
|
|
|------------|--------|-----|
|
|
| NestJS | 11+ | Framework |
|
|
| Fastify | 4+ | HTTP Server |
|
|
| TypeORM | 0.3+ | ORM (Email entities) |
|
|
| Stripe | 20+ | Pagamentos |
|
|
| Firebase Admin | 13+ | Push Notifications |
|
|
| amqplib | 0.10+ | LavinMQ Consumer |
|
|
| Nodemailer | 6+ | SMTP Client |
|
|
| Handlebars | 4+ | Template Engine |
|
|
| Pino | 9+ | Logging |
|
|
|
|
---
|
|
|
|
## 🔗 Integrações
|
|
|
|
| Serviço | Módulo | Uso |
|
|
|---------|--------|-----|
|
|
| **Stripe** | StripeModule | Pagamentos, assinaturas |
|
|
| **LavinMQ** | EmailModule | Fila de emails |
|
|
| **Firebase** | FcmTokensModule | Push notifications |
|
|
| **PostgreSQL** | TypeORM | Email settings/templates |
|