services/api/package.json

Overview

Este archivo define el manifiesto del backend API de la plataforma Somos Plano. Declara el nombre del paquete, su tipo de módulos, el entrypoint principal y los scripts operativos para desarrollo, arranque, semillas, migraciones, mantenimiento y verificación.

También concentra las dependencias que sostienen la capa API. En el repositorio, ese arranque se conecta con src/server.js como punto de entrada y con src/app.js como composición de Express, donde se montan las rutas de negocio y el endpoint de salud.

[!IMPORTANT] El paquete está marcado como private y usa ES modules con "type": "module". Su entrada principal es src/server.js.

How it works

flowchart TB
    pkg[services api package json] --> meta[package metadata]
    pkg --> scripts[scripts]
    pkg --> deps[dependencies]
    pkg --> devdeps[dev dependencies]

    pkg --> main[src server js]
    main --> app[src app js]

    scripts --> dev[dev]
    scripts --> start[start]
    scripts --> seed[seed]
    scripts --> ops[migrations lifecycle digest match inventory recovery]
    scripts --> quality[test lint build]

    deps --> runtime[runtime stack]
    devdeps --> tooling[development tooling]

El manifiesto no ejecuta lógica de negocio por sí mismo. Su función es coordinar cómo se inicia el backend y qué herramientas lo acompañan. dev y start apuntan a src/server.js, mientras que seed ejecuta src/scripts/seed.js.

La composición real del servidor vive en src/app.js. Ese archivo importa y monta rutas como auth, public, uploads, listings, campaigns, match, conversations, contact-gate, payments, leads, listing-events, listing-likes y listing-comments, además del health check /api/health.

Key components

Este manifiesto tiene pocos campos estructurales, pero todos son operativos. Los más importantes son el main, los scripts y las dependencias de ejecución.

  • name — Identifica el paquete como plano-api.
  • version — Fija la versión actual en 0.0.1.
  • private — Marca el paquete como no publicable.
  • type — Declara el uso de módulos ES.
  • main — Define src/server.js como entrypoint.
  • scripts — Reúne los comandos de desarrollo, mantenimiento, pruebas y validación.
  • dependencies — Declara las librerías usadas en tiempo de ejecución.
  • devDependencies — Declara las herramientas de desarrollo.

Data & fields

El manifiesto está compuesto por metadatos del paquete, scripts operativos y dos grupos de dependencias. Los valores definidos aquí controlan cómo se arranca, cómo se valida y qué capacidades externas están disponibles para la API.

