gohorsejobs/backend/BACKEND.md

14 KiB
Executable file

Backend - GoHorse Jobs API

Go PostgreSQL

Last Updated: 2024-12-29

API REST desenvolvida em Go seguindo princípios de Clean Architecture e DDD.


🏗️ Arquitetura

backend/
├── cmd/
│   ├── api/                # Entrypoint principal
│   └── manual_migrate/     # Migration runner
│
├── internal/
│   ├── api/                # Clean Architecture Layer
│   │   ├── handlers/       # HTTP Handlers (Admin, Auth, Settings, Storage, Tickets)
│   │   └── middleware/     # Auth, CORS, Rate Limiting, Sanitize
│   │
│   ├── core/               # Domain Layer (DDD)
│   │   ├── domain/entity/  # Entidades (User, Company, Email)
│   │   ├── ports/          # Interfaces (Repositories)
│   │   └── usecases/       # Casos de uso (Auth, Register)
│   │
│   ├── infrastructure/     # Infrastructure Layer
│   │   ├── auth/           # JWT Service implementation
│   │   └── persistence/    # Repository implementations (Postgres)
│   │
│   ├── services/           # Business logic services (Email, Notification, Tickets)
│   │
│   ├── dto/                # Data Transfer Objects
│   ├── models/             # GORM models (Legacy/Transition)
│   ├── router/             # Route configuration
│   └── utils/              # Helpers (JWT, Sanitizer)
│
├── migrations/             # SQL Migrations (30+)
├── tests/                  # E2E and Integration tests
└── docs/                   # Swagger documentation

📊 Diagrama de Fluxo (C4 Simplificado)

graph TD
    Client[📱 Clients Frontend/App] -->|JSON/HTTP| Router[🚦 Router Mux]
    
    subgraph CoreBackend [Core Backend]
        Router --> Middleware[🛡️ Middleware Auth/CORS]
        Middleware --> Handlers[🎮 HTTP Handlers]
        Handlers --> UseCases[🧠 Services & UseCases]
        UseCases --> Repos[💾 Repositories]
        UseCases --> Adapters[🔌 External Adapters]
    end
    
    Repos --> DB[(🐘 PostgreSQL)]
    
    Adapters --> Firebase[🔥 Firebase FCM]
    Adapters --> LavinMQ[📨 LavinMQ]
    Adapters --> Storage[☁️ S3/R2 Storage]
    Adapters --> Stripe[💳 Stripe]

🚀 Deployment & CI/CD (Forgejo)

O deployment é automatizado via Forgejo Actions.

Workflow: Deploy Backend (Dev)

Arquivo: .forgejo/workflows/deploy.yaml

Este workflow é disparado automaticamente ao realizar um push para o branch dev com alterações na pasta backend/.

