.
This commit is contained in:
parent
9e9ddcceb3
commit
0065c4d4d3
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -53,7 +53,7 @@
|
||||
"command": "pnpm run dev --filter=server",
|
||||
"skipFiles": ["<node_internals>/**"],
|
||||
"env": {
|
||||
"NODE_OPTIONS": "--inspect"
|
||||
"NODE_OPTIONS": "--inspect=0"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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);
|
||||
}
|
||||
};
|
||||
@ -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<string, any> = new Map();
|
||||
const initializedModels = new Set<string>();
|
||||
@ -8,22 +7,23 @@ const initializedModels = new Set<string>();
|
||||
/**
|
||||
* 🔹 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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 <CTRL> + C at any time");
|
||||
|
||||
@ -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<ContactsService>("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: () => {},
|
||||
/*...*/
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user