C2 backend
Actualizado: 7 de marzo de 2026
C2 — Reto Tecnico: Desarrollo Backend#
Cargo: Desarrollo Backend Tipo de reto: Desarrollo de producto Stack: Node.js, TypeScript, NestJS, Prisma, PostgreSQL Producto: PayrollAPI — API de gestion de nomina Metodologia de evaluacion: Ver 00-metodologia-evaluacion.md
1. Vision del Producto#
Producto: PayrollAPI — Una API REST para gestion de nomina de empleados con calculo automatico de salarios, deducciones, impuestos y generacion de recibos.
Problema que resuelve: Las empresas pequenas necesitan calcular nominas mensuales de forma precisa, con reglas fiscales, deducciones variables y un historial auditable de pagos.
Usuarios objetivo: Departamentos de RRHH de empresas de 10-200 empleados.
No hay frontend. El reto es 100% backend. Se evalua la API via Swagger, Postman, y tests automatizados.
2. Roles del Sistema#
| Rol | Descripcion | Permisos |
|---|---|---|
| Admin RRHH | Gestor principal de nomina | CRUD empleados, ejecutar nomina, ver reportes, configurar reglas |
| Contador | Revisa y aprueba nominas | Ver nominas, aprobar/rechazar, exportar reportes. No puede editar empleados |
| Empleado | Consulta su propio recibo | Ver sus recibos de pago, descargar PDF. No puede ver datos de otros |
3. Historias de Usuario — Backlog Priorizado#
H01 — Registro y autenticacion#
Prioridad: Critica | Nivel minimo: N1 | Estimacion: 2 pts
Como admin RRHH, quiero registrarme e iniciar sesion para gestionar la nomina de mi empresa.
Criterios de aceptacion:
- AC-01: Registro con email, nombre y contrasena (minimo 8 chars, 1 numero, 1 mayuscula). Contrasena hasheada con bcrypt (costo >= 10)
- AC-02: Login devuelve JWT (expira 24h) con role del usuario en el payload
- AC-03: Endpoint de refresh token. Logout invalida el token
- AC-04: Rutas protegidas por rol: admin ve todo, contador solo lectura de nominas, empleado solo sus datos
- AC-05: Si credenciales incorrectas: "Credenciales invalidas" (sin revelar que campo fallo)
Definition of Done: Tests de registro, login exitoso, login fallido, acceso por rol.
H02 — CRUD de empleados#
Prioridad: Critica | Nivel minimo: N1 | Estimacion: 3 pts
Como admin RRHH, quiero gestionar los empleados de mi empresa para tener un registro actualizado.
Criterios de aceptacion:
- AC-01: Crear empleado: nombre, apellido, cedula (unica), email (unico), fecha ingreso, salario base, departamento, tipo contrato (FIJO / TEMPORAL)
- AC-02: Editar empleado: todos los campos excepto cedula
- AC-03: Desactivar empleado (soft-delete con
terminatedAt). No se elimina fisicamente - AC-04: Listar empleados con paginacion (
?page=1&limit=20&department=IT&status=active) - AC-05: Buscar por nombre o cedula (parcial, case-insensitive)
Definition of Done: CRUD completo. Test de creacion con validacion. Test de paginacion.
H03 — Configuracion de reglas de nomina#
Prioridad: Critica | Nivel minimo: N1 | Estimacion: 3 pts
Como admin RRHH, quiero configurar las reglas fiscales y de deducciones para que la nomina se calcule correctamente.
Criterios de aceptacion:
- AC-01: Tabla de configuracion con: concepto (nombre), tipo (DEDUCCION / BONIFICACION), calculo (PORCENTAJE / MONTO_FIJO), valor, aplicaA (TODOS / FIJO / TEMPORAL), activo (boolean)
- AC-02: Reglas predeterminadas al hacer seed: AFP (2.87%), SFS (3.04%), ISR (escala progresiva RD), Bono vacacional (1 salario/ano)
- AC-03: El admin puede crear, editar y desactivar reglas. No puede eliminarlas (auditoria)
- AC-04: Las reglas tienen un campo
effectiveDate— no aplican retroactivamente
Tabla ISR Republica Dominicana (simplificada para el reto):
| Rango anual (DOP) | Tasa |
|---|---|
| 0 — 416,220 | Exento |
| 416,220.01 — 624,329 | 15% del excedente |
| 624,329.01 — 867,123 | 20% del excedente + 31,216 |
| 867,123.01+ | 25% del excedente + 79,776 |
Definition of Done: Seed crea reglas default. Test que valida calculo ISR para 3 rangos diferentes.
H04 — Calculo de nomina mensual#
Prioridad: Critica | Nivel minimo: N1 | Estimacion: 5 pts
Como admin RRHH, quiero ejecutar el calculo de nomina de un mes para generar los recibos de todos los empleados activos.
Criterios de aceptacion:
- AC-01: Endpoint POST /payroll/calculate con
{ month: "2026-03", employeeIds?: string[] }. Si no se envian IDs, calcula para todos los empleados activos - AC-02: Para cada empleado calcula: salario bruto, cada deduccion aplicable, salario neto = bruto - deducciones + bonificaciones
- AC-03: El ISR se calcula sobre el ingreso anual (salario mensual × 12) y se divide entre 12 para la retencion mensual
- AC-04: Se crea un registro de
PayrollRuncon: mes, fecha de ejecucion, estado (DRAFT / APPROVED / PAID), total bruto, total deducciones, total neto - AC-05: Cada empleado tiene un
PayrollItemvinculado al run con el desglose detallado - AC-06: No se puede ejecutar la misma nomina dos veces para el mismo mes (idempotencia). Si ya existe un run para ese mes en DRAFT, retorna el existente. Si esta en APPROVED/PAID, error 409
Definition of Done: Test que ejecuta nomina para 3 empleados con salarios diferentes y valida los calculos de ISR, AFP y SFS.
H05 — Aprobacion y flujo de nomina#
Prioridad: Alta | Nivel minimo: N2 | Estimacion: 3 pts
Como contador, quiero aprobar o rechazar una nomina antes de que se procese el pago.
Criterios de aceptacion:
- AC-01: Endpoint PATCH /payroll/:id/approve — cambia estado de DRAFT a APPROVED. Solo rol contador o admin
- AC-02: Endpoint PATCH /payroll/:id/reject — cambia estado de DRAFT a REJECTED con motivo obligatorio
- AC-03: Una nomina REJECTED puede recalcularse (vuelve a DRAFT). Una APPROVED no puede modificarse
- AC-04: Endpoint PATCH /payroll/:id/pay — cambia de APPROVED a PAID. Solo admin. Registra fecha de pago
- AC-05: Historial de transiciones de estado (audit log): quien cambio, cuando, de que estado a cual
Definition of Done: Test del flujo completo: DRAFT -> APPROVED -> PAID. Test de rechazo y recalculo.
H06 — API REST documentada#
Prioridad: Alta | Nivel minimo: N2 | Estimacion: 3 pts
Como evaluador tecnico, quiero consultar la API sin frontend para verificar que todo funciona.
Criterios de aceptacion:
- AC-01: Todos los endpoints siguen convenciones REST con codigos HTTP correctos (200, 201, 204, 400, 401, 403, 404, 409, 422)
- AC-02: Errores en formato consistente:
{ error: string, message: string, statusCode: number } - AC-03: Swagger/OpenAPI accesible en /api/docs
- AC-04: Paginacion en listados:
{ data: [], meta: { total, page, limit, pages } }
Endpoints esperados:
POST /auth/register
POST /auth/login
POST /auth/logout
POST /auth/refresh
GET /employees (listar, filtros: department, status, search)
POST /employees (crear)
GET /employees/:id (detalle)
PATCH /employees/:id (editar)
DELETE /employees/:id (soft-delete / desactivar)
GET /payroll-rules (listar reglas activas)
POST /payroll-rules (crear regla)
PATCH /payroll-rules/:id (editar regla)
POST /payroll/calculate (ejecutar calculo)
GET /payroll (listar nominas, filtro por mes/estado)
GET /payroll/:id (detalle con items por empleado)
PATCH /payroll/:id/approve (aprobar)
PATCH /payroll/:id/reject (rechazar)
PATCH /payroll/:id/pay (marcar como pagada)
GET /payroll/:id/receipts/:employeeId (recibo individual)
GET /payroll/:id/export (exportar resumen)
GET /me/receipts (empleado ve sus propios recibos)
Definition of Done: Swagger accesible. Todos los endpoints responden correctamente.
H07 — Modelo de datos y migraciones#
Prioridad: Alta | Nivel minimo: N2 | Estimacion: 2 pts
Como desarrollador que toma el proyecto, quiero levantar la base de datos con un solo comando.
Criterios de aceptacion:
- AC-01: Schema Prisma con migraciones versionadas
- AC-02:
npx prisma migrate deploylevanta todo sin errores - AC-03: Seed crea: 1 admin, 1 contador, 5 empleados con diferentes salarios, reglas de nomina default, 1 nomina de ejemplo
- AC-04: Indices en: email (unique), cedula (unique), payrollRunId en items, effectiveDate en reglas
Modelo minimo esperado:
User: id, name, email (unique), password, role (ADMIN/ACCOUNTANT/EMPLOYEE), employeeId? (FK), createdAt
Employee: id, firstName, lastName, cedula (unique), email (unique), hireDate, baseSalary (Decimal), department, contractType (FIXED/TEMPORARY), terminatedAt?, createdAt, updatedAt
PayrollRule: id, name, type (DEDUCTION/BONUS), calculation (PERCENTAGE/FIXED_AMOUNT), value (Decimal), appliesTo (ALL/FIXED/TEMPORARY), active, effectiveDate, createdAt
PayrollRun: id, month (unique format YYYY-MM), status (DRAFT/APPROVED/REJECTED/PAID), totalGross, totalDeductions, totalNet, executedAt, approvedBy?, approvedAt?, paidAt?, createdAt
PayrollItem: id, payrollRunId (FK), employeeId (FK), grossSalary, deductions (JSON detail), bonuses (JSON detail), netSalary, createdAt
AuditLog: id, entity, entityId, action, changedBy (FK User), oldValue (JSON), newValue (JSON), createdAt
Definition of Done: git clone + npm install + npx prisma migrate deploy + npx prisma db seed = DB lista con datos de ejemplo.
H08 — Generacion de recibos#
Prioridad: Alta | Nivel minimo: N2 | Estimacion: 3 pts
Como empleado, quiero descargar mi recibo de pago en PDF para mis registros personales.
Criterios de aceptacion:
- AC-01: Endpoint GET /payroll/:runId/receipts/:employeeId que genera un PDF del recibo
- AC-02: El PDF incluye: nombre empresa, periodo, datos del empleado, desglose (salario bruto, cada deduccion con nombre y monto, bonificaciones, salario neto)
- AC-03: El empleado solo puede ver sus propios recibos (verificacion de token + employeeId)
- AC-04: Cache del PDF: si ya se genero para ese run+empleado, no recalcular
- AC-05: Endpoint GET /me/receipts para que el empleado liste todos sus recibos historicos
Definition of Done: Descargar PDF. Verificar que los montos coinciden con el calculo. Test de autorizacion (empleado A no puede ver recibo de empleado B).
H09 — Reportes y exportacion#
Prioridad: Alta | Nivel minimo: N3 | Estimacion: 3 pts
Como admin RRHH, quiero exportar la nomina en diferentes formatos para enviar al banco y a contabilidad.
Criterios de aceptacion:
- AC-01: Endpoint GET /payroll/:id/export?format=csv que exporta la nomina completa en CSV
- AC-02: Endpoint GET /payroll/:id/export?format=json para integracion con otros sistemas
- AC-03: Reporte de costos por departamento: GET /reports/by-department?month=2026-03
- AC-04: Reporte historico: GET /reports/employee/:id/history — todos los recibos de un empleado con grafico de salario neto por mes
- AC-05: Solo admin y contador pueden acceder a reportes
Definition of Done: CSV descargable con formato correcto. Test de reporte por departamento con 3 departamentos.
H10 — Webhook bancario#
Prioridad: Alta | Nivel minimo: N3 | Estimacion: 3 pts
Como sistema de nomina, quiero recibir confirmacion del banco cuando los pagos se procesan para actualizar el estado automaticamente.
Criterios de aceptacion:
- AC-01: Endpoint POST /webhook/bank que recibe notificacion de pago procesado
- AC-02: El webhook verifica una firma HMAC-SHA256 en el header
X-Bank-Signature(clave en.env) - AC-03: Al recibir confirmacion, actualiza el PayrollRun de PAID a COMPLETED y registra referencia bancaria
- AC-04: Si el banco reporta fallo, marca como PAYMENT_FAILED y notifica al admin (log o event)
- AC-05: Idempotencia: si el mismo webhook llega dos veces, no procesa duplicado
Datos de prueba: Script de simulacion del webhook incluido en el repo (scripts/simulate-bank-webhook.ts).
Definition of Done: Test que simula webhook exitoso y fallido. Verificar idempotencia.
H11 — Nomina automatica (Cron job)#
Prioridad: Media | Nivel minimo: N3 | Estimacion: 3 pts
Como admin RRHH, quiero que la nomina se precalcule automaticamente el dia 25 de cada mes para no olvidarme.
Criterios de aceptacion:
- AC-01: Cron job que ejecuta el calculo de nomina el dia 25 a las 08:00
- AC-02: Crea la nomina en estado DRAFT — no aprueba ni paga automaticamente
- AC-03: Envia notificacion (log o evento) al admin y al contador de que la nomina esta lista para revision
- AC-04: Si la nomina de ese mes ya existe, no crea duplicado
- AC-05: El cron es configurable via variable de entorno (
PAYROLL_CRON_SCHEDULE)
Definition of Done: Cron ejecuta correctamente. Test que simula ejecucion y verifica que se crea el PayrollRun.
H12 — Testing#
Prioridad: Alta | Nivel minimo: N3 | Estimacion: 3 pts
Como equipo tecnico, queremos confianza de que los calculos de nomina son correctos.
Criterios de aceptacion:
- AC-01: Tests unitarios para: calculo de ISR (todos los rangos), calculo de AFP, calculo de SFS, aplicacion de reglas
- AC-02: Tests de integracion para: flujo completo de nomina (crear empleados -> calcular -> aprobar -> pagar), autorizacion por roles
- AC-03: Al menos 1 test E2E: flujo completo desde registro hasta descarga de recibo PDF
- AC-04: Coverage > 60% (N3) o > 80% (N4)
- AC-05:
npm testcorre sin configuracion adicional - AC-06: Test de edge cases: empleado con salario exento de ISR, empleado temporal sin bono vacacional, nomina rechazada y recalculada
Definition of Done: npm test pasa. Coverage report generado.
H13 — CI/CD Pipeline (solo N4)#
Prioridad: Media | Nivel minimo: N4 | Estimacion: 3 pts
Como equipo DevOps, quiero deploy automatico si los tests pasan.
Criterios de aceptacion:
- AC-01: Pipeline GitHub Actions / Cloud Build: install, lint, test, build, deploy
- AC-02: Pipeline falla si tests fallan, lint tiene errores, o build falla
- AC-03: Deploy a staging en push a
develop, produccion en push amain - AC-04: Secrets gestionados en CI, no en el repo
- AC-05: Notificacion de resultado
Definition of Done: Push, pipeline verde, app desplegada automaticamente.
H14 — Observabilidad (solo N4)#
Prioridad: Media | Nivel minimo: N4 | Estimacion: 3 pts
Como operador, quiero logs, metricas y alertas.
Criterios de aceptacion:
- AC-01: Logging estructurado JSON (pino/winston). Cada log: timestamp, level, message, requestId
- AC-02: GET /health: status, uptime, version, DB connectivity
- AC-03: Metricas: requests/s, latencia p50/p95/p99, errores/s
- AC-04: Alerta si healthcheck falla 3 veces seguidas
- AC-05: Dashboard basico con metricas reales
Definition of Done: Dashboard accesible con metricas del sistema desplegado.
H15 — Documentacion de arquitectura (solo N4)#
Prioridad: Media | Nivel minimo: N4 | Estimacion: 2 pts
Como arquitecto, quiero entender las decisiones sin leer todo el codigo.
Criterios de aceptacion:
- AC-01: Diagrama de arquitectura C4 nivel 2 minimo
- AC-02: Al menos 3 ADRs documentando decisiones clave
- AC-03: README completo: setup, tests, deploy, env vars
- AC-04: Trade-offs documentados explicitamente
Definition of Done: Un dev nuevo entiende la arquitectura leyendo solo README y ADRs.
4. Sprint Planning — Que completar segun tu nivel#
| Historia | N1 Junior | N2 Semi-Senior | N3 Senior | N4 Arquitecto |
|---|---|---|---|---|
| H01 Auth | Obligatoria | Obligatoria | Obligatoria | Obligatoria |
| H02 CRUD empleados | Obligatoria | Obligatoria | Obligatoria | Obligatoria |
| H03 Reglas nomina | Obligatoria | Obligatoria | Obligatoria | Obligatoria |
| H04 Calculo nomina | Obligatoria | Obligatoria | Obligatoria | Obligatoria |
| H05 Aprobacion | — | Obligatoria | Obligatoria | Obligatoria |
| H06 API documentada | — | Obligatoria | Obligatoria | Obligatoria |
| H07 Modelo y migraciones | — | Obligatoria | Obligatoria | Obligatoria |
| H08 Recibos PDF | — | Obligatoria | Obligatoria | Obligatoria |
| H09 Reportes | — | — | Obligatoria | Obligatoria |
| H10 Webhook banco | — | — | Obligatoria | Obligatoria |
| H11 Cron job | — | — | Obligatoria | Obligatoria |
| H12 Testing | — | — | Obligatoria | Obligatoria |
| H13 CI/CD | — | — | — | Obligatoria |
| H14 Observabilidad | — | — | — | Obligatoria |
| H15 Docs arquitectura | — | — | — | Obligatoria |
5. Timebox del Sprint#
| Nivel | Tiempo total | Expectativa |
|---|---|---|
| N1 — Junior | 8 horas | H01-H04. Auth + CRUD + calculo de nomina funcionando con numeros correctos |
| N2 — Semi-Senior | 8 horas | H01-H08. Flujo completo de aprobacion + API documentada + recibos PDF |
| N3 — Senior | 6 horas | H01-H12. Reportes + webhook + cron + tests + 60% coverage |
| N4 — Arquitecto | 6 horas | H01-H15. Todo + CI/CD + observabilidad + ADRs |
6. Entregables#
| # | Entregable | Descripcion | Obligatorio |
|---|---|---|---|
| E1 | Repositorio Git | Publico o privado con acceso concedido al evaluador. Historial visible | Si |
| E2 | URL de deploy | API funcionando en URL publica | Si para N2+ |
| E3 | README | Setup local, correr tests, desplegar, env vars | Si |
| E4 | Video explicativo | 5 min max: que construiste, decisiones clave, que harias diferente | Si |
| E5 | Diagrama arquitectura | C4, Mermaid, draw.io | Solo N4 |
| E6 | ADRs | Minimo 3 decisiones documentadas | Solo N4 |
7. Stack sugerido (no obligatorio)#
| Capa | Opcion A (nuestro stack) | Opcion B | Opcion C |
|---|---|---|---|
| Framework | NestJS + TypeScript | Express + TypeScript | Fastify + TypeScript |
| ORM | Prisma + PostgreSQL | TypeORM + PostgreSQL | Drizzle + PostgreSQL |
| Auth | Passport JWT | Custom JWT middleware | Auth0 |
| @react-pdf/renderer o PDFKit | Puppeteer (headless HTML->PDF) | jsPDF | |
| Cron | @nestjs/schedule (cron) | node-cron | Bull queue + scheduler |
| Testing | Jest + Supertest | Vitest + Supertest | Mocha + Chai |
| Deploy | Railway | Render | Docker + VPS |
| CI/CD | GitHub Actions | Cloud Build | GitLab CI |
Reto especifico para C2 — Backend. Para la rubrica general y metodologia, ver 00-metodologia-evaluacion.md