gohorsejobs/backend
Tiago Yamamoto 5f3430bd98 fix: reorder uuid_generate_v7 migration to run before tables that use it
- Rename 021_create_uuid_v7_function.sql to 009_create_uuid_v7_function.sql
- Add CREATE EXTENSION IF NOT EXISTS pgcrypto for gen_random_bytes()
- Remove obsolete 022_migrate_to_uuid_v7.sql (already handled by table def)

This fixes the error where migration 017 tried to use uuid_generate_v7()
before it was created.
2025-12-24 11:52:44 -03:00
..
cmd refactor: rename PORT to BACKEND_PORT and API_HOST to BACKEND_HOST 2025-12-23 23:28:17 -03:00
docs docs(backend): update Swagger annotations for admin and core handlers 2025-12-24 00:45:48 -03:00
internal feat: implement high priority features 2025-12-24 11:40:53 -03:00
migrations fix: reorder uuid_generate_v7 migration to run before tables that use it 2025-12-24 11:52:44 -03:00
tests/e2e feat(tests): �� added unit tests and E2E tests for handlers 2025-12-15 09:08:32 -03:00
.dockerignore docs: complete project documentation overhaul 2025-12-09 19:36:36 -03:00
.env.example feat: implement high priority features 2025-12-24 11:40:53 -03:00
.gitignore first commit 2025-12-09 19:04:48 -03:00
Dockerfile fix(docker): align Dockerfile port with .env configuration (8521) 2025-12-13 18:23:48 -03:00
go.mod chore: remove unused google/uuid dependency 2025-12-24 11:42:46 -03:00
go.sum chore: remove unused google/uuid dependency 2025-12-24 11:42:46 -03:00
README.md feat: security refactor, server-side pagination, and docs update 2025-12-23 00:50:51 -03:00

Backend - GoHorse Jobs API

Go PostgreSQL

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


🏗️ Arquitetura

internal/
├── api/                    # Clean Architecture Layer
│   ├── handlers/           # HTTP Handlers (Controllers)
│   └── middleware/         # Auth, CORS, Rate Limiting
│
├── core/                   # Domain Layer (DDD)
│   ├── domain/entity/      # Entidades puras (sem deps externas)
│   ├── ports/              # Interfaces (Repository, Service)
│   └── usecases/           # Casos de uso (Business Logic)
│
├── infrastructure/         # Infrastructure Layer
│   ├── auth/               # JWT Service implementation
│   └── persistence/        # Repository implementations
│
├── handlers/               # Legacy controllers
├── middleware/             # Security middlewares
├── models/                 # GORM models
├── services/               # Business logic (legacy)
└── utils/                  # Helpers (JWT, Sanitizer)

🔒 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.)

Validação de JWT

O servidor valida no boot que JWT_SECRET tenha pelo menos 32 caracteres. Em produção (ENV=production), o servidor não inicia com secrets fracos.


📡 Endpoints

Públicos

Método Endpoint Descrição
GET /health Health check
GET /swagger/* Documentação Swagger
POST /api/v1/auth/login Autenticação
POST /api/v1/companies Registro de empresa
GET /jobs Listar vagas (Busca, Filtros, Paginação)

🔍 Busca e Filtros (GET /jobs)

O endpoint /jobs suporta filtros avançados via query params:

  • q: Busca textual (Título, Descrição, Empresa)
  • location: Filtro por localização (Partial Match)
  • type: Tipo de contrato (full-time, part-time, etc.)
  • workMode: Modelo de trabalho (remote, hybrid, onsite)
  • page & limit: Paginação server-side

Protegidos (JWT Required)

Método Endpoint Roles Descrição
GET /api/v1/users superadmin, companyAdmin Listar usuários
POST /api/v1/users superadmin, companyAdmin Criar usuário
DELETE /api/v1/users/{id} superadmin Deletar usuário
POST /jobs companyAdmin, recruiter Criar vaga

Exemplo: atualizar candidatura para "Contratado"

Use este fluxo para marcar uma candidatura como aprovada (status hired).

  1. Endpoint: PUT /applications/{id}/status
    • Substitua {id} pelo identificador numérico da candidatura. Exemplo: /applications/1234/status.
  2. Payload (application/json):
{
  "status": "hired",
  "notes": "Candidato APROVADO após a entrevista final. Salário de R$ 5.500,00 acordado. Início em 01/02/2026."
}
  • O campo status é obrigatório e deve ser "hired" para confirmar a contratação.
  • O campo notes é opcional e pode registrar observações do recrutador.
  1. Próximo passo recomendado: Após o 200 OK, crie a conta de usuário interno do contratado com POST /api/v1/users.

🚀 Desenvolvimento

Executar

# Copie o .env
cp .env.example .env

# Execute
go run ./cmd/api

Testes

# Todos os testes
go test ./...

# Com verbose
go test -v ./internal/middleware/... ./internal/utils/...

Regenerar Swagger

swag init -g cmd/api/main.go --parseDependency --parseInternal

🐳 Docker

# Build
docker build -t gohorse-backend .

# Run
docker run -p 8080:8080 --env-file .env gohorse-backend

Imagem otimizada: ~73MB (Alpine + non-root user)


📁 Arquivos Importantes

Arquivo Descrição
cmd/api/main.go Entrypoint da aplicação
internal/router/router.go Configuração de todas as rotas
internal/database/database.go Conexão GORM com PostgreSQL
migrations/*.sql Migrations do banco de dados
docs/swagger.json Documentação OpenAPI gerada