diff --git a/.vscode/launch.json b/.vscode/launch.json index d5e60c9..43ee7d8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -53,7 +53,7 @@ "command": "pnpm run dev --filter=server", "skipFiles": ["/**"], "env": { - "NODE_OPTIONS": "--inspect" + "NODE_OPTIONS": "--inspect=0" } } ] diff --git a/apps/server/src/app.ts b/apps/server/src/app.ts index fa2a3a8..44e453e 100644 --- a/apps/server/src/app.ts +++ b/apps/server/src/app.ts @@ -44,9 +44,6 @@ export function createApp(): Application { next(); }); - // Registrar rutas de la API - // app.use("/api/v1", v1Routes()); - // Gestión global de errores. // Siempre al final de la cadena de middlewares // y después de las rutas. diff --git a/apps/server/src/config/register-models.ts b/apps/server/src/config/register-models.ts deleted file mode 100644 index 471fda8..0000000 --- a/apps/server/src/config/register-models.ts +++ /dev/null @@ -1,66 +0,0 @@ -import * as glob from "glob"; -import * as path from "path"; -import { DataTypes } from "sequelize"; -import { sequelize } from "./database"; -import { logger } from "@rdx/logger"; - -/** - * 🔹 Registra todos los modelos en Sequelize - */ -export const registerModels = async () => { - const cwd = path.resolve(`${__dirname}/../`); - const models: { [key: string]: any } = {}; - - // Opciones para buscar los modelos - const globOptions = { - cwd, - nocase: true, - nodir: true, - absolute: false, - }; - - try { - logger.info(`🔎 Searching models in: ${cwd}`); - - // Buscamos los ficheros que terminen en .model.js o .model.ts - glob.sync("**/*.model.{js,ts}", globOptions).forEach((file) => { - //logger.info(`📄 File >> ${file}...`); - const modelDef = require(path.join(file)).default; - const model = typeof modelDef === "function" ? modelDef(sequelize, DataTypes) : false; - - if (model) { - models[model.name] = model; - logger.info(`🔸 Model >> ${model.name} (${file})`); - } else { - logger.info(`🚫 No model`); - } - }); - - // Asociaciones y hooks de los modelos, si existen - for (const modelName in models) { - const model = models[modelName]; - if (model.associate) { - model.associate(sequelize, models); - } - if (model.hooks) { - model.hooks(sequelize); - } - } - } catch (error) { - logger.error("❌ Error registering models:", error); - process.exit(1); - } - - try { - // Sincronizamos DB en modo desarrollo - if (process.env.NODE_ENV !== "production") { - await sequelize.sync({ force: false, alter: true }); - logger.info(`✔️${" "}Database synchronized successfully.`); - } else { - logger.warning("⚠️ Running in production mode - Skipping database sync."); - } - } catch (error) { - logger.error("❌ Error synchronizing database:", error); - process.exit(1); - } -}; diff --git a/apps/server/src/core/helpers/model-loader.ts b/apps/server/src/core/helpers/model-loader.ts index d3ce598..eb58f4d 100644 --- a/apps/server/src/core/helpers/model-loader.ts +++ b/apps/server/src/core/helpers/model-loader.ts @@ -1,6 +1,5 @@ import { logger } from "@rdx/logger"; -import { ModelInitializer } from "@rdx/modules"; -import { Sequelize } from "sequelize"; +import { ModelInitializer, ModuleParams } from "@rdx/modules"; const registeredModels: Map = new Map(); const initializedModels = new Set(); @@ -8,22 +7,23 @@ const initializedModels = new Set(); /** * 🔹 Registra todos los modelos en Sequelize */ -export const registerModel = (models: ModelInitializer[], database: Sequelize) => { +export const registerModel = (models: ModelInitializer[], params: ModuleParams) => { for (const initModelFn of models) { - const model = initModelFn(database); + const model = initModelFn(); if (model) { registeredModels.set(model.name, model); } } }; -export const initModels = async (sequelize: Sequelize) => { - registeredModels.forEach((_, name) => loadModel(name, sequelize)); +export const initModels = async (params: ModuleParams) => { + registeredModels.forEach((_, name) => loadModel(name, params)); try { // Sincronizamos DB en modo desarrollo + const { database } = params; if (process.env.NODE_ENV !== "production") { - await sequelize.sync({ force: false, alter: true }); + await database.sync({ force: false, alter: true }); logger.info(`✔️${" "}Database synchronized successfully.`); } else { logger.warning("⚠️ Running in production mode - Skipping database sync."); @@ -34,19 +34,21 @@ export const initModels = async (sequelize: Sequelize) => { } }; -export const loadModel = (name: string, sequelize: Sequelize) => { +export const loadModel = (name: string, params: ModuleParams) => { if (initializedModels.has(name)) return; const model = registeredModels.get(name); if (!model) throw new Error(`❌ Model "${name}" not found.`); + const { database } = params; + // Asociaciones y hooks de los modelos, si existen if (model.associate) { - model.associate(sequelize); + model.associate(database); } if (model.hooks) { - model.hooks(sequelize); + model.hooks(database); } initializedModels.add(name); diff --git a/apps/server/src/core/helpers/module-loader.ts b/apps/server/src/core/helpers/module-loader.ts index 5e9b999..8e99687 100644 --- a/apps/server/src/core/helpers/module-loader.ts +++ b/apps/server/src/core/helpers/module-loader.ts @@ -1,7 +1,5 @@ import { logger } from "@rdx/logger"; -import { IModuleServer } from "@rdx/modules"; -import { Application } from "express"; -import { Sequelize } from "sequelize"; +import { IModuleServer, ModuleParams } from "@rdx/modules"; import { initModels, registerModel } from "./model-loader"; import { registerService } from "./service-registry"; @@ -15,14 +13,14 @@ export function registerModule(pkg: IModuleServer) { registeredModules.set(pkg.metadata.name, pkg); } -export function initModules(app: Application, database: Sequelize) { +export function initModules(params: ModuleParams) { registeredModules.forEach((_, name) => { - loadModule(name, app, database); + loadModule(name, params); }); - initModels(database); + initModels(params); } -const loadModule = (name: string, app: Application, database: Sequelize) => { +const loadModule = (name: string, params: ModuleParams) => { if (initializedModules.has(name)) return; const pkg = registeredModules.get(name); @@ -30,16 +28,16 @@ const loadModule = (name: string, app: Application, database: Sequelize) => { // Resolver dependencias primero const deps = pkg.metadata.dependencies || []; - deps.forEach((dep) => loadModule(dep, app, database)); + deps.forEach((dep) => loadModule(dep, params)); // Inicializar el module - pkg.init(app); + pkg.init(params); - const pkgApi = pkg.registerDependencies?.(); + const pkgApi = pkg.registerDependencies?.(params); // Registrar modelos de Sequelize, si los expone if (pkgApi?.models) { - registerModel(pkgApi.models, database); + registerModel(pkgApi.models, params); } // Registrar sus servicios, si los expone diff --git a/apps/server/src/index.ts b/apps/server/src/index.ts index acf4591..b8e62eb 100644 --- a/apps/server/src/index.ts +++ b/apps/server/src/index.ts @@ -3,7 +3,7 @@ import http from "http"; import { DateTime } from "luxon"; import { createApp } from "./app"; import { ENV } from "./config"; -import { connectToDatabase, sequelize } from "./config/database"; +import { connectToDatabase, sequelize as database } from "./config/database"; import { initModules } from "./core/helpers"; import { registerModules } from "./modules"; @@ -68,11 +68,12 @@ const serverConnection = (conn: any) => { //const sequelizeConn = createSequelizeAdapter(); //const firebirdConn = createFirebirdAdapter(); -// Registrar paquetes de la aplicación registerModules(); const app = createApp(); +// Registrar paquetes de la aplicación + // Crea el servidor HTTP const server = http .createServer(app) @@ -125,7 +126,7 @@ process.on("uncaughtException", (error: Error) => { // initStructure(sequelizeConn.connection); // insertUsers(); - initModules(app, sequelize); + initModules({ app, database: database, baseRoutePath: "/api/v1" }); server.listen(currentState.port, () => { logger.info("To shut down your server, press + C at any time"); diff --git a/modules/invoices/src/server/index.ts b/modules/invoices/src/server/index.ts index ba29ee5..a1acc10 100644 --- a/modules/invoices/src/server/index.ts +++ b/modules/invoices/src/server/index.ts @@ -1,8 +1,7 @@ /* import { getService } from "@apps/server/src/core/service-registry"; */ import { logger } from "@rdx/logger"; -import { IModuleServer } from "@rdx/modules"; -import { Application } from "express"; -import { initInvoiceModel } from "./intrastructure"; +import { IModuleServer, ModuleParams } from "@rdx/modules"; +import { initInvoiceModel, invoicesRouter } from "./intrastructure"; export const invoicesModule: IModuleServer = { metadata: { @@ -10,15 +9,16 @@ export const invoicesModule: IModuleServer = { version: "1.0.0", dependencies: [], }, - init(app: Application) { + init(params: ModuleParams) { // const contacts = getService("contacts"); - //invoicesRouter(app); - logger.info("🚀 Invoices module initialized"); + invoicesRouter(params); + logger.info({ message: "🚀 Invoices module initialized", label: "invoices" }); }, - registerDependencies() { - logger.info("🚀 Invoices module dependencies registered"); + registerDependencies(params) { + const { database } = params; + logger.info({ message: "🚀 Invoices module dependencies registered", label: "invoices" }); return { - models: [(sequelize) => initInvoiceModel(sequelize)], + models: [() => initInvoiceModel(database)], services: { getInvoice: () => {}, /*...*/ diff --git a/modules/invoices/src/server/intrastructure/express/invoices.routes.ts b/modules/invoices/src/server/intrastructure/express/invoices.routes.ts index 65fadd5..463584b 100644 --- a/modules/invoices/src/server/intrastructure/express/invoices.routes.ts +++ b/modules/invoices/src/server/intrastructure/express/invoices.routes.ts @@ -1,4 +1,3 @@ -import { Express } from "express"; import { buildGetInvoiceController, buildListInvoicesController, @@ -7,10 +6,17 @@ import { import { buildCreateInvoiceController } from "#/server/presentation/controllers/create-invoice"; import { validateAndParseBody } from "@rdx/core"; -import { NextFunction, Request, Response, Router } from "express"; +import { ModuleParams } from "@rdx/modules"; +import { Application, NextFunction, Request, Response, Router } from "express"; import { Sequelize } from "sequelize"; -export const invoicesRouter = (app: Express, database: Sequelize) => { +export const invoicesRouter = (params: ModuleParams) => { + const { app, database, baseRoutePath } = params as { + app: Application; + database: Sequelize; + baseRoutePath: string; + }; + const routes: Router = Router({ mergeParams: true }); routes.get( @@ -62,5 +68,5 @@ export const invoicesRouter = (app: Express, database: Sequelize) => { } );*/ - app.use("/invoices", routes); + app.use(`${baseRoutePath}/invoices`, routes); }; diff --git a/packages/rdx-modules/src/module-server.interface.ts b/packages/rdx-modules/src/module-server.interface.ts index 9c41ad5..f22e6c7 100644 --- a/packages/rdx-modules/src/module-server.interface.ts +++ b/packages/rdx-modules/src/module-server.interface.ts @@ -1,10 +1,9 @@ //Contrato para los Modules backend (Node.js) -import { Application } from "express"; -import { ModuleDependencies, ModuleMetadata } from "./types"; +import { ModuleDependencies, ModuleMetadata, ModuleParams } from "./types"; export interface IModuleServer { metadata: ModuleMetadata; - init(app: Application): void; - registerDependencies?(): ModuleDependencies; + init(params: ModuleParams): void; + registerDependencies?(params: ModuleParams): ModuleDependencies; } diff --git a/packages/rdx-modules/src/types.ts b/packages/rdx-modules/src/types.ts index 2250fc9..dc65d52 100644 --- a/packages/rdx-modules/src/types.ts +++ b/packages/rdx-modules/src/types.ts @@ -1,8 +1,10 @@ // Contiene tipos comunes entre cliente y servidor -import { Sequelize } from "sequelize"; +export type ModuleParams = { + [key: string]: any; +}; -export type ModelInitializer = (sequelize: Sequelize) => any; +export type ModelInitializer = () => any; export interface ModuleMetadata { name: string;