Apariencia
ZModule
api/index.ts exporta por defecto un ZModule (api/src/modules/types.ts). El cargador lo importa desde api/index.mjs, comprueba que manifest.key coincide con la clave del plugin y registra sus permisos.
ts
import type { ZModule } from "@host/modules/types";
const notas: ZModule = {
name: "notas",
manifest: { key: "notas", title: trKey("Notas"), description: trKey("…"), category: "operacion", icon: "message", defaultEnabled: false },
permissionGroups: [/* … */],
routes: async (app) => {/* … */},
jobs: {/* … */},
schedules: [/* … */],
domainHandlers: {/* … */},
hooks: {/* … */},
};
export default notas;Campos de ZModule
| Campo | Tipo | Para qué |
|---|---|---|
name | texto | Nombre interno del módulo (convención: la clave). |
manifest | OptionalModuleManifest | Ficha del módulo opcional. Obligatoria en un plugin: sin ella el módulo sería parte del núcleo. |
routes | (app: FastifyInstance) => Promise<void> | Plugin de Fastify. Se monta bajo /api/v1: escribe /notas, no /api/v1/notas. |
jobs | Record<tipo, (payload, job) => Promise<void>> | Manejadores de la cola. Ver Jobs y schedules. |
schedules | Schedule[] | Tareas periódicas del worker. |
domainHandlers | Partial<Record<DomainEventName, handler | handler[]>> | Reacciones a eventos de dominio. |
hooks | Record<nombre, handler | handler[]> | Respuestas a ganchos que llama el núcleo. |
permissionGroups | PluginPermissionGroup[] | Grupos de permisos propios. Ver Permisos. |
seeds | Seed[] | Semillas estructurales para los scripts de siembra del host. En un plugin, los datos iniciales van en la migración SQL. |
manifest (OptionalModuleManifest)
| Campo | Tipo | Descripción |
|---|---|---|
key | texto | Igual que plugin.json → key. |
title | trKey(texto) | Nombre visible. La clave es el texto en español. |
description | trKey(texto) | Una frase en lenguaje llano. |
category | operacion | cliente | finanzas | marketing | analisis | cumplimiento | Agrupa las tarjetas del Marketplace. |
icon | texto | Nombre de icono del admin. |
defaultEnabled | booleano | Estado en una instalación que nunca lo ha tocado. En un módulo nuevo, normalmente false (opt-in). |
dependsOn | string[] | Claves de otros módulos opcionales que deben estar activos para encender este. Si es un plugin, también va en requires. |
permissions | Permission[] | Informativo para el catálogo. |
gateRoutes | booleano | Por defecto true: todas las rutas responden 404 MODULE_DISABLED con el módulo apagado. false es solo para módulos anteriores al marco. |
Textos: trKey
Los textos de la API se escriben con trKey("texto en español") (@host/lib/i18n): la clave es el propio texto, como en el resto de la API. En una notificación o en un manejador que conoce el idioma del destinatario se usa trFor(locale, texto, params).
Gate del módulo
Con manifest, todas las rutas del plugin responden 404 MODULE_DISABLED mientras el módulo esté apagado (hook preHandler en api/src/app.ts). Una ruta que debe responder siempre lleva config: { moduleGate: false }. Las tareas periódicas de un módulo apagado se saltan solas, salvo las marcadas runWhenDisabled.
Para consultar el estado desde código: isModuleEnabled(db, "clave"), assertModuleEnabled, requireModule y skipIfModuleDisabled (@host/lib/modules). Una clave que no es del núcleo ni de ningún módulo cargado (un plugin sin instalar) devuelve false.
Tablas propias
El host no conoce las tablas del plugin. Se tipan dentro del plugin (api/tables.ts) y se accede a ellas con un cast documentado: ver el paso de la API en la guía.
Exportaciones con nombre
Además del export default, api/index.ts puede exportar con nombre lo que otros plugins consumen con @plugin/<clave> (siempre que lo declaren en requires), y el estado interno que los tests necesiten alcanzar por globalThis.__HURY_PLUGINS__[clave].