[
    {
        "name": "name",
        "type": "string",
        "required": true,
        "description": "Nombre del paquete. El valor es plano-api."
    },
    {
        "name": "version",
        "type": "string",
        "required": true,
        "description": "Versión del paquete. El valor es 0.0.1."
    },
    {
        "name": "private",
        "type": "boolean",
        "required": true,
        "description": "Marca el paquete como privado."
    },
    {
        "name": "type",
        "type": "string",
        "required": true,
        "description": "Indica que el proyecto usa módulos ES."
    },
    {
        "name": "main",
        "type": "string",
        "required": true,
        "description": "Archivo principal del paquete. El valor es src/server.js."
    },
    {
        "name": "scripts",
        "type": "object",
        "required": true,
        "description": "Comandos npm disponibles para desarrollo, mantenimiento, pruebas y validación.",
        "children": [
            {
                "name": "dev",
                "type": "string",
                "required": true,
                "description": "Ejecuta nodemon src/server.js."
            },
            {
                "name": "start",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/server.js."
            },
            {
                "name": "seed",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/seed.js."
            },
            {
                "name": "migrate:legacy-admin",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/migrateLegacyAdmin.js."
            },
            {
                "name": "migrate:public-users",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/migratePublicUsers.js."
            },
            {
                "name": "migrate:legacy-email-verification",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/migrateLegacyEmailVerification.js."
            },
            {
                "name": "migrate:optional-phone-index",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/migrateOptionalPhoneIndex.js."
            },
            {
                "name": "migrate:audit-orphan-listings",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/auditOrphanListings.js."
            },
            {
                "name": "lifecycle:anonymize",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/anonymizeExpiredAccounts.js."
            },
            {
                "name": "lifecycle:send-purge-warnings",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/sendPurgeWarnings.js."
            },
            {
                "name": "lifecycle:purge",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/purgeExpiredAccounts.js."
            },
            {
                "name": "lifecycle:purge-notification-outbox",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/purgeHistoricalNotificationOutbox.js."
            },
            {
                "name": "digest:send-listing-performance",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/sendListingPerformanceDigests.js."
            },
            {
                "name": "match:preview",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/previewMatchForRequirement.js."
            },
            {
                "name": "inventory:deletions",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/inventoryDeletionState.js."
            },
            {
                "name": "recovery:pending-requirements",
                "type": "string",
                "required": true,
                "description": "Ejecuta node src/scripts/resumePendingRequirementDeletions.js."
            },
            {
                "name": "test",
                "type": "string",
                "required": true,
                "description": "Ejecuta node --test con concurrencia 1."
            },
            {
                "name": "test:mongo",
                "type": "string",
                "required": true,
                "description": "Ejecuta node --test con concurrencia 1, timeout de 120000 y los tests integration/mongo/*.mongo.js."
            },
            {
                "name": "lint",
                "type": "string",
                "required": true,
                "description": "Ejecuta node --check sobre un conjunto fijo de archivos del backend."
            },
            {
                "name": "build",
                "type": "string",
                "required": true,
                "description": "Ejecuta npm run lint."
            }
        ]
    },
    {
        "name": "dependencies",
        "type": "object",
        "required": true,
        "description": "Paquetes usados en tiempo de ejecución.",
        "children": [
            {
                "name": "@imagekit/nodejs",
                "type": "string",
                "required": true,
                "description": "Cliente de ImageKit."
            },
            {
                "name": "altcha-lib",
                "type": "string",
                "required": true,
                "description": "Librería para challenges y verificación de soluciones."
            },
            {
                "name": "bcryptjs",
                "type": "string",
                "required": true,
                "description": "Librería de hashing de contraseñas."
            },
            {
                "name": "cors",
                "type": "string",
                "required": true,
                "description": "Middleware de CORS."
            },
            {
                "name": "dotenv",
                "type": "string",
                "required": true,
                "description": "Carga variables de entorno."
            },
            {
                "name": "express",
                "type": "string",
                "required": true,
                "description": "Framework HTTP del backend."
            },
            {
                "name": "express-rate-limit",
                "type": "string",
                "required": true,
                "description": "Middleware de limitación de solicitudes."
            },
            {
                "name": "google-auth-library",
                "type": "string",
                "required": true,
                "description": "Cliente para autenticación de Google."
            },
            {
                "name": "jsonwebtoken",
                "type": "string",
                "required": true,
                "description": "Firma y verificación de JWT."
            },
            {
                "name": "mongoose",
                "type": "string",
                "required": true,
                "description": "Acceso y modelado sobre MongoDB."
            },
            {
                "name": "multer",
                "type": "string",
                "required": true,
                "description": "Procesamiento de cargas multipart."
            },
            {
                "name": "redis",
                "type": "string",
                "required": true,
                "description": "Cliente de Redis."
            },
            {
                "name": "resend",
                "type": "string",
                "required": true,
                "description": "Cliente de envío de correo."
            },
            {
                "name": "stripe",
                "type": "string",
                "required": true,
                "description": "Cliente de pagos de Stripe."
            },
            {
                "name": "twilio",
                "type": "string",
                "required": true,
                "description": "Cliente de comunicaciones de Twilio."
            },
            {
                "name": "yazl",
                "type": "string",
                "required": true,
                "description": "Creación de archivos ZIP."
            }
        ]
    },
    {
        "name": "devDependencies",
        "type": "object",
        "required": true,
        "description": "Herramientas de desarrollo.",
        "children": [
            {
                "name": "mongodb-memory-server",
                "type": "string",
                "required": true,
                "description": "Servidor MongoDB en memoria para entornos locales o de prueba."
            },
            {
                "name": "nodemon",
                "type": "string",
                "required": true,
                "description": "Recarga automática durante el desarrollo."
            }
        ]
    }
]

