Proyecto de Tesis de Ingeniería en Informática
Nidus es una plataforma SaaS B2B que transforma el reclutamiento mediante:
- Motor Semántico: Busca candidatos por significado, no solo palabras clave
- Reducción de Sesgos: Anonimiza automáticamente datos demográficos
- Arquitectura Empresarial: Hexagonal, multi-tenant, escalable
- Observabilidad: Métricas en tiempo real con Prometheus + Grafana
- Docker & Docker Compose 3.8+
- Git
- (Opcional) Python 3.11+ para desarrollo local
git clone https://github.com/Medalcode/Nidus.git
cd Nidus
# Crear archivo .env
cp backend/.env.example backend/.env # (si existe)
# O crear uno manualmente:
cat > backend/.env << EOF
DATABASE_URL=postgresql://nidus_user:nidus_password@db:5432/nidus_db
CELERY_BROKER_URL=redis://redis:6379/0
CELERY_RESULT_BACKEND=redis://redis:6379/0
SECRET_KEY=your-secret-key-change-in-production
ENVIRONMENT=development
EOF# Construir y levantar todos los servicios
docker-compose up -d
# Ver logs
docker-compose logs -f backend # Backend FastAPI
docker-compose logs -f worker # Celery worker
docker-compose logs -f db # Base de datos# Backend API
curl -s http://localhost:8000/health | jq
# Prometheus
open http://localhost:9090
# Buscar métrica: up{job="fastapi"}
# Grafana (Dashboard)
open http://localhost:3000
# Login: admin / admin
# Redis CLI
redis-cli PING
# Output: PONG
# PostgreSQL
psql postgresql://nidus_user:nidus_password@localhost:5432/nidus_db -c "\dt"cd backend
# Crear venv
python3.11 -m venv venv
source venv/bin/activate # Linux/Mac
# o: venv\Scripts\activate # Windows
# Instalar dependencias
pip install -r requirements.txt
# Descargar modelo spaCy (para NLP en Fase 2)
python -m spacy download es_core_news_md
# Configurar variables de entorno
export DATABASE_URL="postgresql://nidus_user:nidus_password@localhost:5432/nidus_db"
export CELERY_BROKER_URL="redis://localhost:6379/0"
export SECRET_KEY="dev-secret-key"cd backend
# Crear todas las tablas
alembic upgrade head
# Verificar esquema
alembic current
# Ver historial de migraciones
alembic history --verbose# Terminal 1: Backend FastAPI
cd backend
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# Terminal 2: Celery Worker
cd backend
celery -A app.celery_app worker --loglevel=info
# Terminal 3: Frontend (si está en desarrollo)
cd frontend
npm install
npm start
# Terminal 4: Redis (si no usas Docker)
redis-server# Documentación interactiva (Swagger)
open http://localhost:8000/docs
# Health check
curl -s http://localhost:8000/api/v1/health | jq
# Ver métricas
curl -s http://localhost:8000/metrics | grep "fastapi"Nidus/
├── .github/
│ ├── IMPLEMENTATION_PLAN.md # Roadmap detallado (5 fases)
│ ├── IMPLEMENTATION_STATUS.md # Status actual + hitos
│ └── workflows/ # CI/CD (en desarrollo)
├── backend/
│ ├── app/
│ │ ├── api/
│ │ │ ├── v1/
│ │ │ │ ├── router.py # Enrutador principal
│ │ │ │ └── endpoints/ # Endpoints por recurso
│ │ │ └── deps.py # Inyección de dependencias ✨ NUEVO
│ │ ├── models/
│ │ │ ├── tenant.py # Modelo Tenant ✨ NUEVO
│ │ │ ├── user.py # Modelo User (actualizado)
│ │ │ └── candidate.py # Modelo Candidate (actualizado)
│ │ ├── repositories/ # Acceso a datos (Hexagonal)
│ │ │ ├── base.py # Base genérica (actualizado)
│ │ │ └── candidate.py # Candidate repo (ampliado)
│ │ ├── services/
│ │ │ └── candidate_service.py # Lógica de negocio ✨ NUEVO
│ │ ├── schemas/
│ │ │ └── candidate.py # Pydantic schemas ✨ NUEVO
│ │ ├── tasks/
│ │ │ └── cv_processing.py # Celery tasks (a actualizar)
│ │ ├── core/
│ │ │ ├── config.py # Variables de entorno
│ │ │ ├── database.py # Conexión SQLAlchemy
│ │ │ └── logging_config.py # Logging centralizado
│ │ ├── celery_app.py # Configuración Celery
│ │ └── main.py # Punto de entrada FastAPI
│ ├── migrations/
│ │ ├── env.py
│ │ └── versions/
│ │ └── 001_add_multitenant_and_ai_fields.py ✨ NUEVO
│ ├── Dockerfile # ✨ NUEVO (multi-stage)
│ ├── requirements.txt # ✨ ACTUALIZADO (NLP, pgvector, prometheus)
│ └── alembic.ini
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ │ ├── AnalysisPanel.jsx # Búsqueda semántica (Fase 5)
│ │ │ └── Dashboard.jsx
│ │ ├── lib/
│ │ │ └── api.js # API client
│ │ └── index.js
│ ├── Dockerfile # ✨ NUEVO
│ └── package.json
├── docker-compose.yml # ✨ ACTUALIZADO (stack completo)
├── prometheus.yml # ✨ NUEVO (config Prometheus)
└── README.md # Este archivo
Leyenda:
- ✨ NUEVO: Creado en esta actualización
- 🔄 ACTUALIZADO: Modificado significativamente
┌─────────────────────────────────────┐
│ Frontend (React) │ Fase 5 (🟡 TODO)
│ - AnalysisPanel.jsx │
│ - Búsqueda Semántica UI │
└────────────────┬────────────────────┘
│ HTTP/REST
┌────────────────▼────────────────────┐
│ FastAPI API Layer (v1) │ Fase 1 ✅
│ - /candidates │
│ - /search/semantic │
│ - /metrics │
│ - Endpoints con deps.py (deps) │
└────────────────┬────────────────────┘
│
┌────────┴────────┐
│ │
┌───────▼──────┐ ┌───────▼──────┐
│ Services │ │ Repositories│ Hexagonal ✅
│ (Business │ │ (Data Access│
│ Logic) │ │ Layer) │
└───────┬──────┘ └───────┬──────┘
│ │
└────────┬────────┘
│
┌────────▼────────┐
│ SQLAlchemy │
│ Models │ Multi-Tenant ✅
│ (tenant_id) │
└────────┬────────┘
│
┌────────▼────────┐
│ PostgreSQL │
│ + pgvector │ Fase 2 (🟡 TODO)
│ (embeddings) │
└─────────────────┘
Asíncrono:
┌──────────────┐
│ Celery Tasks │ Fase 3 (🟡 TODO: reintentos + DLQ)
│ (cv_process) │
└──────┬───────┘
│
┌──────▼───────┐
│ Redis Broker │
└──────────────┘
Cada usuario pertenece a un Tenant (empresa). Los datos se filtran automáticamente:
# En cualquier endpoint:
@router.get("/candidates/")
def get_candidates(
db: Session = Depends(get_db),
tenant_id: int = Depends(get_current_tenant_id), # ← Automático
):
# La consulta SIEMPRE filtra por tenant_id
candidates = candidate_repo.get_multi(db, tenant_id=tenant_id)
return candidatesSeguridad garantizada:
- ✅ Usuario de Tenant A NO puede ver datos de Tenant B
- ✅ Inyección de dependencias automática
- ✅ Verificación en cada operación CRUD
| Fase | Nombre | Estado | Duración |
|---|---|---|---|
| 1 | Arquitectura Hexagonal + Multi-Tenancy | ✅ DONE | 2-3 días |
| 2 | Motor Semántico + NLP + Anonimización | 🟡 TODO | 3-4 días |
| 3 | Robustez Celery + DLQ + Observabilidad | 🟡 TODO | 2 días |
| 4 | Docker + CI/CD (GitHub Actions) | 🟡 TODO | 2 días |
| 5 | Frontend React (AnalysisPanel) | 🟡 TODO | 3 días |
Detalles completos: Ver IMPLEMENTATION_PLAN.md
Status actual: Ver IMPLEMENTATION_STATUS.md
# Unit tests
cd backend
pytest tests/ -v
# Con cobertura
pytest --cov=app tests/
# Specific test
pytest tests/test_api.py::test_candidate_creation -v# Ejecutar migraciones
cd backend
alembic upgrade head# El contenedor de Docker automáticamente lo habilita
# Para desarrollo local:
docker exec nidus_db psql -U nidus_user -d nidus_db -c "CREATE EXTENSION IF NOT EXISTS vector;"# Asegúrate que Redis está corriendo
docker-compose ps
# O localmente:
redis-server- Plan Detallado: IMPLEMENTATION_PLAN.md
- Status Actual: IMPLEMENTATION_STATUS.md
- API Docs:
http://localhost:8000/docs(Swagger interactivo) - Backlog & Issues: docs/BACKLOG.md
Componentes Demostrados:
- ✅ Arquitectura Hexagonal (Repository + Service pattern)
- ✅ Multi-tenancy segura (tenant_id filtering)
- ✅ Inyección de dependencias (FastAPI Depends)
- ✅ JWT Authentication
- 🟡 Semantic search (Fase 2)
- 🟡 Bias reduction (Fase 2)
- 🟡 Distributed system resilience (Fase 3)
Valor académico:
- Sistema real producción-listo
- Demostración de patrones empresariales
- Ética en IA integrada desde el diseño
- Desarrollo: Copilot (Implementación técnica)
- Supervisión: Gemini (Validación arquitectura + decisiones)
- Autor: [Tu nombre - Tesis de Ingeniería]
MIT License - Ver LICENSE
Última actualización: Mayo 2026
Versión: 0.2.0 (Fase 1 Complete)
Próxima: Fase 2 - Motor Semántico + NLP