# Banco de Talentos — Plano de Implementação

## Visão geral
Sistema completo de vagas de emprego integrado à plataforma multi-tenant:
- **Landing page pública** — vitrine de vagas por empresa com data e contagem de candidatos
- **Área do candidato** — cadastro de currículo e candidatura a vagas
- **Painel admin** — gestão completa de vagas, candidatos e currículos

---

## 1. Banco de Dados — sistema-nuvem

### 1.1 Tabela `jobs` (vagas)
```sql
CREATE TABLE IF NOT EXISTS jobs (
  id             SERIAL PRIMARY KEY,
  tenant_id      INT          NOT NULL,
  title          TEXT         NOT NULL,
  description    TEXT         NOT NULL,
  requirements   TEXT,
  benefits       TEXT,
  location       TEXT,
  work_mode      TEXT         NOT NULL DEFAULT 'presencial',  -- presencial | híbrido | remoto
  job_type       TEXT         NOT NULL DEFAULT 'clt',        -- clt | pj | freelance | estagio | temporario
  category       TEXT,
  salary_min     NUMERIC(10,2),
  salary_max     NUMERIC(10,2),
  salary_hide    BOOLEAN      NOT NULL DEFAULT false,
  slots          INT          NOT NULL DEFAULT 1,
  active         BOOLEAN      NOT NULL DEFAULT true,
  published_at   TIMESTAMPTZ  DEFAULT NOW(),
  expires_at     TIMESTAMPTZ,
  created_at     TIMESTAMPTZ  DEFAULT NOW(),
  updated_at     TIMESTAMPTZ  DEFAULT NOW()
);
```

### 1.2 Tabela `resumes` (currículos)
```sql
CREATE TABLE IF NOT EXISTS resumes (
  id            SERIAL PRIMARY KEY,
  tenant_id     INT    NOT NULL,
  user_cpf      TEXT   NOT NULL,
  user_nome     TEXT   NOT NULL,
  email         TEXT,
  phone         TEXT,
  linkedin      TEXT,
  portfolio     TEXT,
  about         TEXT,
  experience    JSONB  NOT NULL DEFAULT '[]',
  -- [{ company, role, start, end, current, description }]
  education     JSONB  NOT NULL DEFAULT '[]',
  -- [{ institution, degree, course, start, end, current }]
  skills        JSONB  NOT NULL DEFAULT '[]',
  -- [{ name, level }]  level: basico | intermediario | avancado
  file_url      TEXT,           -- PDF anexado pelo candidato
  updated_at    TIMESTAMPTZ DEFAULT NOW(),
  created_at    TIMESTAMPTZ DEFAULT NOW(),
  UNIQUE (tenant_id, user_cpf)
);
```

### 1.3 Tabela `job_applications` (candidaturas)
```sql
CREATE TABLE IF NOT EXISTS job_applications (
  id              SERIAL PRIMARY KEY,
  tenant_id       INT    NOT NULL,
  job_id          INT    NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
  resume_id       INT    REFERENCES resumes(id),
  applicant_nome  TEXT   NOT NULL,
  applicant_email TEXT,
  applicant_phone TEXT,
  applicant_cpf   TEXT   NOT NULL,
  cover_letter    TEXT,
  status          TEXT   NOT NULL DEFAULT 'novo',
  -- novo | em_analise | aprovado | reprovado | contratado
  admin_notes     TEXT,
  applied_at      TIMESTAMPTZ DEFAULT NOW(),
  updated_at      TIMESTAMPTZ DEFAULT NOW(),
  UNIQUE (job_id, applicant_cpf)
);
```

### 1.4 Índices
```sql
CREATE INDEX IF NOT EXISTS idx_jobs_tenant      ON jobs(tenant_id, active);
CREATE INDEX IF NOT EXISTS idx_jobs_published   ON jobs(published_at DESC);
CREATE INDEX IF NOT EXISTS idx_applications_job ON job_applications(job_id);
CREATE INDEX IF NOT EXISTS idx_resumes_cpf      ON resumes(tenant_id, user_cpf);
```

---

## 2. Backend — sistema-nuvem/controllers + routes

