# Backend - GoHorse Jobs API

[![Go](https://img.shields.io/badge/Go-1.24-00ADD8?style=flat-square&logo=go)](https://golang.org/)
[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-16-336791?style=flat-square&logo=postgresql)](https://postgresql.org/)

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

```mermaid
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
```bash
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)
```bash
# 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)
```bash
# 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
```bash
# 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).
