Skip to content

Commit 7927c8c

Browse files
authored
Pedro/improments (#161)
## Resumo Este PR melhora a experiência de navegação e filtragem das vagas, tornando a página mais intuitiva, consistente e mais fácil de compartilhar. Também inclui ajustes para manter o estado da interface sincronizado com a URL e reforçar a cobertura de testes. ## O que foi alterado - Melhoria no componente de filtros das vagas para oferecer uma experiência de busca mais clara e amigável. - Ajuste na forma como termos de busca e filtros são aplicados, facilitando a combinação de critérios e a refinagem dos resultados. - Sincronização do estado de filtros, arquivo selecionado e paginação com os parâmetros da URL, permitindo compartilhar e restaurar a visualização mais facilmente. - Refinamento da tabela de vagas para refletir melhor os filtros ativos, a página atual e o tamanho da paginação. - Atualização e expansão dos testes unitários relacionados a filtros, paginação e renderização da página de vagas. - Inclusão/atualização de documentação relevante para refletir as mudanças na experiência e no fluxo de uso da funcionalidade. ## Por que isso é importante Essas alterações tornam a busca por vagas mais previsível, mais fácil de usar e mais preparada para cenários com muitos resultados ou vários filtros aplicados ao mesmo tempo. ## Pontos para revisão - Comportamento entre o estado da interface e os parâmetros da URL. - Lógica de filtros ao combinar busca, palavras-chave e seleção de arquivo. - Comportamento de paginação e tamanho de página em diferentes cenários. ## Testes Foram atualizados os testes unitários da interface para cobrir os fluxos principais de filtragem, paginação e renderização da página. <img width="1753" height="960" alt="image" src="https://github.com/user-attachments/assets/cabeaa22-ffa9-4063-a251-95bedb178de1" />
2 parents 646b288 + 8bcd9eb commit 7927c8c

25 files changed

Lines changed: 1098 additions & 579 deletions

.env.example

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Runtime
2+
NODE_ENV=development
3+
PORT=3001
4+
5+
# Base URLs
6+
APP_URL=http://localhost:3001
7+
FRONTEND_URL=http://localhost:5173
8+
GO_SCRAPER_URL=http://localhost:8081
9+
10+
# Session
11+
# Use uma string longa e secreta em ambientes reais.
12+
SESSION_SECRET=change-me-with-a-long-random-secret
13+
14+
# CORS / frontend access
15+
CORS_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:5174
16+
17+
# Search filters
18+
SEARCH_LOCATION=Brasil
19+
SEARCH_GEO_ID=106057199
20+
SEARCH_LANGUAGE=pt
21+
REMOTE_ONLY=true
22+
JOB_TYPES=C,F
23+
TIME_FILTER=r604800
24+
SEARCH_KEYWORDS=UX Designer,UI Designer,Product Manager,Product Owner
25+
26+
# Scraping behavior
27+
WAIT_BETWEEN_SEARCHES_MS=5000
28+
PAGE_TIMEOUT_MS=10000
29+
MAX_PAGES_PER_KEYWORD=5
30+
31+
# Database / cache
32+
POSTGRES_USER=vagas
33+
POSTGRES_PASSWORD=vagas
34+
POSTGRES_DB=vagas
35+
36+
# Use esta URL quando backend/scraper estiverem rodando fora do Docker e o banco estiver exposto no host.
37+
DATABASE_URL=postgresql://vagas:vagas@localhost:5432/vagas
38+
VALKEY_URL=redis://localhost:6379/0
39+
40+
# Use estas URLs dentro de containers Docker Compose.
41+
# DATABASE_URL=postgresql://vagas:vagas@postgres:5432/vagas
42+
# VALKEY_URL=redis://valkey:6379/0
43+
44+
CACHE_TTL_MS=600000
45+
REDIS_KEY_PREFIX=vagas-full
46+
KEYWORDS_REDIS_KEY=vagas-full:keywords
47+
KEYWORDS_STORAGE_MODE=env
48+
49+
# Legacy flags kept for compatibility
50+
HEADLESS=false
51+
VIEWPORT_WIDTH=1280
52+
VIEWPORT_HEIGHT=800
53+
54+
# Third-party API credentials
55+
ADZUNA_APP_ID=
56+
ADZUNA_APP_KEY=
57+
JOOBLE_API_KEY=
58+
59+
# OAuth credentials
60+
GOOGLE_CLIENT_ID=
61+
GOOGLE_CLIENT_SECRET=
62+
LINKEDIN_CLIENT_ID=
63+
LINKEDIN_CLIENT_SECRET=
64+
GITHUB_CLIENT_ID=
65+
GITHUB_CLIENT_SECRET=

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ node_modules/
44
.env.*
55
!.env.example
66
.vscode/
7+
.docker-local/
78
dist/
89
build/
910
output/

README.md

Lines changed: 120 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,88 @@ Objetivo de produto: fornecer uma base robusta para busca, filtragem e gestão d
7474

7575
- Node.js >= 22
7676
- npm
77-
- Docker e Docker Compose (opcional, recomendado para ambiente completo)
77+
- Docker Desktop com Docker Compose
7878

79-
### Instalação
79+
### Caminho recomendado: stack completa com Docker
80+
81+
Use este fluxo para subir Postgres, Valkey, scraper Go, backend e frontend com a mesma rede Docker.
82+
83+
1. Instale as dependências locais:
84+
85+
```bash
86+
npm ci
87+
```
88+
89+
2. Crie o `.env` da raiz a partir do exemplo versionado:
90+
91+
```bash
92+
cp .env.example .env
93+
```
94+
95+
No Windows PowerShell:
96+
97+
```powershell
98+
Copy-Item .env.example .env
99+
```
100+
101+
3. Crie a rede Docker compartilhada, se ela ainda não existir:
102+
103+
```bash
104+
docker network create vagas-net
105+
```
106+
107+
Se a rede já existir, o Docker vai avisar e você pode seguir para o próximo passo.
108+
109+
4. Suba Postgres e Valkey:
110+
111+
```bash
112+
docker compose -f docker-compose.infra.yml up -d
113+
```
114+
115+
5. Suba scraper, backend e frontend:
116+
117+
```bash
118+
docker compose up --build -d
119+
```
120+
121+
6. Aplique as migrations do backend:
80122

81123
```bash
82-
npm install
124+
docker compose exec backend npm run db:migrate
83125
```
84126

85-
### Execução web (frontend + backend)
127+
7. Acesse os serviços:
128+
129+
- Frontend: http://localhost:5173
130+
- Backend health: http://localhost:3001/health
131+
- Scraper health: http://localhost:8081/health
132+
- Vagas salvas no scraper: http://localhost:8081/admin/jobs/count
133+
134+
### Desenvolvimento com Node local
135+
136+
Use este fluxo quando quiser rodar frontend/backend fora do Docker. Mantenha Postgres e Valkey ativos no Docker e configure URLs locais nos arquivos `.env`.
137+
138+
Arquivos esperados:
139+
140+
- `.env`: usado pela infra/scraper e por comandos auxiliares.
141+
- `backend/.env`: usado pelo backend local.
142+
- `frontend/.env`: usado pelo Vite local.
143+
144+
Criação dos arquivos locais:
145+
146+
```bash
147+
cp backend/.env.example backend/.env
148+
cp frontend/.env.example frontend/.env
149+
```
150+
151+
No Windows PowerShell:
152+
153+
```powershell
154+
Copy-Item backend/.env.example backend/.env
155+
Copy-Item frontend/.env.example frontend/.env
156+
```
157+
158+
Comandos:
86159

87160
```bash
88161
npm run dev
@@ -174,6 +247,8 @@ Usuários:
174247

175248
Jobs:
176249

250+
- GET /jobs
251+
- GET /jobs/files
177252
- GET /jobs/search
178253

179254
Keywords:
@@ -195,47 +270,67 @@ Swagger:
195270

196271
## Docker (infra + aplicação)
197272

198-
Este projeto separa infraestrutura de aplicação em dois arquivos compose.
273+
Este projeto separa infraestrutura e aplicação em dois arquivos Compose:
199274

200-
1. Criar rede compartilhada (necessário uma vez):
275+
- `docker-compose.infra.yml`: Postgres + Valkey.
276+
- `docker-compose.yml`: scraper Go + backend + frontend.
277+
278+
Subir infraestrutura:
201279

202280
```bash
203-
docker network create vagas-net
281+
docker compose -f docker-compose.infra.yml up -d
204282
```
205283

206-
2. Subir infra (Postgres + Valkey):
284+
Subir aplicação:
207285

208286
```bash
209-
docker compose -f docker-compose.infra.yml up -d
287+
docker compose up --build -d
210288
```
211289

212-
3. Subir aplicação (scraper-go + backend + frontend):
290+
Aplicar migrations:
213291

214292
```bash
215-
docker compose up --build -d
293+
docker compose exec backend npm run db:migrate
216294
```
217295

218-
4. Logs:
296+
Ver logs:
219297

220298
```bash
221299
docker compose logs -f backend
222300
docker compose logs -f frontend
223301
docker compose logs -f scraper-go
224302
```
225303

226-
5. Encerrar:
304+
Encerrar:
227305

228306
```bash
229307
docker compose down
230308
docker compose -f docker-compose.infra.yml down
231309
```
232310

311+
Observação: os volumes Docker preservam os dados do Postgres e do Valkey entre execuções. Se você alterar `POSTGRES_USER`, `POSTGRES_PASSWORD` ou `POSTGRES_DB` depois da primeira inicialização, será necessário recriar o volume do Postgres ou manter os valores antigos.
312+
313+
Dentro dos containers, serviços devem usar os nomes da rede Docker:
314+
315+
- Postgres: `postgres:5432`
316+
- Valkey: `valkey:6379`
317+
- Scraper: `scraper-go:8081`
318+
319+
Por isso o `docker-compose.yml` sobrescreve `DATABASE_URL`, `VALKEY_URL`, `GO_SCRAPER_URL` e `SCRAPER_URL` para os valores internos corretos.
320+
233321
Serviços padrão:
234322

235323
- Frontend: http://localhost:5173
236324
- Backend: http://localhost:3001
237325
- Scraper Go: http://localhost:8081
238326

327+
Endpoints úteis do scraper:
328+
329+
- Health: http://localhost:8081/health
330+
- Status da execução: http://localhost:8081/admin/scrape/status
331+
- Contagem de vagas salvas: http://localhost:8081/admin/jobs/count
332+
- Lista de vagas salvas: http://localhost:8081/admin/jobs
333+
239334
## Desktop com Electron
240335

241336
O app desktop empacota frontend + backend e inicia a aplicação com Electron.
@@ -259,13 +354,23 @@ Saída esperada do instalador:
259354

260355
## Variáveis de ambiente
261356

262-
Arquivo base:
357+
Arquivos de exemplo:
263358

359+
- .env.example
264360
- backend/.env.example
361+
- frontend/.env.example
265362

266-
Arquivo local:
363+
Arquivos locais ignorados pelo Git:
267364

365+
- .env
268366
- backend/.env
367+
- frontend/.env
368+
369+
Uso recomendado:
370+
371+
- Docker Compose: copie `.env.example` para `.env`. O Compose usa esse arquivo para infra, scraper, backend e build do frontend.
372+
- Backend local via Node: use `backend/.env`.
373+
- Frontend local via Vite: use `frontend/.env`.
269374

270375
Variáveis centrais de operação:
271376

SCRAPER.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,19 @@ cd scraper-go
122122
go run ./cmd/server
123123
```
124124

125-
Docker: há um `Dockerfile` em `scraper-go/`.
125+
Docker: há um `Dockerfile` em `scraper-go/`. No Docker Compose, configure `VALKEY_URL=redis://valkey:6379/0` no `.env` da raiz para que o scraper acesse o Valkey pelo nome do serviço na rede Docker.
126126

127127
## Endpoints HTTP
128128

129129
O serviço expõe endpoints HTTP (implementação em `cmd/server` e arquivos associados). Principais rotas:
130130

131131
- POST `/scrape` — body JSON com `ScrapeRequest` para disparar uma busca em todas as fontes configuradas. Retorna `ScrapeResponse` com `jobs`, `total`, `cachedAt` e `fromCache`.
132+
- GET `/health` — verifica se o scraper está online e qual cache está em uso.
132133
- GET `/api/keywords` — retorna as keywords atualmente carregadas.
133134
- POST `/api/keywords` — atualiza/persiste as keywords (aceita `keywords: string[]`).
135+
- GET `/admin/scrape/status` — informa se existe uma execução em andamento.
136+
- GET `/admin/jobs/count` — retorna a quantidade de vagas persistidas no Valkey.
137+
- GET `/admin/jobs` — lista as vagas persistidas no Valkey.
134138

135139
Exemplo de `ScrapeRequest` (JSON):
136140

@@ -230,7 +234,7 @@ Boas práticas nos adaptadores:
230234

231235
## Variáveis de ambiente importantes
232236

233-
- `REDIS_URL` / `VALKEY_URL` — conexão Redis/Valkey.
237+
- `VALKEY_URL` — conexão Redis/Valkey. Em Docker Compose, use `redis://valkey:6379/0`; em execução local fora do Docker, use uma URL acessível pelo host, por exemplo `redis://localhost:6379/0`.
234238
- `JOOBLE_API_KEY` — Jooble integration.
235239
- `ADZUNA_APP_ID` / `ADZUNA_APP_KEY` — Adzuna API.
236240
- Configurações de logging e quota podem ser definidas via `.env`.

backend/.env.example

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,30 @@
11
# Runtime
2-
# Runtime
3-
NODE_ENV=production
2+
NODE_ENV=development
43
PORT=3001
54

6-
# Base URL da aplicação
7-
# Ex: APP_URL=http://localhost:3001/api
8-
APP_URL=
9-
10-
# Sessão
11-
# Use uma string longa e secreta em produção
12-
SESSION_SECRET=
5+
# Base URLs
6+
APP_URL=http://localhost:3001
7+
FRONTEND_URL=http://localhost:5173
138

14-
# CORS / frontend access (separar por vírgula)
15-
CORS_ALLOWED_ORIGINS=
9+
# Session
10+
# Use uma string longa e secreta em ambientes reais.
11+
SESSION_SECRET=change-me-with-a-long-random-secret
1612

17-
# URL do frontend (usada para redirect pos-OAuth)
18-
FRONTEND_URL=http://localhost:5173
13+
# CORS / frontend access
14+
CORS_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:5174
1915

20-
# LinkedIn search filters (defaults)
16+
# Search filters
2117
SEARCH_LOCATION=Brasil
2218
SEARCH_GEO_ID=106057199
2319
SEARCH_LANGUAGE=pt
2420
REMOTE_ONLY=true
2521
JOB_TYPES=C,F
2622
TIME_FILTER=r604800
23+
SEARCH_KEYWORDS=UX Designer,UI Designer,Product Manager,Product Owner
2724

28-
# Keywords (opcional: fallback inicial)
29-
# SEARCH_KEYWORDS=UX Designer,UI Designer,Product Manager,Product Owner
30-
SEARCH_KEYWORDS=
31-
32-
# Storage / Cache
33-
# DATABASE_URL template (substitua USER/PASS/HOST/PORT/DB)
34-
# DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@host:5432/${POSTGRES_DB}
35-
DATABASE_URL=
36-
37-
# VALKEY/Redis URL
38-
VALKEY_URL=
39-
# Exemplo: redis://:password@localhost:6379/0
40-
41-
# Cache TTL (ms)
25+
# Database / cache for backend running locally outside Docker
26+
DATABASE_URL=postgresql://vagas:vagas@localhost:5432/vagas
27+
VALKEY_URL=redis://localhost:6379/0
4228
CACHE_TTL_MS=600000
4329

4430
# Scraping behavior
@@ -51,22 +37,20 @@ HEADLESS=false
5137
VIEWPORT_WIDTH=1280
5238
VIEWPORT_HEIGHT=800
5339

54-
# Third-party API credentials (NUNCA commit valores reais)
40+
# Third-party API credentials
5541
ADZUNA_APP_ID=
5642
ADZUNA_APP_KEY=
43+
JOOBLE_API_KEY=
5744

45+
# OAuth credentials
5846
GOOGLE_CLIENT_ID=
5947
GOOGLE_CLIENT_SECRET=
60-
6148
LINKEDIN_CLIENT_ID=
6249
LINKEDIN_CLIENT_SECRET=
63-
6450
GITHUB_CLIENT_ID=
6551
GITHUB_CLIENT_SECRET=
6652

67-
# Scraper Go service URL
53+
# Local scraper services
6854
GO_SCRAPER_URL=http://localhost:8081
69-
70-
71-
SCRAPER_URL=http://scraper-go:8081
72-
PROMETHEUS_URL=http://prometheus:9090
55+
SCRAPER_URL=http://localhost:8081
56+
PROMETHEUS_URL=http://localhost:9090

0 commit comments

Comments
 (0)