Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
05536c0
refactor(PAV-181): reorganiza arquitetura modular do frontend
hltav Nov 1, 2026
1c486a2
refactor(PAV-181): reorganiza modulo de ajuda do frontend
hltav Nov 1, 2026
2c1a0d0
refactor(PAV-181): modulariza componentes de mentoria
hltav Nov 1, 2026
c49ef41
refactor(PAV-181): modulariza componentes da home
hltav Nov 1, 2026
0aeb909
refactor(PAV-181): modulariza hook e infraestrutura de perfil
hltav Nov 1, 2026
217019b
refactor(PAV-181): modulariza componentes de perfil
hltav Nov 1, 2026
71dc259
refactor(PAV-181): modulariza hook e infraestrutura de vagas
hltav Nov 1, 2026
404c60d
refactor(PAV-181): modulariza componentes do catalogo de vagas
hltav Nov 1, 2026
039ebd5
refactor(PAV-181): modulariza componentes de candidaturas
hltav Nov 1, 2026
b1705e4
refactor(PAV-181): modulariza modal de detalhes de vagas
hltav Nov 1, 2026
64abafd
refactor(PAV-181): modulariza componentes do dashboard
hltav Nov 1, 2026
add245a
refactor(PAV-181): reorganiza tema helpers e contratos
hltav Nov 2, 2026
53dcb54
refactor(PAV-181): remove compatibilidade legada do dashboard
hltav Nov 2, 2026
16d04f6
refactor(PAV-181): consolida domains na arquitetura features
hltav Nov 2, 2026
ada3a94
refactor(PAV-181): padroniza estrutura de app features e shared
hltav Nov 2, 2026
91c911c
refactor(PAV-181): reestrutura arquitetura modular do frontend Candid…
hltav Nov 2, 2026
a17e658
feat(frontend): atualiza paletas de cores e destaques visuais
hltav Nov 2, 2026
8e33251
feat(frontend): moderniza busca, filtros e apresentação das vagas
hltav Nov 3, 2026
0da45b6
fix(frontend): corrige consistência da compatibilidade nas vagas
hltav Nov 3, 2026
965248b
PAV-182: [Frontend] Revisar busca de vagas, filtros e integração com …
hltav Nov 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions frontend/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
# Arquitetura do Frontend

O frontend é organizado por domínios de negócio, não por tipos técnicos de arquivo.
O frontend usa Feature-Based Architecture. Cada funcionalidade mantém seus componentes, contratos e integrações; camadas internas existem somente quando necessárias.

## Camadas
## Organização

- `src/app`: composição da aplicação, providers, rotas e páginas de nível global.
- `src/domains/<domain>/domain`: tipos de negócio e regras puras, sem React ou HTTP.
- `src/domains/<domain>/application`: hooks React e casos de uso que orquestram regras de domínio.
- `src/domains/<domain>/infrastructure`: gateways de API e código específico de transporte.
- `src/domains/<domain>/presentation`: páginas e componentes pertencentes ao domínio.
- `src/shared`: primitivas de UI, assets, hooks e utilitários técnicos reutilizáveis.
- `src/app/routes`: definição das rotas e página de rota não encontrada.
- `src/app/providers`: composição dos providers globais.
- `src/app/layouts`: layout autenticado e seus componentes de navegação.
- `src/app/dashboard`: composição, navegação, providers e tema do painel atual.
- `src/features`: applications, auth, dashboard, help, home, jobs, marketing, mentoring, notifications e profile.
- `src/shared/api`: cliente HTTP compartilhado e tratamento de erros de API.
- `src/shared/utils`, `hooks`, `ui`, `assets` e `feedback`: utilitários, hooks, componentes, recursos e contexto de feedback reutilizáveis.
- `src/styles`: estilos globais.