Etapas do CI/CD:

  1. Trigger: Push no branch dev (apenas alterações em backend/**).
  2. Runner: Executa no ambiente docker (verifique as labels do seu runner).
  3. SSH Action: Conecta no servidor de desenvolvimento (Apolo) via SSH.
  4. Atualização de Código:
    • Navega até /mnt/data/gohorsejobs (ou caminho configurado).
    • Faz git fetch e git checkout dev.
    • git pull origin dev.
  5. Build & Restart (Podman):
    • Constrói a imagem: podman build -t localhost/gohorsejobs-backend-dev ./backend
    • Reinicia o serviço: sudo systemctl restart gohorsejobs-backend-dev
    • Limpeza: podman image prune -f

Secrets Necessários (Forgejo):

  • HOST: IP do servidor.
  • USERNAME: Usuário SSH.
  • SSH_KEY: Chave privada SSH.
  • PORT: Porta SSH (ex: 22).

🔧 Services

Service Arquivo Descrição
AdminService admin_service.go CRUD de empresas, usuários, candidatos, tags, email templates
JobService job_service.go CRUD de vagas com filtros avançados
ApplicationService application_service.go Gestão de candidaturas
TicketService ticket_service.go (Novo) Sistema de tickets de suporte
ChatService chat_service.go Mensagens e conversas (Appwrite)
NotificationService notification_service.go Notificações push
EmailService email_service.go Produtor de emails via LavinMQ
FCMService fcm_service.go Firebase Cloud Messaging
StorageService storage_service.go Pre-signed URLs (S3/R2)
CredentialsService credentials_service.go (Novo) Gestão de credenciais criptografadas
CloudflareService cloudflare_service.go Cache purge via API
SettingsService settings_service.go System settings
AppwriteService appwrite_service.go Integração Appwrite Realtime
AuditService audit_service.go Logs de auditoria

🔒 Segurança

Middlewares Implementados

Middleware Arquivo Descrição
Auth middleware/auth.go Validação JWT + RBAC
CORS middleware/cors.go Whitelist de origens via CORS_ORIGINS
Rate Limiting middleware/rate_limit.go 100 req/min por IP
Security Headers middleware/security_headers.go OWASP headers (XSS, CSP, etc.)
Sanitize middleware/sanitize.go XSS sanitization em JSON bodies

Autenticação

  • JWT com expiração configurável
  • Password Pepper via PASSWORD_PEPPER env var
  • HttpOnly Cookies para refresh tokens
  • RSA Encryption para credenciais sensíveis

📡 Endpoints (API Reference)

🔐 Auth & Identity

Método Endpoint Descrição Roles
POST /api/v1/auth/login Autenticação (Retorna JWT + User) Public
POST /api/v1/auth/logout Logout (Limpa Cookie HttpOnly) Public
POST /api/v1/auth/register Registro de Candidato Public
POST /api/v1/auth/register/company Registro de Empresa (Cria Admin) Public
POST /api/v1/tokens Salvar token FCM para Push Auth

👤 Users & Profiles

Método Endpoint Descrição Roles
GET /api/v1/users/me Dados do usuário logado Auth
PATCH /api/v1/users/me/profile Atualizar meu perfil Auth
GET /api/v1/users Listar usuários (Admin: da empresa. Superadmin: todos) Admin/Super
POST /api/v1/users Criar usuário (Admin: user normal. Superadmin: pode criar outros Supers) Admin/Super
GET /api/v1/users/roles Listar roles disponíveis no sistema Admin/Super
PATCH /api/v1/users/{id} Atualizar usuário Admin/Super
DELETE /api/v1/users/{id} Remover usuário Admin/Super

🏢 Companies (Tenants)

Método Endpoint Descrição Roles
GET /api/v1/companies Listar empresas (Public: simples. Admin: detalhado) Public/Admin
POST /api/v1/companies Criar nova empresa (via auto-cadastro ou Admin) Public
GET /api/v1/companies/{id} Detalhes da empresa Public
PATCH /api/v1/companies/{id} Editar dados da empresa Admin/Super
PATCH /api/v1/companies/{id}/status Alterar status (Ativo/Inativo) Admin/Super
DELETE /api/v1/companies/{id} Remover empresa (Soft delete) Admin/Super

💼 Jobs (Vagas)

Método Endpoint Descrição Roles
GET /api/v1/jobs Listar vagas (filtros: local, keywords) Public
GET /api/v1/jobs/{id} Detalhes da vaga Public
POST /api/v1/jobs Criar nova vaga Recruiter
PUT /api/v1/jobs/{id} Editar vaga Recruiter
DELETE /api/v1/jobs/{id} Remover vaga Recruiter
POST /api/v1/jobs/{id}/duplicate Duplicar uma vaga existente Admin/Recruiter
GET /api/v1/jobs/moderation Listar vagas para moderação Admin/Super
PATCH /api/v1/jobs/{id}/status Aprovar/Rejeitar vaga Admin/Super

📝 Applications (Candidaturas)

Método Endpoint Descrição Roles
POST /api/v1/applications Candidatar-se a uma vaga Candidate
GET /api/v1/applications Minhas candidaturas (ou recebidas, se Recruiter) Auth
GET /api/v1/applications/{id} Detalhes da candidatura Auth
PUT /api/v1/applications/{id}/status Atualizar fase/status Recruiter
DELETE /api/v1/applications/{id} Desistir/Remover Auth
GET /api/v1/candidates Listar base de candidatos (Global) Admin/Super

🎫 Support (Tickets)

Método Endpoint Descrição Roles
GET /api/v1/support/tickets Meus tickets de suporte Auth
GET /api/v1/support/tickets/all Todos os tickets (Visão Admin) SuperAdmin
POST /api/v1/support/tickets Abrir novo ticket Auth
GET /api/v1/support/tickets/{id} Ver conversa do ticket Auth
POST /api/v1/support/tickets/{id}/messages Enviar mensagem no ticket Auth
PATCH /api/v1/support/tickets/{id}/close Fechar ticket Auth
DELETE /api/v1/support/tickets/{id} Remover ticket Admin/Super

💬 Chat & Messaging

Método Endpoint Descrição Roles
GET /api/v1/conversations Listar conversas ativas Auth
GET /api/v1/conversations/{id}/messages Ver histórico de mensagens Auth
POST /api/v1/conversations/{id}/messages Enviar mensagem direta Auth

🔔 Notifications

Método Endpoint Descrição Roles
GET /api/v1/notifications Listar notificações Auth
PATCH /api/v1/notifications/{id}/read Marcar como lida Auth
PATCH /api/v1/notifications/read-all Marcar todas como lidas Auth

🌍 Locations

Método Endpoint Descrição Roles
GET /api/v1/locations/countries Listar países Public
GET /api/v1/locations/countries/{id}/states Listar estados de um país Public
GET /api/v1/locations/states/{id}/cities Listar cidades de um estado Public
GET /api/v1/locations/search Busca textual (Cidade/Estado) Public

🏷️ Tags & Metadata

Método Endpoint Descrição Roles
GET /api/v1/tags Listar tags (skills, benefícios) Public
POST /api/v1/tags Criar nova tag Admin/Super
PATCH /api/v1/tags/{id} Editar tag Admin/Super

⚙️ System & Settings

Método Endpoint Descrição Roles
GET /api/v1/system/settings/{key} Ler configuração de sistema Auth
POST /api/v1/system/settings/{key} Salvar configuração SuperAdmin
GET /api/v1/system/credentials Ver credenciais (mascaradas) SuperAdmin
POST /api/v1/system/credentials Salvar/Rotacionar credencial SuperAdmin
GET /api/v1/storage/upload-url Gerar URL pré-assinada (S3/R2) Auth
POST /api/v1/system/cloudflare/purge Limpar cache CDN SuperAdmin
GET /api/v1/audit/logins Ver logs de acesso SuperAdmin

📧 Email Management

Método Endpoint Descrição Roles
GET /api/v1/admin/email-templates Listar templates SuperAdmin
POST /api/v1/admin/email-templates Criar template SuperAdmin
GET /api/v1/admin/email-settings Configurações SMTP/Provider SuperAdmin
PUT /api/v1/admin/email-settings Atualizar configs de email SuperAdmin

💳 Payments

Método Endpoint Descrição Roles
POST /api/v1/payments/create-checkout Criar sessão de checkout Auth
GET /api/v1/payments/status/{id} Verificar status pagto Auth
POST /api/v1/payments/webhook Webhook (Stripe/Gateway) Public

🗄️ Migrations

O projeto usa um sistema de migrations manuais via cmd/manual_migrate.

Executar Migrations

go run ./cmd/manual_migrate

💻 Desenvolvimento Local

Pré-requisitos

  • Go 1.22+
  • Podman (ou Docker, mas o projeto é otimizado para Podman/Quadlet)
  • PostgreSQL (Rodando local ou via container)

Executar com Go (Método Padrão)

# 1. Configurar Ambiente
cp .env.example .env
# Edite o .env com suas credentials (DB, JWT_SECRET, etc)

# 2. Executar Migrations
go run ./cmd/manual_migrate

# 3. Iniciar API Server
go run ./cmd/api

Executar com Podman (Container)

# Construir a imagem
podman build -t gohorse-backend ./backend

# Rodar o container
# Nota: --network host é útil em dev para acessar o DB local facilmente
podman run --name api -p 8080:8080 --env-file ./backend/.env gohorse-backend

Nota: Não utilizamos docker-compose neste projeto. A infraestrutura de produção utiliza Quadlet (Systemd + Podman). Para dev, recomenda-se rodar o binário Go nativo ou usar podman run individualmente.

Testes

# Todos os testes
go test ./...

# Com cobertura
go test -cover ./...

Troubleshooting (CI/CD & Runner)

O Workflow não inicia (Waiting for runner...)

  • Causa: Nenhuma maquina registrada com o label correto.
  • Solução:
    1. Verifique, no arquivo .forgejo/workflows/deploy.yaml, o campo runs-on.
    2. Se estiver como docker, seu act_runner deve ter suporte a este label (ex: labels: "docker:docker://node:16-bullseye,ubuntu-latest:docker://node:16-bullseye" no config.yaml).
    3. Se o runner for genérico, use ubuntu-latest.

Falha de SSH (ssh: handshake failed)

  • Solução:
    1. Verifique se a chave pública (id_rsa.pub) correspondente à SSH_KEY do secret está no arquivo ~/.ssh/authorized_keys da máquina de destino.
    2. Confira se o IP (HOST) está acessível da rede onde o runner está.

Falha de Build no Podman

  • Causa: Falta de permissão ou serviço parado.
  • Solução:
    1. Rode podman logs -f <conteiner> na máquina de destino.
    2. Verifique se o usuário tem permissão de usar podman (rootless ou sudo).