### 2.1 Endpoints públicos (customer-app)
- [x] `GET  /api/jobs` — listar vagas ativas com contagem de candidatos
  - Query params: `category`, `work_mode`, `job_type`, `limit`, `offset`
  - Retorna: `{ jobs, total }` — cada vaga inclui `applicants_count`
- [x] `GET  /api/jobs/:id` — detalhe da vaga (sem candidatos)
- [x] `POST /api/jobs/:id/apply` — candidatar-se a uma vaga
  - Body: `{ applicant_cpf, applicant_nome, applicant_phone, applicant_email, cover_letter, resume_id? }`
  - Impede candidatura duplicada (mesmo CPF + vaga)

### 2.2 Endpoints do candidato (autenticado — `verifyUserToken`)
- [x] `GET  /api/user/resume` — buscar currículo do usuário logado
- [x] `POST /api/user/resume` — criar currículo
- [x] `PUT  /api/user/resume` — atualizar currículo completo
- [ ] `POST /api/user/resume/upload` — upload de PDF (multer → `/public/resumes/`)
- [x] `GET  /api/user/applications` — listar candidaturas do usuário
- [x] `DELETE /api/user/applications/:id` — cancelar candidatura (se ainda `novo`)

### 2.3 Endpoints admin (autenticado — `verifyToken`)
- [x] `GET    /api/admin/jobs` — listar todas as vagas com `applicants_count`
  - Query: `active`, `category`, `work_mode`, `search`, `limit`, `offset`
- [x] `POST   /api/admin/jobs` — criar vaga
- [x] `PUT    /api/admin/jobs/:id` — editar vaga
- [x] `PATCH  /api/admin/jobs/:id/toggle` — ativar / desativar vaga
- [x] `DELETE /api/admin/jobs/:id` — remover vaga (apenas sem candidatos, senão desativar)
- [x] `GET    /api/admin/jobs/:id/applications` — candidatos de uma vaga
  - Query: `status`, `limit`, `offset`
  - Retorna dados + currículo vinculado
- [x] `GET    /api/admin/applications/:id` — detalhe de candidatura com currículo completo
- [x] `PATCH  /api/admin/applications/:id` — atualizar status + notas admin
- [x] `GET    /api/admin/resumes` — buscar currículos por CPF / nome
- [x] `GET    /api/admin/resumes/:cpf` — currículo completo de um candidato

---

## 3. Admin App — admin-app/src

### 3.1 Sidebar + Rota
- [x] Adicionar item **Vagas** no sidebar de `App.tsx` (ícone: `Briefcase`)
- [x] Nova rota `/jobs` → `<JobsPage />`

### 3.2 JobsService — services/api.ts
- [x] `list(params)`, `create(data)`, `update(id, data)`, `toggle(id)`, `remove(id)`
- [x] `getApplications(jobId, params)`, `getApplication(id)`, `updateApplication(id, data)`
- [x] `searchResumes(params)`, `getResume(cpf)`, `kpi()`

### 3.3 JobsPage.tsx — visão geral
- [x] **Header** com: total de vagas ativas, total de candidaturas, botão "Nova Vaga"
- [x] **KPI cards**: Vagas ativas · Vagas encerradas · Total candidatos · Contratações
- [x] **Tabela/lista de vagas** com colunas:
  - Título · Categoria · Modo · Tipo · Publicado em · Expira em · Candidatos · Status · Ações
- [x] Filtros: busca por título, categoria, modo de trabalho, status (ativo/inativo)
- [x] Paginação
- [x] Botão **Ver candidatos** por vaga (abre drawer lateral)
- [x] Botões **Editar** / **Ativar-Desativar** / **Excluir** por linha

### 3.4 JobModal — criar / editar vaga
- [x] Título, Descrição, Requisitos, Benefícios, Localização
- [x] Modo de trabalho (select: Presencial / Híbrido / Remoto)
- [x] Tipo de contrato (select: CLT / PJ / Freelance / Estágio / Temporário)
- [x] Categoria, Número de vagas, Salário (min · max · checkbox "A combinar")
- [x] Data de expiração (opcional), Ativa (toggle)

