gohorsejobs/backoffice/BACKOFFICE.md

8.8 KiB

Backoffice API - NestJS

NestJS TypeScript Fastify

GoHorse Jobs SaaS Administration, Subscription Management, and Email Worker API.


🏗️ Arquitetura

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)

// 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:

// 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

# 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)

# Instalar dependências
pnpm install

# Desenvolvimento (Hot Reload)
pnpm start:dev

# Produção
pnpm build
pnpm start:prod

Executar com Podman (Container)

# 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: 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