Behaviors

Este manifiesto define comportamientos operativos a través de scripts. No expone funciones JavaScript propias. Su papel es activar comandos concretos del backend.

Desarrollo y arranque

  • dev — inicia src/server.js con nodemon para desarrollo local.
  • start — inicia src/server.js con node directamente.
  • seed — ejecuta src/scripts/seed.js para carga inicial de datos.

Migraciones y mantenimiento

  • migrate:legacy-admin — ejecuta la migración de administradores heredados.
  • migrate:public-users — ejecuta la migración de usuarios públicos.
  • migrate:legacy-email-verification — ejecuta la migración de verificación de correo heredada.
  • migrate:optional-phone-index — ejecuta la migración del índice opcional de teléfono.
  • migrate:audit-orphan-listings — ejecuta la auditoría de listings huérfanos.
  • lifecycle:anonymize — ejecuta la anonimización de cuentas expiradas.
  • lifecycle:send-purge-warnings — ejecuta el envío de avisos de purge.
  • lifecycle:purge — ejecuta la purga de cuentas expiradas.
  • lifecycle:purge-notification-outbox — ejecuta la limpieza histórica del outbox de notificaciones.

Analítica, match y recuperación

  • digest:send-listing-performance — ejecuta el envío de digests de rendimiento de listings.
  • match:preview — ejecuta la previsualización de match para un requirement.
  • inventory:deletions — ejecuta el inventario del estado de borrados.
  • recovery:pending-requirements — ejecuta la reanudación de eliminaciones de requirements pendientes.

Verificación y calidad

  • test — usa el runner nativo de Node con una sola concurrencia.
  • test:mongo — ejecuta pruebas Mongo de integración con timeout ampliado.
  • lint — ejecuta node --check sobre un conjunto fijo de archivos del backend. El script cubre config, utils, middlewares, models, módulos y scripts.
  • build — reutiliza lint como validación final.

Workflows

1. Instalar dependencias | Ejecutar npm install dentro de services/api.
2. Arrancar desarrollo | Ejecutar npm run dev para iniciar src/server.js con nodemon.
3. Arrancar en modo directo | Ejecutar npm start para lanzar src/server.js con node.
4. Cargar datos iniciales | Ejecutar npm run seed para poblar el backend con el script declarado.
5. Ejecutar mantenimiento | Usar los scripts migrate:*, lifecycle:*, digest:*, match:*, inventory:* o recovery:* según la tarea.
6. Validar el código | Ejecutar npm test, npm run test:mongo, npm run lint o npm run build.

El flujo operativo está centrado en scripts explícitos. No hay un paso implícito de compilación. build solo delega a lint.

Gotchas & edge cases

[!WARNING] build no genera artefactos. Solo ejecuta npm run lint.

[!IMPORTANT] main apunta a src/server.js, no a src/app.js. La composición Express vive en src/app.js, que se importa desde el arranque.

[!NOTE] test:mongo usa una ruta concreta: integration/mongo/*.mongo.js. También fuerza --test-concurrency=1 y --test-timeout=120000.

[!WARNING] El script lint es sensible a un conjunto fijo de archivos. Si uno falla, la validación completa falla.

services/api/package.json conecta con el entrypoint real services/api/src/server.js, que arranca la base de datos y el servidor HTTP. También se relaciona con services/api/src/app.js, donde se montan las rutas de negocio y el endpoint de salud.

  • services/api/src/server.js — entrada principal del backend, declarada en main.
  • services/api/src/app.js — composición de Express y montaje de rutas.
  • services/api/src/scripts/seed.js — objetivo del script seed.
  • services/api/src/scripts/* — objetivos de migración, mantenimiento, digest, match, inventario y recuperación.
  • services/api/integration/mongo/*.mongo.js — objetivos del script test:mongo.
  • services/api/src/modules/* — módulos revisados por lint y cargados por src/app.js.