{"id":31850037,"url":"https://github.com/dev-gaspar/work-date-capta","last_synced_at":"2025-10-12T11:16:26.394Z","repository":{"id":316943409,"uuid":"1060234265","full_name":"dev-gaspar/work-date-capta","owner":"dev-gaspar","description":null,"archived":false,"fork":false,"pushed_at":"2025-09-27T17:44:10.000Z","size":124,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-27T19:31:22.509Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dev-gaspar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-19T15:26:28.000Z","updated_at":"2025-09-27T17:44:13.000Z","dependencies_parsed_at":"2025-09-27T19:31:36.643Z","dependency_job_id":null,"html_url":"https://github.com/dev-gaspar/work-date-capta","commit_stats":null,"previous_names":["dev-gaspar/work-date-capta"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/dev-gaspar/work-date-capta","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-gaspar%2Fwork-date-capta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-gaspar%2Fwork-date-capta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-gaspar%2Fwork-date-capta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-gaspar%2Fwork-date-capta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dev-gaspar","download_url":"https://codeload.github.com/dev-gaspar/work-date-capta/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-gaspar%2Fwork-date-capta/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279011195,"owners_count":26084899,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-12T02:00:06.719Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-12T11:16:22.952Z","updated_at":"2025-10-12T11:16:26.387Z","avatar_url":"https://github.com/dev-gaspar.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# API de Fechas Hábiles - Colombia\n\nAPI REST desarrollada en TypeScript para calcular fechas hábiles en Colombia, teniendo en cuenta días festivos nacionales, horarios laborales y conversiones de zona horaria.\n\n## 📋 Descripción del Proyecto\n\nEsta API fue desarrollada como parte de una prueba técnica para CAPTA, implementando un sistema que calcula fechas hábiles considerando:\n\n- **Días laborales**: Lunes a viernes\n- **Horario laboral**: 8:00 AM a 5:00 PM (hora de Colombia)\n- **Almuerzo**: 12:00 PM a 1:00 PM (no laboral)\n- **Días festivos**: Festivos oficiales de Colombia (2025-2035)\n- **Zona horaria**: Cálculos en `America/Bogota`, respuesta en UTC\n\n## 🚀 Características Implementadas\n\n### ✅ Funcionalidades Core\n- **Cálculo de fechas hábiles** sumando días y/o horas\n- **Manejo de zona horaria** Colombia → UTC\n- **Gestión de días festivos** desde archivo JSON\n- **Validación de horarios laborales** con horario de almuerzo\n- **Ajuste automático** a horarios/días laborales válidos\n- **API REST** con endpoints documentados\n\n### ✅ Arquitectura y Calidad\n- **TypeScript** con tipado estricto en toda la aplicación\n- **Arquitectura modular** (controladores, servicios, middleware, utils)\n- **Manejo centralizado de errores** con códigos HTTP apropiados\n- **Tests unitarios** con Jest cubriendo casos edge\n- **Validación de parámetros** robusta\n- **Middleware CORS** configurado\n\n## 🏗️ Estructura del Proyecto\n\n```\nfechas-habiles-capta/\n├── src/\n│   ├── app.ts                    # Configuración de Express\n│   ├── server.ts                 # Punto de entrada del servidor\n│   ├── controllers/\n│   │   └── dateController.ts     # Controlador principal de fechas\n│   ├── services/\n│   │   └── dateService.ts        # Lógica de negocio para cálculos\n│   ├── middleware/\n│   │   ├── cors.ts              # Middleware CORS\n│   │   ├── httpErrorHandlers.ts # Manejadores de errores HTTP\n│   │   └── index.ts             # Exportaciones de middleware\n│   ├── types/\n│   │   └── index.ts             # Definiciones de tipos TypeScript\n│   └── utils/\n│       ├── apiErrorHandler.ts   # Manejo centralizado de errores\n│       └── holidayUtils.ts      # Gestión de días festivos\n├── tests/\n│   ├── dateService.test.ts      # Tests unitarios del servicio de fechas\n│   ├── holidayUtils.test.ts     # Tests de utilidades de festivos\n│   └── integrationApi.test.ts   # Tests de integración de la API\n├── dist/                        # Código compilado (generado)\n├── WorkingDays.json             # Lista de días festivos 2025-2035\n├── package.json\n├── tsconfig.json\n├── jest.config.js\n└── README.md\n```\n\n## 📡 API Endpoints\n\n### `GET /work-date`\nEndpoint principal para calcular fechas hábiles.\n\n**Parámetros de Query:**\n- `days` (opcional): Número de días hábiles a sumar (entero positivo)\n- `hours` (opcional): Número de horas hábiles a sumar (entero positivo) \n- `date` (opcional): Fecha inicial en UTC ISO 8601 con sufijo Z\n\n**Respuesta exitosa (200):**\n```json\n{\n  \"date\": \"2025-01-20T14:00:00.000Z\"\n}\n```\n\n**Respuesta de error (400, 500):**\n```json\n{\n  \"error\": \"InvalidParameters\",\n  \"message\": \"Detalle del error\"\n}\n```\n\n### `GET /health`\nVerificación del estado de la API.\n\n### `GET /`\nDocumentación básica y ejemplos de uso.\n\n## 🔧 Instalación y Configuración\n\n### Prerrequisitos\n- Node.js (v16 o superior)\n- npm o yarn\n\n### Instalación\n```bash\n# Clonar el repositorio\ngit clone \u003crepository-url\u003e\ncd fechas-habiles-capta\n\n# Instalar dependencias\nnpm install\n\n# Compilar TypeScript\nnpm run build\n```\n\n### Scripts Disponibles\n```bash\n# Desarrollo con recarga automática\nnpm run dev\n\n# Compilar TypeScript\nnpm run build\n\n# Ejecutar en producción\nnpm start\n\n# Ejecutar tests\nnpm test\n\n# Ejecutar tests en modo watch\nnpm run test:watch\n```\n\n## 📚 Ejemplos de Uso\n\n### Ejemplo 1: Sumar 1 hora desde viernes 5:00 PM\n```bash\nGET /work-date?hours=1\u0026date=2025-01-17T22:00:00.000Z\n# Resultado: 2025-01-20T14:00:00.000Z (lunes 9:00 AM Colombia)\n```\n\n### Ejemplo 2: Sumar 1 día + 4 horas desde martes 3:00 PM\n```bash\nGET /work-date?days=1\u0026hours=4\u0026date=2025-01-21T20:00:00.000Z\n# Resultado: 2025-01-23T15:00:00.000Z (jueves 10:00 AM Colombia)\n```\n\n### Ejemplo 3: Calcular desde fecha con festivos\n```bash\nGET /work-date?days=5\u0026hours=4\u0026date=2025-04-10T15:00:00.000Z\n# Resultado: 2025-04-21T20:00:00.000Z (saltando festivos 17-18 abril)\n```\n\nGET /work-date?days=1\u0026hours=2\n# Calcula desde la hora actual en Colombia\n```\n\n## 🧪 Tests\n\nEl proyecto incluye tests unitarios y de integración:\n\n```bash\n# Ejecutar todos los tests\nnpm test\n\n# Ver cobertura\nnpm test -- --coverage\n```\n\n### Tests Implementados\n- **DateService**: Tests unitarios con casos de la prueba técnica\n- **HolidayManager**: Validación de festivos, fines de semana y días laborales  \n- **Integration API**: Tests de integración que validan la API completa con peticiones HTTP reales\n- **Casos edge**: Horarios de almuerzo, aproximaciones, múltiples festivos consecutivos\n\n## 🔧 Tecnologías Utilizadas\n\n### Dependencias de Producción\n- **Express.js** `^4.18.2` - Framework web\n- **Day.js** `^1.11.10` - Manipulación de fechas y zonas horarias\n- **Axios** `^1.6.0` - Cliente HTTP para peticiones HTTP\n\n### Dependencias de Desarrollo\n- **TypeScript** `^5.3.3` - Tipado estático\n- **Jest** `^29.7.0` - Framework de testing\n- **ts-jest** `^29.1.1` - Configuración Jest para TypeScript\n- **@types/express** `^4.17.21` - Tipos para Express\n- **@types/node** `^20.10.5` - Tipos para Node.js\n\n## 📐 Arquitectura y Patrones\n\n### Separación de Responsabilidades\n- **Controllers**: Manejo de requests/responses HTTP\n- **Services**: Lógica de negocio pura\n- **Utils**: Utilidades reutilizables (festivos, errores)\n- **Middleware**: Interceptores (CORS, errores)\n- **Types**: Definiciones de tipos centralizadas\n\n### Características de TypeScript\n- **Tipado estricto** en toda la aplicación\n- **Interfaces** para requests, responses y configuración\n- **Enums** para tipos de errores\n- **Tipos personalizados** para fechas y parámetros\n\n### Manejo de Errores\n- **Centralizado** a través de `ApiErrorHandler`\n- **Códigos HTTP apropiados** (400, 500)\n- **Mensajes descriptivos** en español\n- **Logging** para debugging\n\n## 🌐 Lógica de Negocio\n\n### Configuración Laboral Colombia\n```typescript\nconst WORKING_CONFIG = {\n  hours: {\n    start: 8,      // 8:00 AM\n    end: 17,       // 5:00 PM  \n    lunchStart: 12, // 12:00 PM\n    lunchEnd: 13   // 1:00 PM\n  },\n  days: {\n    monday: true, tuesday: true, wednesday: true,\n    thursday: true, friday: true,\n    saturday: false, sunday: false\n  },\n  timezone: 'America/Bogota'\n}\n```\n\n### Algoritmo de Cálculo\n1. **Conversión a zona horaria Colombia**\n2. **Ajuste a horario laboral válido**\n3. **Suma de días hábiles** (saltando festivos/fines de semana)\n4. **Suma de horas laborales** (respetando almuerzo)\n5. **Conversión final a UTC**\n\n### Días Festivos\nLos días festivos se cargan desde `WorkingDays.json` con fechas para 2025-2035, obtenidas del recurso oficial de CAPTA.\n\n## 🔍 Validaciones Implementadas\n\n### Parámetros de Entrada\n- Al menos uno de `days` o `hours` debe estar presente\n- Valores deben ser enteros positivos\n- Parámetro `date` debe estar en formato ISO 8601 UTC con sufijo Z\n\n### Ajustes Automáticos\n- **Antes de 8:00 AM**: Se ajusta a 8:00 AM\n- **Después de 5:00 PM**: Se mueve al siguiente día laboral a 8:00 AM\n- **Durante almuerzo**: Se ajusta a 1:00 PM\n- **Fin de semana/festivo**: Se mueve al siguiente día laboral a 8:00 AM\n\n## 🚀 Deployment con AWS Lambda\n\nEste proyecto incluye configuración completa para deployment en AWS Lambda usando CDK con un sistema automatizado que maneja las dependencias automáticamente.\n\n### Scripts de Deployment\n\n```bash\n# Deploy completo (recomendado para producción)\nnpm run deploy\n\n# Deploy rápido para desarrollo (usa hotswap)\nnpm run deploy:watch\n\n# Solo compilar y preparar paquete Lambda\nnpm run build:lambda\n\n# Solo preparar paquete Lambda (después de build)\nnpm run prepare-lambda\n```\n\n### ¿Cómo funciona la automatización?\n\nEl sistema automatizado (`scripts/prepare-lambda.js`) se encarga de:\n\n1. **Limpiar y recrear** el directorio `lambda-package/`\n2. **Copiar código compilado** desde `dist/`\n3. **Crear package.json optimizado** con solo dependencias de producción\n4. **Instalar dependencias** específicas para Lambda\n5. **Copiar archivos adicionales** como `WorkingDays.json`\n\n### Flujo de trabajo recomendado\n\n```bash\n# Para desarrollo iterativo\nnpm run deploy:watch\n\n# Para deployment de producción  \nnpm run deploy\n\n# Para troubleshooting\nnpm run build:lambda  # Solo preparar sin deployar\n```\n\n### Configuración AWS\n\n1. **Bootstrap CDK** (primera vez):\n   ```bash\n   cdk bootstrap\n   ```\n\n2. **Configurar credenciales AWS** usando AWS CLI o variables de entorno\n\n### API Desplegada\n\nUna vez deployada, la API estará disponible en:\n- **Health check**: `https://{api-url}/prod/health`\n- **Endpoint principal**: `https://{api-url}/prod/work-date`\n- **Documentación**: `https://{api-url}/prod/`\n\n**Nota**: El directorio `lambda-package/` se genera automáticamente","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-gaspar%2Fwork-date-capta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdev-gaspar%2Fwork-date-capta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-gaspar%2Fwork-date-capta/lists"}