migrateOptionalPhoneIndex.js

Overview

Este archivo define una migración puntual para el índice de User.phone. Su objetivo es adaptar el esquema de índices a la fase de Google Auth, donde una cuenta puede no traer teléfono.

La migración revisa la colección de User, detecta el índice legacy phone_1 sin partialFilterExpression y lo elimina. El comentario del archivo indica que Mongoose recreará el índice correcto en la siguiente conexión, sin tocar documentos existentes.

[!IMPORTANT] El script no modifica ningún documento. Solo elimina un índice de MongoDB cuando encuentra la variante legacy exacta.

[!NOTE] El archivo usa import.meta.url y process.argv[1] para distinguir entre importación y ejecución directa.

How it works

flowchart TD
    a1[Archivo migrateOptionalPhoneIndex js]
    b1[Comprueba ejecucion directa]
    c1[Carga dotenv]
    d1[Define MONGO_URI]
    e1[Conecta con mongoose]
    f1[runMigrateOptionalPhoneIndex]
    g1[User collection]
    h1[Lee indexes]
    i1[Busca phone_1 legacy]
    j1[Elimina el indice legacy]
    k1[Devuelve dropped false]
    l1[Imprime summary JSON]
    m1[Desconecta mongoose]

    a1 --> b1
    b1 --> c1
    c1 --> d1
    d1 --> e1
    e1 --> f1
    f1 --> g1
    g1 --> h1
    h1 --> i1
    i1 -->|Si| j1
    i1 -->|No| k1
    j1 --> l1
    k1 --> l1
    l1 --> m1

Cuando el archivo se ejecuta como módulo principal, entra en el bloque CLI. Primero carga variables de entorno con dotenv. Después resuelve MONGO_URI y conecta con mongoose.

Luego llama a runMigrateOptionalPhoneIndex(). Esa función inspecciona los índices de User.collection, busca phone_1 sin partialFilterExpression y decide si debe borrarlo. Al final, el script imprime el resumen en JSON y cierra la conexión.

  • El índice debe llamarse phone_1.
  • No debe tener partialFilterExpression.
  • Si el índice ya es parcial, no se borra.
  • Si el índice no existe, tampoco se hace ningún cambio.

Key components

{
    "title": "runMigrateOptionalPhoneIndex",
    "content": "Funci\u00f3n p\u00fablica que inspecciona los \u00edndices de User.collection, elimina el \u00edndice legacy phone_1 sin partialFilterExpression y devuelve un resumen con dropped y reason.",
    "type": "function",
    "filePath": "services/api/src/scripts/migrateOptionalPhoneIndex.js",
    "badges": [
        "public"
    ]
}

Además de la función exportada, el archivo usa estos componentes:

  • User desde ../models/User.js — aporta User.collection, que es la colección inspeccionada.
  • mongoose — gestiona la conexión, el listado de índices y la eliminación del índice.
  • dotenv — carga variables de entorno para la ejecución directa.
  • path y fileURLToPath — resuelven la ruta del archivo y permiten localizar ../../.env.

Data & fields

Variables de ejecución

[
    {
        "name": "process.argv[1]",
        "type": "string",
        "required": true,
        "description": "Se usa para detectar si el archivo se ejecuta como módulo principal."
    },
    {
        "name": "__dirname",
        "type": "string",
        "required": true,
        "description": "Directorio del script. Sirve para resolver la ruta de ../../.env."
    },
    {
        "name": "MONGODB_URI",
        "type": "string",
        "description": "URI de MongoDB. Si falta, usa mongodb://127.0.0.1:27017/plano_backoffice."
    }
]

Resultado de la migración

[
    {
        "name": "dropped",
        "type": "boolean",
        "required": true,
        "description": "Indica si se eliminó el índice legacy."
    },
    {
        "name": "reason",
        "type": "string",
        "required": true,
        "description": "Mensaje de estado devuelto por la migración."
    }
]
  • phone_1 ya es parcial o no existe
  • phone_1 legacy (no-sparse) eliminado; Mongoose lo recrea como parcial

Behaviors

  • runMigrateOptionalPhoneIndex [badge:public] — obtiene User.collection.indexes(), identifica el índice phone_1 legacy y, si corresponde, ejecuta collection.dropIndex('phone_1').
  • Bloque isMainModule — carga ../../.env, vuelve a ejecutar dotenv.config(), resuelve MONGO_URI, conecta con MongoDB, ejecuta la migración, imprime el resumen y cierra la conexión.
  • Manejo de errores del CLI — si falla el flujo principal, imprime [migrateOptionalPhoneIndex] fatal: con el mensaje del error y asigna process.exitCode = 1.

Workflows

1. Detectar ejecución directa | El script compara `path.resolve(process.argv[1])` con la URL del propio archivo.
2. Cargar entorno | Primero carga `../../.env` y después ejecuta `dotenv.config()` con la configuración por defecto.
3. Abrir conexión | Usa `MONGODB_URI` o el valor `mongodb://127.0.0.1:27017/plano_backoffice`.
4. Revisar índices | `runMigrateOptionalPhoneIndex()` consulta `User.collection.indexes()`.
5. Eliminar el índice legacy | Si existe `phone_1` sin `partialFilterExpression`, ejecuta `dropIndex('phone_1')`.
6. Emitir resultado | El script imprime el resumen en JSON.
7. Cerrar conexión | En `finally`, ejecuta `mongoose.disconnect()`.

Gotchas & edge cases

[!WARNING] Si phone_1 ya es parcial, o si no existe, la función no hace cambios. En ese caso devuelve dropped: false.

[!IMPORTANT] La desconexión de mongoose ocurre dentro de finally. La conexión se cierra incluso si la migración falla.

[!NOTE] El archivo no modifica el campo phone de ningún usuario. Solo actúa sobre metadata de índices.

  • ../models/User.js — proporciona User.collection, que es la base real de la migración.
  • mongoose — expone connect, disconnect, collection.indexes() y collection.dropIndex().
  • dotenv — carga variables de entorno en la ruta de ejecución directa.
  • MongoDB — almacena el índice phone_1 que esta migración inspecciona y elimina cuando corresponde.