Fluxo de Dados do Sistema
Visão Geral
O Acesso ao Emprego utiliza uma arquitetura monolítica modular com Django, onde o fluxo de dados é gerenciado através de views, serializers, models e processamento assíncrono com Celery.
Fluxos Principais de Dados
1. Fluxo de Cadastro de Candidato
2. Fluxo de Publicação de Processo Seletivo
3. Fluxo de Matching com IA
Modelos de Dados
Schema Principal (PostgreSQL)
# accounts/models.py
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_avatar_path)
# candidates/models.py
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)
start_year = models.IntegerField()
end_year = models.IntegerField(null=True)
# job_vacancies/models.py
class SelectiveProcess(models.Model):
company = models.ForeignKey(Company)
title = models.CharField(max_length=255)
description = models.TextField()
requirements = models.JSONField()
salary_min = models.DecimalField()
salary_max = models.DecimalField()
status = models.CharField(choices=PROCESS_STATUS)
created_at = models.DateTimeField(auto_now_add=True)
class CandidateSubmission(models.Model):
candidate = models.ForeignKey(Candidate)
selective_process = models.ForeignKey(SelectiveProcess)
submitted_at = models.DateTimeField(auto_now_add=True)
ai_score = models.DecimalField(null=True)
status = models.CharField(choices=SUBMISSION_STATUS)
Cache Structure (Redis)
# Cache patterns utilizados
CACHE_PATTERNS = {
# Cache de usuário
'user': {
'key': 'user:{user_id}',
'ttl': 3600, # 1 hora
'data': 'User object serializado'
},
# Cache de processos seletivos
'selective_process': {
'key': 'sp:{process_id}',
'ttl': 1800, # 30 minutos
'data': 'SelectiveProcess serializado'
},
# Cache de scores de matching
'matching_scores': {
'key': 'match:{candidate_id}:{process_id}',
'ttl': 86400, # 24 horas
'data': 'Score decimal'
},
# Cache de sessão
'session': {
'key': 'session:{session_key}',
'ttl': 86400, # 24 horas
'data': 'Session data'
}
}
Processamento Assíncrono com Celery
Tasks Implementadas
# job_vacancies/tasks.py
@shared_task
def calculate_submission_rate(submission_id):
"""
Calcula score de compatibilidade usando Fuzzy Logic
"""
submission = CandidateSubmission.objects.get(id=submission_id)
# Buscar dados
candidate_data = serialize_candidate(submission.candidate)
job_data = serialize_job(submission.selective_process)
# Processar com Fuzzy
from fuzzy.pln_processing import FuzzyProcessor
processor = FuzzyProcessor()
score = processor.calculate_match(candidate_data, job_data)
# Atualizar banco
submission.ai_score = score
submission.save()
# Invalidar cache
cache.delete(f'match:{submission.candidate_id}:{submission.selective_process_id}')
return score
@shared_task
def update_candidate_rankings():
"""
Task periódica para atualizar rankings
"""
active_processes = SelectiveProcess.objects.filter(
status='active'
)
for process in active_processes:
submissions = CandidateSubmission.objects.filter(
selective_process=process,
status='pending'
)
for submission in submissions:
calculate_submission_rate.delay(submission.id)
Fluxo de Autenticação e Autorização
Segurança de Dados
Validação e Sanitização
# serializers.py
class CandidateSerializer(serializers.ModelSerializer):
cpf = serializers.CharField(
validators=[validate_cpf],
write_only=True
)
email = serializers.EmailField(
validators=[EmailValidator()]
)
birth_date = serializers.DateField(
validators=[validate_age]
)
def validate(self, data):
# Sanitizar dados
data['full_name'] = clean_text(data.get('full_name'))
data['description'] = sanitize_html(data.get('description'))
return data
Controle de Acesso
# permissions.py
class IsOwnerPermission(BasePermission):
"""Apenas o dono pode acessar"""
def has_object_permission(self, request, view, obj):
return obj.user == request.user
class IsCandidatePermission(BasePermission):
"""Apenas candidatos podem acessar"""
def has_permission(self, request, view):
return request.user.is_candidate
class IsCompanyUserPermission(BasePermission):
"""Apenas usuários de empresa podem acessar"""
def has_permission(self, request, view):
return request.user.is_company
Otimização de Performance
Estratégias Implementadas
-
Database Optimization
- Índices em campos frequentemente consultados
- Select_related e prefetch_related no ORM
- Connection pooling
-
Cache Strategy
- Cache de objetos frequentes no Redis
- Cache de sessão
- Invalidação inteligente
-
Async Processing
- Tarefas pesadas no Celery
- Batch processing periódico
- Queue prioritization
# views.py - Exemplo de otimização
class SelectiveProcessViewSet(viewsets.ModelViewSet):
def get_queryset(self):
return SelectiveProcess.objects.select_related(
'company'
).prefetch_related(
'stages',
'submissions__candidate__user'
).annotate(
submission_count=Count('submissions')
)
Monitoramento do Fluxo de Dados
Logs e Métricas
# logging_config.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': 'logs/portal.log',
'maxBytes': 10485760, # 10MB
'backupCount': 5,
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'INFO',
},
'celery': {
'handlers': ['file'],
'level': 'INFO',
},
'fuzzy': {
'handlers': ['file'],
'level': 'DEBUG',
},
},
}
Arquitetura Simplificada
Este documento reflete o fluxo de dados real implementado no Acesso ao Emprego, focando na arquitetura Django monolítica com processamento assíncrono via Celery.
Performance
O sistema está otimizado para processar milhares de candidaturas diárias com uso eficiente de cache e processamento assíncrono.