> Exceção: o domínio `new_dashboard` ainda não segue integralmente essas 4 camadas. Hoje ele usa uma organização própria (`components/`, `context/`, `hooks/`, `infrastructure/`, `types/`, `utils/`, `layout.tsx`, `page.tsx`), sem pastas `domain/`, `application/` ou `presentation/` separadas. `auth`, `jobs` e `marketing` seguem o padrão de 4 camadas descrito acima.
## Convenções das funcionalidades

## Domínios
- `api/`: integrações HTTP; clientes e contratos existentes são preservados.
- `hooks/`: hooks de carregamento, persistência e estado.
- `components/` e `pages/`: componentes e páginas específicos da funcionalidade.
- `domain/` e `types/`: regras puras, schemas e contratos, quando necessários.
- `application/`: contextos e providers com responsabilidade de aplicação; não são hooks.
- Arquivos pequenos de contratos, eventos ou dados podem permanecer na raiz da funcionalidade. Não criar diretórios vazios.

- `auth`: estado de sessão, acesso à API de credenciais/OAuth e telas de login, registro e callback.
- `jobs`: entidades de vagas, filtros, deduplicação, paginação, acesso à API de vagas/scraper e UI de vagas.
- `marketing`: seções da landing page pública.
- `new_dashboard`: nova estrutura de painel do frontend. Contribuidores que procuram a experiência atual de dashboard devem começar por aqui.
O catálogo anterior mantém seu contrato em `features/jobs/types/job.types.ts`, distinto do contrato do painel em `features/jobs/domain/job.ts`. O contexto e os dados demonstrativos legados permanecem em `features/jobs/legacy`. Candidaturas, notas e Kanban pertencem a `features/applications`.

## Política de imports
## Imports

O código deve importar a partir de `@/app`, `@/domains` ou `@/shared`. Pastas técnicas antigas como `src/components`, `src/pages`, `src/hooks`, `src/services`, `src/context`, `src/lib` e `src/types` foram removidas para manter uma estrutura única orientada por domínio.
Preferir imports canônicos com `@/app`, `@/features` e `@/shared`. Preservar imports relativos locais quando claros. Código específico permanece na funcionalidade; somente recursos reutilizáveis pertencem a shared. Evitar dependências circulares. Rotas, exports, providers, APIs e modelos distintos são preservados pela organização.
10 changes: 5 additions & 5 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ Variáveis usadas:

## Organização

O frontend segue uma estrutura orientada por domínio:
O frontend segue uma arquitetura Feature-Based, com domínio separado quando necessário:

- `src/app`: composição da aplicação, providers, rotas e layouts autenticados.
- `src/domains/auth`: login, registro, callback OAuth e estado de sessão.
- `src/domains/jobs`: busca, filtros, paginação e interface de vagas.
- `src/domains/marketing`: landing page pública.
- `src/domains/new_dashboard`: nova estrutura de painel do frontend. É aqui que contribuidores devem procurar a experiência nova de dashboard, com abas de home, vagas, mentoring, perfil e ajuda.
- `src/features/auth`: login, registro, callback OAuth e estado de sessão.
- `src/features/jobs`: busca, filtros, paginação e interface de vagas, preservando os contratos distintos dos catálogos.
- `src/features/marketing`: landing page pública.
- `src/app/dashboard`: composição, providers, tema e navegação do painel. As funcionalidades de home, vagas, candidaturas, mentoria, perfil, ajuda e notificações estão em `src/features/`.
- `src/shared`: componentes de UI, assets, hooks e utilitários reutilizáveis.

Veja também [ARCHITECTURE.md](ARCHITECTURE.md).
Expand Down
73 changes: 73 additions & 0 deletions frontend/docs/PAV-182-match-vagas-salvas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# PAV-182 — Viabilidade de recuperar Match das vagas salvas

## Resultado da auditoria

O contrato atual não permite recuperar uma vaga específica do catálogo por
identificador estável. O enriquecimento das vagas salvas não foi implementado.
O Kanban mantém `Não calculado` quando a API não fornece compatibilidade.

## Endpoint e perfil

