Componentes Principais do Sistema
Visão Geral dos Componentes
O Acesso ao Emprego é construído com uma arquitetura monolítica modular em Django, com frontend React e processamento assíncrono via Celery.
Componentes Frontend
1. Aplicação React
Stack Tecnológico
- Framework: React 19 com TypeScript 5.7
- Build Tool: Vite
- UI Library: Material-UI v6
- State Management: Zustand
- API Client: Axios + React Query
- Roteamento: React Router DOM v6
- Validação: Schemas customizados com Zod
Estrutura de Componentes
// Estrutura principal de componentes
frontend/src/presentation/
├── components/
│ ├── common/ // Componentes reutilizáveis
│ │ ├── AlertComponent/
│ │ ├── ButtonComponent/
│ │ ├── DialogComponent/
│ │ ├── TableComponent/
│ │ └── MenuComponent/
│ ├── auth/ // Autenticação
│ │ └── PrivateRoute.tsx
│ └── layout/ // Layout da aplicação
│ ├── Header/
│ └── EditProfileModal/
├── pages/
│ ├── private/
│ │ ├── candidate/ // Páginas do candidato
│ │ ├── company/ // Páginas da empresa
│ │ └── publicAgency/ // Páginas do órgão público
│ └── error/ // Páginas de erro
└── layouts/ // Layouts por tipo de usuário
Componentes Principais
Componentes Comuns:
AlertComponent: Notificações e alertasTableComponent: Tabelas com paginação e filtrosRichTextEditor: Editor de texto rico para descriçõesSearchComponent: Busca com autocompleteFilterComponent: Filtros avançados para vagas
Componentes Especializados:
ImageCropper: Recorte de imagens de perfilJobCard: Card de exibição de vagasResumeBuilder: Construtor de currículoStageManager: Gerenciador de etapas do processo seletivo
2. Gerenciamento de Estado
Zustand Stores
// Estrutura das stores
store/
├── auth/authStore.ts // Autenticação e tokens
├── candidate/
│ ├── resumeStore.ts // Dados do currículo
│ └── filterStore.ts // Filtros de busca
├── company/
│ ├── resumeStore.ts // Perfil da empresa
│ └── templatesStore.ts // Templates de questões
├── modal/modalStore.ts // Controle de modais
└── user/userStore.ts // Dados do usuário
Componentes Backend
1. Django Apps
Accounts App
Gerenciamento de usuários e autenticação
# Models principais
class CustomUser(AbstractUser):
email = models.EmailField(unique=True)
cpf = models.CharField(max_length=11, unique=True)
is_candidate = models.BooleanField(default=False)
is_company = models.BooleanField(default=False)
is_government_agent = models.BooleanField(default=False)
profile_avatar = models.ImageField(upload_to='user/')
class CandidateUser(models.Model):
user = models.OneToOneField(CustomUser)
# Campos específicos do candidato
class CompanyUser(models.Model):
user = models.ForeignKey(CustomUser)
company = models.ForeignKey('companies.Company')
role = models.CharField(choices=COMPANY_ROLES)
Candidates App
Perfis e currículos dos candidatos
# Models principais
class Candidate(models.Model):
user = models.OneToOneField(CustomUser)
birth_date = models.DateField()
address = models.JSONField()
contact_email = models.EmailField()
class AcademicFormation(models.Model):
candidate = models.ForeignKey(Candidate)
institution = models.CharField(max_length=255)
course = models.CharField(max_length=255)
level = models.CharField(choices=FORMATION_LEVELS)
class ProfessionalExperience(models.Model):
candidate = models.ForeignKey(Candidate)
company_name = models.CharField(max_length=255)
position = models.CharField(max_length=255)
description = models.TextField()
class CandidateHardSkill(models.Model):
candidate = models.ForeignKey(Candidate)
skill = models.ForeignKey(HardSkill)
proficiency = models.IntegerField(choices=PROFICIENCY_LEVELS)
Companies App
Gestão de empresas parceiras
# Models principais
class Company(models.Model):
cnpj = models.CharField(max_length=14, unique=True)
name = models.CharField(max_length=255)
email = models.EmailField()
status = models.CharField(choices=COMPANY_STATUS)
created_by = models.ForeignKey(CustomUser)
approved_by = models.ForeignKey(CustomUser, null=True)
Job Vacancies App
Processos seletivos e candidaturas
# Models principais
class SelectiveProcess(models.Model):
company = models.ForeignKey(Company)
title = models.CharField(max_length=255)
description = models.TextField()
requirements = models.JSONField()
salary_range = DecimalRangeField()
status = models.CharField(choices=PROCESS_STATUS)
class Stage(models.Model):
selective_process = models.ForeignKey(SelectiveProcess)
name = models.CharField(max_length=255)
type = models.CharField(choices=STAGE_TYPES)
order = models.IntegerField()
class CandidateSubmission(models.Model):
candidate = models.ForeignKey(Candidate)
selective_process = models.ForeignKey(SelectiveProcess)
submitted_at = models.DateTimeField(auto_now_add=True)
status = models.CharField(choices=SUBMISSION_STATUS)
class CandidatesSelectiveProcessStage(models.Model):
candidate = models.ForeignKey(Candidate)
stage = models.ForeignKey(Stage)
status = models.CharField(choices=STAGE_STATUS)
score = models.DecimalField(null=True)
2. Sistema de Autenticação JWT
# Configuração JWT
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(hours=24),
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
'AUTH_HEADER_TYPES': ('Bearer',),
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
}
# Views de autenticação
class TokenPairView(TokenObtainPairView):
"""Endpoint para login e obtenção de tokens"""
serializer_class = TokenPairSerializer
class TokenRefreshView(TokenRefreshView):
"""Endpoint para renovação de token"""
pass
3. Sistema de Permissões
# Permissões customizadas
class IsOwnerPermission(BasePermission):
"""Verifica se o usuário é dono do recurso"""
class IsCandidatePermission(BasePermission):
"""Verifica se o usuário é candidato"""
class IsCompanyUserPermission(BasePermission):
"""Verifica se o usuário pertence a uma empresa"""
class IsGovernmentAgentPermission(BasePermission):
"""Verifica se o usuário é agente governamental"""
Componentes de Processamento
1. Fuzzy Logic Engine
Sistema de IA para matching inteligente entre candidatos e vagas
# fuzzy/pln_processing.py
class FuzzyMatchingEngine:
def __init__(self):
self.rules_count = 125 # 125 regras de inferência
self.similarity_threshold = 0.7
def calculate_match_score(self, candidate, job):
"""
Calcula score de compatibilidade usando:
- Similaridade de experiência profissional
- Alinhamento de formação acadêmica
- Correspondência de habilidades
"""
experience_score = self.analyze_experience(
candidate.experiences,
job.requirements
)
education_score = self.analyze_education(
candidate.formations,
job.education_requirements
)
skills_score = self.analyze_skills(
candidate.hard_skills,
job.required_skills
)
# Aplicação das regras fuzzy
fuzzy_score = self.apply_fuzzy_rules(
experience_score,
education_score,
skills_score
)
return fuzzy_score
2. Celery Tasks
# Tarefas assíncronas
@shared_task
def calculate_submission_rate(submission_id):
"""Calcula score de candidatura com IA"""
submission = CandidateSubmission.objects.get(id=submission_id)
# Processamento com fuzzy logic
score = FuzzyMatchingEngine().calculate_match_score(
submission.candidate,
submission.selective_process
)
submission.ai_score = score
submission.save()
@shared_task
def send_notification_email(user_id, template, context):
"""Envia email de notificação"""
user = User.objects.get(id=user_id)
send_mail(
template=template,
to=user.email,
context=context
)
3. Celery Beat - Tarefas Periódicas
# Configuração de tarefas periódicas
CELERY_BEAT_SCHEDULE = {
'update-rankings': {
'task': 'job_vacancies.tasks.update_candidate_rankings',
'schedule': crontab(hour=2, minute=0), # Diariamente às 2h
},
'cleanup-expired-sessions': {
'task': 'accounts.tasks.cleanup_sessions',
'schedule': timedelta(hours=6), # A cada 6 horas
},
}
Componentes de Infraestrutura
1. Banco de Dados PostgreSQL
# Configuração do banco
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'portal_talentos',
'USER': 'portal_user',
'HOST': 'postgres',
'PORT': '5432',
'CONN_MAX_AGE': 600,
}
}
2. Cache Redis
# Configuração de cache
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://redis:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'PARSER_CLASS': 'redis.connection.HiredisParser',
'CONNECTION_POOL_CLASS': 'redis.BlockingConnectionPool',
}
}
}
# Broker Celery
CELERY_BROKER_URL = 'redis://redis:6379/0'
CELERY_RESULT_BACKEND = 'django-db'
3. Armazenamento de Arquivos
# Configuração de mídia
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'
# Validadores de upload
def validate_image_size(image):
"""Valida tamanho máximo de 5MB"""
def validate_image_extension(value):
"""Aceita apenas jpg, jpeg, png"""
4. Docker Compose
# docker-compose.dev.yml
services:
backend:
build: ./backend
ports:
- "8000:8000"
depends_on:
- postgres
- redis
postgres:
image: postgres:14
environment:
POSTGRES_DB: portal_talentos
redis:
image: redis:7.2-alpine
worker:
build: ./backend
command: celery -A app worker -l info
beat:
build: ./backend
command: celery -A app beat -l info
APIs e Endpoints
Estrutura de APIs REST
# URLs principais
urlpatterns = [
path('api/auth/', include('authentication.urls')),
path('api/accounts/', include('accounts.urls')),
path('api/candidates/', include('candidates.urls')),
path('api/companies/', include('companies.urls')),
path('api/job-vacancies/', include('job_vacancies.urls')),
path('api/questionnaires/', include('questionnaires.urls')),
]
Documentação Swagger
# Configuração DRF Spectacular
SPECTACULAR_SETTINGS = {
'TITLE': 'Acesso ao Emprego API',
'DESCRIPTION': 'API do Sistema de Gestão do Perfil Profissional',
'VERSION': '1.0.0',
'SERVE_INCLUDE_SCHEMA': False,
}
Arquitetura Atual
Esta documentação reflete a arquitetura atual implementada no Acesso ao Emprego, com foco nos componentes realmente utilizados em produção.