### 3.5 ApplicationsDrawer — candidatos de uma vaga
- [x] Lista de candidatos com: nome, CPF, telefone, data de candidatura, status
- [x] Filtro por status
- [x] Clicar em candidato → abre `CandidateDetailModal`

### 3.6 CandidateDetailModal — perfil completo do candidato
- [x] Dados pessoais do candidato
- [x] Carta de apresentação (se enviou)
- [x] Currículo completo inline: Sobre · Experiências · Formação · Habilidades
- [x] Selector de status com cores: Novo · Em Análise · Aprovado · Reprovado · Contratado
- [x] Campo de notas internas do admin
- [x] Botão **Salvar status + notas**
- [x] Botão **Baixar currículo PDF** (se disponível)

### 3.7 ResumesView — banco de currículos
- [x] Busca por nome ou CPF
- [x] Tabela: nome, CPF, e-mail, telefone, última atualização, vagas candidatadas
- [x] Clicar → abre currículo completo

---

## 4. Customer App — customer-app/src

### 4.1 Landing page — seção Vagas
- [x] Nova seção `VagasSection` em `LandingPage.tsx`
- [x] Grid de cards de vagas (máx. 6 na landing, link "Ver todas")
- [x] Card de vaga inclui título, modo, tipo, localização, salário, data, candidatos
- [x] Link "Ver todas as vagas" → `/vagas`
- [x] Seção só aparece se houver vagas ativas

### 4.2 JobsAPI — api.ts
- [x] `list(params)`, `get(id)`, `apply(id, data)`
- [x] `myResume()`, `saveResume(data)`, `myApplications()`, `cancelApplication(id)`

### 4.3 Nova página — VagasListPage `/vagas`
- [x] Listagem completa de vagas com filtros por palavra-chave, modo e tipo
- [x] Cards modernos com todas as informações
- [x] Paginação (12 por página)

### 4.4 Nova página — VagaDetailPage `/vagas/:id`
- [x] Descrição completa + requisitos + benefícios
- [x] Info: localização, modo, tipo, salário, data, candidatos
- [x] Formulário de candidatura com auto-preenchimento se logado
- [x] Badge "Você já se candidatou" + status da candidatura se já aplicou

### 4.5 Área do Membro — DashboardPage
- [x] Nova aba **"Vagas"** no dashboard
- [x] Sub-aba **"Minhas Candidaturas"**: lista com vaga, data, status (badge colorido)
- [x] Sub-aba **"Meu Currículo"**: ResumeBuilder completo

### 4.6 Construtor de Currículo — ResumeBuilder
- [x] Seção **Dados Pessoais**: nome, e-mail, telefone, LinkedIn, portfólio, sobre
- [x] Seção **Experiências** (lista dinâmica): empresa, cargo, início, fim, atual, descrição
- [x] Seção **Formação** (lista dinâmica): instituição, grau, curso, início, fim
- [x] Seção **Habilidades** (lista dinâmica): nome + nível
- [x] Botão **Salvar Currículo**

### 4.7 Navbar — novo link
- [x] Adicionar "Vagas" na Navbar com `to="/vagas"`

---

## 5. Rotas novas — server.js
- [x] Montar controller `jobController.js` com todos os endpoints
- [x] Registrar todas as rotas em `server.js`

---

## Ordem de implementação

1. [x] Banco: criar tabelas `jobs`, `resumes`, `job_applications` + índices
2. [x] Backend: controller + rotas públicas (listar vagas, candidatar)
3. [x] Backend: rotas do candidato (currículo, candidaturas)
4. [x] Backend: rotas admin (CRUD vagas, candidatos, currículos)
5. [x] Admin: JobsService + JobsPage + JobModal
6. [x] Admin: ApplicationsDrawer + CandidateDetailModal
7. [x] Admin: ResumesView (integrada na JobsPage)
8. [x] Customer: JobsAPI + seção Vagas na landing
9. [x] Customer: VagasListPage + VagaDetailPage
10. [x] Customer: ResumeBuilder no Dashboard
11. [x] Customer: aba Vagas/Candidaturas no Dashboard
12. [x] Navbar: link Vagas
13. [x] Build dos 3 apps (customer-app + admin-app) — zero erros TS