- O frontend usa `searchDashboardJobs`, em
`src/features/jobs/api/dashboardJobsApi.ts`, para consultar `GET /jobs/search`.
- O endpoint também está disponível sob `/api/v1/jobs/search` conforme a montagem
das rotas em `backend/src/app.ts`.
- O cliente utiliza cookies da sessão (`withCredentials`). O controller envia
`req.session.userId` para `SearchJobsService`, que carrega o perfil atual por
`JobProfileMatchService` e utiliza o cálculo existente de compatibilidade.
- A busca devolve `matchScore`, `matchSource` e `matchedTechnologies` quando
disponíveis. Ausência de score não equivale a um percentual calculado de zero.

## Contrato de consulta

O parser `backend/src/modules/jobs/parsers/jobSearchQuery.parser.ts` aceita:

- `keywords`, `family`, `familyMode`, `technology`, `company`;
- `model`/`type`, `level`, `seniority`, `contract`/`contractType`/`jobTypes`;
- `location`, `continent`, `country`, `state`, `city`;
- `matchSort`/`sort` e paginação `page`, `limit`.

Não há filtro de ID original, ID externo, URL, `jobLink` ou lote de IDs/URLs.
Enviar esses parâmetros não cria uma consulta por identidade: o parser não os
inclui nos filtros. As rotas públicas de catálogo são `/jobs/search` e
`/jobs/filters/options`; não existe rota de detalhe ou lookup do catálogo.
O limite de resultados por página é 100, definido em `backend/src/lib/pagination.ts`.

## Identificadores e correspondência

- A vaga salva possui um UUID de `saved_jobs`, diferente do ID do catálogo.
- Ela preserva `jobLink`, título, empresa, localização, fonte e uma keyword,
mas não uma associação ao ID original do catálogo nem os dados de Match.
- O frontend gera um ID de apresentação `recommended:<link>:<índice>` para a
busca. Esse valor não é um identificador de catálogo aceito pelo endpoint.
- Quando há URL original válida, `jobLink` permite comparar exatamente com
`url` de um resultado recebido. Isso não oferece um mecanismo para localizar
esse resultado sem percorrer a busca, nem garante unicidade no catálogo.
- Se a URL original estiver ausente, o frontend gera um link `canddate.local`
com dados textuais e índice da página; esse fallback não identifica uma vaga
original de forma estável.
- Título igual, empresa parcial ou primeiro resultado textual não comprovam
identidade. Providers diferentes e vagas homônimas não podem ser associados
automaticamente. A busca por empresa usa substring; keywords usam índices
de busca, sem contrato de correspondência exata por URL.

## Decisão de implementação e performance

Nenhuma nova requisição foi adicionada. Não há busca por card, varredura do
catálogo, paginação ilimitada ou cache novo de pontuações. A página atual de
resultados não foi utilizada como mecanismo de recuperação das vagas salvas:
ela não garante disponibilidade após recarregar e pode excluir essas vagas
pelos filtros ativos.

## Dependência para uma solução definitiva

É necessário um contrato autenticado de consulta em lote por identidade estável,
ou enriquecimento de `/saved-jobs` no servidor com associação ao catálogo.
Esse contrato deve resolver correspondências ausentes ou ambíguas explicitamente,
reutilizar o mesmo serviço de Match e o perfil atual, preservar zero real e
retornar score ausente quando não houver cálculo. Deve também definir expiração
e invalidação por mudanças de perfil/catálogo. Não basta persistir um percentual
fixo nem reaproveitar pontuações antigas pelo título.

Essa alteração depende de backend e ficou fora desta etapa. Não há contrato
novo, endpoint proposto implementado ou alteração do cálculo de compatibilidade.
2 changes: 1 addition & 1 deletion frontend/src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState, useEffect } from "react";
import { AppRoutes } from "@/app/AppRoutes";
import { AppRoutes } from "@/app/routes/AppRoutes";
import Loading from "@/shared/ui/Loading";

function App() {
Expand Down
Loading
Loading