Servicio backend construido con NestJS + TypeScript para gestionar productos, almacenes e inventario con trazabilidad FIFO, siguiendo principios de Clean Architecture.
- API pública versionada bajo
/api/v1 - Seguridad técnica por header
api_key(el guard también aceptax-api-keypor compatibilidad) - Documentación interactiva con Scalar en
/docs - Especificación OpenAPI en
/openapi.json - Módulos funcionales disponibles:
products,warehouseseinventory - Persistencia seleccionable por
DATABASE_TYPE(in-memoryomongodb) resuelta desdesrc/infrastructure/persistence/repository.providers.ts
pnpm install
$env:API_KEY='local-api-key'
$env:DATABASE_TYPE='in-memory'
pnpm start:devPuntos útiles una vez levantado el servicio:
GET http://localhost:3000/api/v1GET http://localhost:3000/api/v1/healthGET http://localhost:3000/docsGET http://localhost:3000/openapi.json
| Variable | Requerida | Valor por defecto | Uso |
|---|---|---|---|
API_KEY |
Sí | — | Clave obligatoria para consumir la API pública |
PORT |
No | 3000 |
Puerto HTTP del servicio |
DOCS_ENABLED |
No | true |
Habilita o deshabilita Scalar/OpenAPI |
DOCS_PATH |
No | /docs |
Ruta donde se publica la referencia interactiva |
OPENAPI_JSON_PATH |
No | /openapi.json |
Ruta del documento OpenAPI |
DATABASE_TYPE |
No | in-memory |
Selecciona el adapter de persistencia |
MONGODB_URI |
Condicional | — | Obligatoria cuando DATABASE_TYPE='mongodb' |
MONGODB_DB_NAME |
Condicional | — | Obligatoria cuando DATABASE_TYPE='mongodb' |
Cuando
DATABASE_TYPE='mongodb', el servicio inicializa conexión real, crea índices de soporte y usa repositorios MongoDB enproducts,warehouseseinventory.
Puedes generar una API key de 32 bytes hex con Node.js:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"También puedes usar el script del proyecto:
pnpm run generate:api-keypnpm install
$env:API_KEY='local-api-key'
$env:DATABASE_TYPE='mongodb'
$env:MONGODB_URI='mongodb://localhost:27017'
$env:MONGODB_DB_NAME='inventory-service'
pnpm start:dev| Módulo | Endpoints |
|---|---|
system |
GET /api/v1, GET /api/v1/health |
products |
POST /api/v1/products, GET /api/v1/products, GET /api/v1/products/{productId}, PUT /api/v1/products/{productId}, PUT /api/v1/products/{productId}/images, GET /api/v1/products/{productId}/image-references, DELETE /api/v1/products/{productId} |
warehouses |
POST /api/v1/warehouses, GET /api/v1/warehouses, GET /api/v1/warehouses/{warehouseId}, PUT /api/v1/warehouses/{warehouseId}, DELETE /api/v1/warehouses/{warehouseId} |
inventory |
POST /api/v1/inventory/entries, POST /api/v1/inventory/exits, POST /api/v1/inventory/adjustments, GET /api/v1/inventory/lots/{lotId}, GET /api/v1/inventory/products/{productId}, GET /api/v1/inventory/products/{productId}/availability, GET /api/v1/inventory/movements |
curl -H "api_key: local-api-key" http://localhost:3000/api/v1/health{
"data": {},
"meta": {
"requestId": "req_a1b2c3d4e5f6"
}
}{
"error": {
"code": "MISSING_API_KEY",
"message": "El header api_key es obligatorio para consumir la API pública.",
"details": []
},
"meta": {
"requestId": "req_a1b2c3d4e5f6",
"timestamp": "2026-04-11T12:00:00.000Z"
}
}Si el header existe pero no coincide con la configuración, el servicio responde 401 con el código INVALID_API_KEY.
| Comando | Propósito |
|---|---|
pnpm start:dev |
Arranque en desarrollo con watch |
pnpm build |
Compilación de producción |
pnpm lint |
Revisión de estilo con ESLint |
pnpm test |
Pruebas unitarias |
pnpm test:e2e |
Pruebas end-to-end |
pnpm test:cov |
Cobertura |
pnpm release |
Publica una nueva versión con semantic-release (solo en CI) |
docs/README.md— resumen técnico del estado actualdocs/architecture/project-architecture-blueprint.md— blueprint arquitectónico y diagramadocs/guides/como-extender-inventory-service.md— guía para ampliar el servicio sin romper la arquitecturadocs/adr/— decisiones arquitectónicas registradas
DATABASE_TYPE='in-memory'sigue siendo útil para bootstrap y pruebas rápidas, pero no ofrece durabilidad- No existe todavía autenticación por usuarios/roles; la protección actual es técnica por
api_key - Las integraciones externas reales con orquestadores aún están pendientes