Compare commits

..

No commits in common. "416f1367aa57906b331a4a2f5e34a939be454f2e" and "0065c4d4d326268acb4761c046e87563e2ff82e2" have entirely different histories.

149 changed files with 1001 additions and 942 deletions

95
.vscode/launch.json vendored
View File

@ -2,66 +2,59 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "Attach to Turbo Server API (ts-node-dev)", "name": "Launch firefox localhost",
"type": "firefox",
"request": "launch",
"reAttach": true,
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}/client"
},
{
"name": "Launch Chrome localhost",
"type": "chrome",
"request": "launch",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}/client"
},
{
"type": "msedge",
"request": "launch",
"name": "CLIENT: Launch Edge against localhost",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}/client"
},
{
"type": "node", "type": "node",
"request": "attach", "request": "attach",
"port": 9229, "name": "Attach to ts-node-dev",
"port": 4321,
"restart": true, "restart": true,
"protocol": "inspector", "timeout": 10000,
"skipFiles": ["<node_internals>/**"],
"sourceMaps": true, "sourceMaps": true,
"outFiles": [ "resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"]
"${workspaceFolder}/apps/api/src/**/*.ts",
"${workspaceFolder}/modules/*/src/**/*.ts",
"${workspaceFolder}/packages/*/src/**/*.ts"
]
}, },
{ {
"name": "Turbo: debug server-side + modules + packages", "name": "Launch via YARN",
"type": "node",
"request": "launch", "request": "launch",
"program": "${workspaceFolder}/apps/server/src/index.ts", "runtimeArgs": ["run", "server"],
"runtimeArgs": ["-r", "ts-node/register"], "runtimeExecutable": "yarn",
"envFile": "${workspaceFolder}/apps/server/.env", "skipFiles": ["<node_internals>/**", "client/**", "dist/**", "doc/**"],
"type": "node"
},
{
"name": "Turbo: debug server-side",
"type": "node-terminal",
"request": "launch",
"command": "pnpm run dev --filter=server",
"skipFiles": ["<node_internals>/**"],
"env": { "env": {
"NODE_ENV": "development",
"NODE_OPTIONS": "--inspect=0" "NODE_OPTIONS": "--inspect=0"
}, }
"skipFiles": ["<node_internals>/**"],
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/apps/server/**/*.js",
"${workspaceFolder}/modules/**/dist/**/*.js",
"${workspaceFolder}/packages/**/dist/**/*.js"
],
"cwd": "${workspaceFolder}"
},
{
"name": "Debug Server",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/apps/server/src/index.ts",
"runtimeArgs": ["--require", "tsconfig-paths/register", "--inspect"],
"cwd": "${workspaceFolder}",
"outFiles": ["${workspaceFolder}/**/*.js"],
"sourceMaps": true,
"envFile": "${workspaceFolder}/apps/server/.env",
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": "Attach to Server",
"type": "node",
"request": "attach",
"port": 9229,
"restart": true,
"protocol": "inspector",
"skipFiles": ["<node_internals>/**"],
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/apps/server/dist/**/*.js",
"${workspaceFolder}/packages/*/dist/**/*.js",
"${workspaceFolder}/modules/*/dist/**/*.js"
]
} }
] ]
} }

View File

@ -1,6 +0,0 @@
{
"watch": ["../../packages", "../../modules", "src"],
"ext": "ts,js,json",
"ignore": ["dist", "node_modules"],
"exec": "ts-node -r tsconfig-paths/register src/index.ts"
}

View File

@ -6,8 +6,7 @@
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"clean": "rm -rf dist && rm -rf node_modules", "clean": "rm -rf dist && rm -rf node_modules",
"dev:2": "ts-node-dev --respawn --inspect --transpile-only --require tsconfig-paths/register src/index.ts", "dev": "nodemon --exec \"node -r esbuild-register ./src/index.ts\" -e .ts",
"dev": "nodemon --watch ../../packages --watch ../../modules --watch ./src --ext ts,js,json --exec ts-node-dev -r tsconfig-paths/register src/index.ts",
"lint": "tsc --noEmit && eslint \"src/**/*.ts*\" --max-warnings 0", "lint": "tsc --noEmit && eslint \"src/**/*.ts*\" --max-warnings 0",
"start": "node -r esbuild-register ./src/index.ts", "start": "node -r esbuild-register ./src/index.ts",
"test": "jest --detectOpenHandles" "test": "jest --detectOpenHandles"
@ -17,6 +16,10 @@
}, },
"dependencies": { "dependencies": {
"@rdx/core": "workspace:*", "@rdx/core": "workspace:*",
"@rdx/ddd-domain": "workspace:*",
"@rdx/logger": "workspace:*",
"@rdx/modules": "workspace:*",
"@rdx/utils": "workspace:*",
"@modules/invoices": "workspace:*", "@modules/invoices": "workspace:*",
"bcrypt": "^5.1.1", "bcrypt": "^5.1.1",
"body-parser": "^2.2.0", "body-parser": "^2.2.0",
@ -37,7 +40,7 @@
"path": "^0.12.7", "path": "^0.12.7",
"reflect-metadata": "^0.2.2", "reflect-metadata": "^0.2.2",
"response-time": "^2.3.3", "response-time": "^2.3.3",
"sequelize": "^6.37.5", "sequelize": "^6.37.7",
"zod": "^3.24.3" "zod": "^3.24.3"
}, },
"devDependencies": { "devDependencies": {
@ -69,8 +72,6 @@
"jest": "^29.7.0", "jest": "^29.7.0",
"nodemon": "^3.1.10", "nodemon": "^3.1.10",
"supertest": "^7.1.0", "supertest": "^7.1.0",
"tsconfig-paths": "^4.2.0",
"ts-node": "^10.9.2",
"typescript": "5.8.3" "typescript": "5.8.3"
} }
} }

View File

@ -1,4 +1,5 @@
import { globalErrorHandler, logger } from "@rdx/core"; import { globalErrorHandler } from "@rdx/core";
import { logger } from "@rdx/logger";
import dotenv from "dotenv"; import dotenv from "dotenv";
import express, { Application } from "express"; import express, { Application } from "express";
import helmet from "helmet"; import helmet from "helmet";

View File

@ -1,82 +1,48 @@
import { logger } from "@rdx/core"; import { logger } from "@rdx/logger";
import dotenv from "dotenv"; import dotenv from "dotenv";
import { Sequelize } from "sequelize"; import { Sequelize } from "sequelize";
dotenv.config(); dotenv.config();
let sequelizeInstance: Sequelize | null = null; export const sequelize = new Sequelize(
process.env.DB_NAME as string, // database
function getDatabase(): Sequelize { process.env.DB_USER as string, // username
if (sequelizeInstance) { process.env.DB_PASSWORD as string, // password
return sequelizeInstance; {
host: process.env.DB_HOST as string,
dialect: "mysql",
port: parseInt(process.env.DB_PORT || "3306", 10),
dialectOptions: {
multipleStatements: true,
dateStrings: true,
typeCast: true,
//timezone: "Z",
},
pool: {
max: 10,
min: 0,
acquire: 30000,
idle: 10000,
},
logQueryParameters: true,
logging: process.env.DB_LOGGING === "true" ? logger.debug : false,
define: {
charset: "utf8mb4",
collate: "utf8mb4_unicode_ci",
//freezeTableName: true,
underscored: true,
timestamps: true,
},
} }
);
sequelizeInstance = new Sequelize( export async function connectToDatabase(): Promise<void> {
process.env.DB_NAME as string,
process.env.DB_USER as string,
process.env.DB_PASSWORD as string,
{
host: process.env.DB_HOST as string,
dialect: "mysql",
port: parseInt(process.env.DB_PORT || "3306", 10),
dialectOptions: {
multipleStatements: true,
dateStrings: true,
typeCast: true,
},
pool: {
max: 10,
min: 0,
acquire: 30000,
idle: 10000,
},
logQueryParameters: true,
logging: process.env.DB_LOGGING === "true" ? logger.debug : false,
define: {
charset: "utf8mb4",
collate: "utf8mb4_unicode_ci",
underscored: true,
timestamps: true,
},
}
);
return sequelizeInstance;
}
export async function tryConnectToDatabase() {
const database = getDatabase();
if (!database) {
const error = new Error("❌ Database not found.");
logger.error({
message: error.message,
label: "tryConnectToDatabase",
});
throw error;
}
logger.info({ message: `🔸 Connecting to database...`, label: "tryConnectToDatabase" });
try { try {
await database.authenticate(); await sequelize.authenticate();
//await registerModels(); //await registerModels();
logger.info({ logger.info(`✔️${" "}Database connection established successfully.`);
message: `✔️${" "}Database connection established successfully.`,
label: "tryConnectToDatabase",
meta: {
host: process.env.DB_HOST,
port: process.env.DB_PORT,
database: process.env.DB_NAME,
user: process.env.DB_USER,
},
});
return database;
} catch (error) { } catch (error) {
logger.error({ logger.error("❌ Unable to connect to the database:", error);
message: `❌ Unable to connect to the database: ${(error as Error).message}`, process.exit(1);
error,
label: "tryConnectToDatabase",
});
throw error;
} }
} }

View File

@ -1,59 +1,56 @@
import { logger, ModuleParams } from "@rdx/core"; import { logger } from "@rdx/logger";
import { ModelInitializer, ModuleParams } from "@rdx/modules";
const allModelInitializers: any[] = []; const registeredModels: Map<string, any> = new Map();
const registeredModels: { [key: string]: any } = {}; const initializedModels = new Set<string>();
/** /**
* 🔹 Registra todos los modelos en Sequelize * 🔹 Registra todos los modelos en Sequelize
*/ */
export const registerModels = (models: any[], params?: ModuleParams) => { export const registerModel = (models: ModelInitializer[], params: ModuleParams) => {
allModelInitializers.push(...models); for (const initModelFn of models) {
const model = initModelFn();
if (model) {
registeredModels.set(model.name, model);
}
}
}; };
export const initModels = async (params: ModuleParams) => { export const initModels = async (params: ModuleParams) => {
logger.info({ message: `Init models...`, label: "initModels" }); registeredModels.forEach((_, name) => loadModel(name, params));
const { database } = params;
if (!database) {
const error = new Error("❌ Database not found.");
logger.error({
message: error.message,
label: "initModels",
});
throw error;
}
// Inicializar modelos
allModelInitializers.forEach((initializer) => {
const model = initializer(database);
registeredModels[model.name] = model;
logger.info({
message: `🔸 Model "${model.name}" registered (sequelize)`,
label: "registerModel",
});
});
// Configurar asociaciones
Object.values(registeredModels).forEach((model) => {
if (typeof model.associate === "function") {
model.associate(database);
}
});
try { try {
// Sincronizamos DB en modo desarrollo // Sincronizamos DB en modo desarrollo
const { database } = params;
if (process.env.NODE_ENV !== "production") { if (process.env.NODE_ENV !== "production") {
await database.sync({ force: false, alter: true }); await database.sync({ force: false, alter: true });
logger.info({ message: `✔️${" "}Database synchronized successfully.`, label: "initModels" }); logger.info(`✔️${" "}Database synchronized successfully.`);
} else { } else {
logger.warning({ logger.warning("⚠️ Running in production mode - Skipping database sync.");
message: "⚠️ Running in production mode - Skipping database sync.",
label: "initModels",
});
} }
} catch (err) { } catch (error) {
const error = err as Error; logger.error("❌ Error synchronizing database:", error);
logger.error({ message: "❌ Error synchronizing database:", error, label: "initModels" }); process.exit(1);
throw error;
} }
}; };
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(database);
}
if (model.hooks) {
model.hooks(database);
}
initializedModels.add(name);
logger.info(`🔸 Model "${model.name}" registered (sequelize)`);
};

View File

@ -1,5 +1,6 @@
import { IModuleServer, logger, ModuleParams } from "@rdx/core"; import { logger } from "@rdx/logger";
import { initModels, registerModels } from "./model-loader"; import { IModuleServer, ModuleParams } from "@rdx/modules";
import { initModels, registerModel } from "./model-loader";
import { registerService } from "./service-registry"; import { registerService } from "./service-registry";
const registeredModules: Map<string, IModuleServer> = new Map(); const registeredModules: Map<string, IModuleServer> = new Map();
@ -12,11 +13,11 @@ export function registerModule(pkg: IModuleServer) {
registeredModules.set(pkg.metadata.name, pkg); registeredModules.set(pkg.metadata.name, pkg);
} }
export async function initModules(params: ModuleParams) { export function initModules(params: ModuleParams) {
registeredModules.forEach((_, name) => { registeredModules.forEach((_, name) => {
loadModule(name, params); loadModule(name, params);
}); });
await initModels(params); initModels(params);
} }
const loadModule = (name: string, params: ModuleParams) => { const loadModule = (name: string, params: ModuleParams) => {
@ -36,7 +37,7 @@ const loadModule = (name: string, params: ModuleParams) => {
// Registrar modelos de Sequelize, si los expone // Registrar modelos de Sequelize, si los expone
if (pkgApi?.models) { if (pkgApi?.models) {
registerModels(pkgApi.models, params); registerModel(pkgApi.models, params);
} }
// Registrar sus servicios, si los expone // Registrar sus servicios, si los expone
@ -48,5 +49,5 @@ const loadModule = (name: string, params: ModuleParams) => {
} }
initializedModules.add(name); initializedModules.add(name);
logger.info({ message: `✅ Module "${name}" registered`, label: "loadModule" }); logger.info(`✅ Paquete "${name}" registrado.`);
}; };

View File

@ -1,10 +1,9 @@
import { logger } from "@rdx/core"; import { logger } from "@rdx/logger";
import http from "http"; import http from "http";
import { DateTime } from "luxon"; import { DateTime } from "luxon";
import os from "os";
import { createApp } from "./app"; import { createApp } from "./app";
import { ENV } from "./config"; import { ENV } from "./config";
import { tryConnectToDatabase } from "./config/database"; import { connectToDatabase, sequelize as database } from "./config/database";
import { initModules } from "./core/helpers"; import { initModules } from "./core/helpers";
import { registerModules } from "./modules"; import { registerModules } from "./modules";
@ -43,17 +42,13 @@ const serverStop = (server: http.Server) => {
// Manejo de errores al iniciar el servidor // Manejo de errores al iniciar el servidor
const serverError = (error: NodeJS.ErrnoException) => { const serverError = (error: NodeJS.ErrnoException) => {
logger.error({ logger.info(`⛔️ Server wasn't able to start properly.`);
message: `⛔️ Server wasn't able to start properly.`,
label: "serverError0",
error,
});
if (error.code === "EADDRINUSE") { if (error.code === "EADDRINUSE") {
logger.error({ message: error.message, error, label: "serverError1" }); logger.error(error.message);
//logger.error(`The port ${error.port} is already used by another application.`); //logger.error(`The port ${error.port} is already used by another application.`);
} else { } else {
logger.error({ message: error.message, error, label: "serverError2" }); logger.error(error);
} }
// Dependiendo de la criticidad, podrías forzar el proceso a salir // Dependiendo de la criticidad, podrías forzar el proceso a salir
@ -118,7 +113,7 @@ process.on("uncaughtException", (error: Error) => {
}); });
// Arranca el servidor si la conexión a la base de datos va bien // Arranca el servidor si la conexión a la base de datos va bien
(async () => { (async (app) => {
try { try {
const now = DateTime.now(); const now = DateTime.now();
logger.info(`Time: ${now.toLocaleString(DateTime.DATETIME_FULL)} ${now.zoneName}`); logger.info(`Time: ${now.toLocaleString(DateTime.DATETIME_FULL)} ${now.zoneName}`);
@ -126,45 +121,18 @@ process.on("uncaughtException", (error: Error) => {
logger.info(`Environment: ${currentState.environment}`); logger.info(`Environment: ${currentState.environment}`);
logger.info(`Process PID: ${process.pid}`); logger.info(`Process PID: ${process.pid}`);
await connectToDatabase();
// Lógica de inicialización de DB, si procede: // Lógica de inicialización de DB, si procede:
// initStructure(sequelizeConn.connection); // initStructure(sequelizeConn.connection);
// insertUsers(); // insertUsers();
const database = await tryConnectToDatabase(); initModules({ app, database: database, baseRoutePath: "/api/v1" });
await initModules({ app, database, baseRoutePath: "/api/v1" });
server.listen(currentState.port, () => { server.listen(currentState.port, () => {
server.emit("listening");
const networkInterfaces = os.networkInterfaces();
const addresses: string[] = [];
// Obtiene todas las direcciones IPv4
for (const interfaceName in networkInterfaces) {
const networkInterface = networkInterfaces[interfaceName];
if (networkInterface) {
for (const iface of networkInterface) {
if (iface.family === "IPv4" && !iface.internal) {
addresses.push(iface.address);
}
}
}
}
addresses.forEach((address) => {
logger.info(`⚡️ Server accessible at: http://${address}:${currentState.port}`);
});
logger.info(`Server started at: ${DateTime.now().toLocaleString(DateTime.DATETIME_FULL)}`);
logger.info(`Server PID: ${process.pid}`);
logger.info(
`Server launched in: ${DateTime.now().diff(currentState.launchedAt).toMillis()} ms`
);
logger.info(`Server path: ${currentState.appPath}`);
logger.info(`Server environment: ${currentState.environment}`);
logger.info("To shut down your server, press <CTRL> + C at any time"); logger.info("To shut down your server, press <CTRL> + C at any time");
logger.info(`⚡️ Server: http://${currentState.host}:${currentState.port}`);
}); });
} catch (error) { } catch (error) {
serverError(error as NodeJS.ErrnoException); serverError(error as NodeJS.ErrnoException);
} }
})(); })(app);

View File

@ -1,50 +1,9 @@
{ {
"extends": "@repo/typescript-config/base.json", "extends": "@repo/typescript-config/base.json",
"compilerOptions": { "compilerOptions": {
/* Basic Options */ "outDir": "./dist",
"target": "ES2022" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
"lib": ["ES2022", "dom"] /* Specify library files to be included in the compilation. */,
"allowJs": false /* Allow javascript files to be compiled. */,
"pretty": true,
// "checkJs": true, /* Report errors in .js files. */
"jsx": "preserve" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */,
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
"sourceMap": true /* Generates corresponding '.map' file. */,
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./dist/" /* Redirect output structure to the directory. */,
//"rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
// "composite": true, /* Enable project compilation */
"removeComments": true /* Do not emit comments to output. */,
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"skipLibCheck": false /* Skip type checking of declaration files. */,
"strict": true /* Enable all strict type-checking options. */,
"noImplicitAny": false /* Raise error on expressions and declarations with an implied 'any' type. */,
"strictNullChecks": true /* Enable strict null checks. */,
"strictFunctionTypes": true /* Enable strict checking of function types. */,
"strictPropertyInitialization": false /* Enable strict checking of property initialization in classes. */,
"noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
"noUnusedLocals": false /* Report errors on unused locals. */,
"noUnusedParameters": false /* Report errors on unused parameters. */,
"noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
/* Module Resolution Options */
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
//"baseUrl": "./" /* Base directory to resolve non-absolute module names. */,
"rootDir": "./src", "rootDir": "./src",
//"types": ["node", "jest"], "types": ["node", "jest"],
"baseUrl": "./", "baseUrl": "./",
"paths": { "paths": {

View File

@ -4,8 +4,8 @@
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev-disabled": "vite --clearScreen false", "dev": "vite --clearScreen false",
"build-disabled": "tsc && vite build", "build": "tsc && vite build",
"preview": "vite preview", "preview": "vite preview",
"lint": "eslint \"src/**/*.ts\"" "lint": "eslint \"src/**/*.ts\""
}, },

View File

@ -52,6 +52,10 @@
}, },
"dependencies": { "dependencies": {
"@rdx/core": "workspace:*", "@rdx/core": "workspace:*",
"@rdx/ddd-domain": "workspace:*",
"@rdx/logger": "workspace:*",
"@rdx/modules": "workspace:*",
"@rdx/utils": "workspace:*",
"bcrypt": "^5.1.1", "bcrypt": "^5.1.1",
"body-parser": "^2.2.0", "body-parser": "^2.2.0",
"cors": "^2.8.5", "cors": "^2.8.5",
@ -71,7 +75,7 @@
"path": "^0.12.7", "path": "^0.12.7",
"reflect-metadata": "^0.2.2", "reflect-metadata": "^0.2.2",
"response-time": "^2.3.3", "response-time": "^2.3.3",
"sequelize": "^6.37.5", "sequelize": "^6.37.7",
"zod": "^3.24.3" "zod": "^3.24.3"
} }
} }

View File

@ -1,4 +1,7 @@
import { ITransactionManager, logger, Result, UniqueID, UtcDate } from "@rdx/core"; import { ITransactionManager } from "@rdx/core";
import { UniqueID, UtcDate } from "@rdx/ddd-domain";
import { logger } from "@rdx/logger";
import { Result } from "@rdx/utils";
import { IInvoiceService, Invoice } from "../domain"; import { IInvoiceService, Invoice } from "../domain";
import { IInvoiceProps, InvoiceNumber, InvoiceSerie, InvoiceStatus } from "../domain"; import { IInvoiceProps, InvoiceNumber, InvoiceSerie, InvoiceStatus } from "../domain";

View File

@ -1,4 +1,7 @@
import { ITransactionManager, logger, Result, UniqueID } from "@rdx/core"; import { ITransactionManager } from "@rdx/core";
import { UniqueID } from "@rdx/ddd-domain";
import { logger } from "@rdx/logger";
import { Result } from "@rdx/utils";
import { IInvoiceService } from "../domain"; import { IInvoiceService } from "../domain";
export class DeleteInvoiceUseCase { export class DeleteInvoiceUseCase {

View File

@ -1,4 +1,7 @@
import { ITransactionManager, logger, Result, UniqueID } from "@rdx/core"; import { ITransactionManager } from "@rdx/core";
import { UniqueID } from "@rdx/ddd-domain";
import { logger } from "@rdx/logger";
import { Result } from "@rdx/utils";
import { IInvoiceService, Invoice } from "../domain"; import { IInvoiceService, Invoice } from "../domain";
export class GetInvoiceUseCase { export class GetInvoiceUseCase {

View File

@ -1,4 +1,6 @@
import { Collection, ITransactionManager, logger, Result } from "@rdx/core"; import { ITransactionManager } from "@rdx/core";
import { logger } from "@rdx/logger";
import { Collection, Result } from "@rdx/utils";
import { IInvoiceService, Invoice } from "../domain"; import { IInvoiceService, Invoice } from "../domain";
export class ListInvoicesUseCase { export class ListInvoicesUseCase {
@ -12,29 +14,7 @@ export class ListInvoicesUseCase {
try { try {
return await this.invoiceService.findInvoices(transaction); return await this.invoiceService.findInvoices(transaction);
} catch (error: unknown) { } catch (error: unknown) {
logger.error({ logger.error(error as Error);
//message: error as Error,
message: "hola",
label: "ListInvoicesUseCase",
});
// Aquí puedes manejar el error de manera más específica si es necesario
// Por ejemplo, puedes lanzar un error personalizado o registrar el error
// logger.error({ message: error, label: "ListInvoicesUseCase" });
// return Result.fail(new Error("Error al listar las facturas"));
// O simplemente devolver el error original
// return Result.fail(error as Error);
// Si el error es un Error de Sequelize, puedes manejarlo de manera diferente
// if (error instanceof SequelizeError) {
// return Result.fail(new Error("Error de base de datos"));
// }
// Si el error es un Error de Sequelize, puedes manejarlo de manera diferente
// if (error instanceof SequelizeError) {
// return Result.fail(new Error("Error de base de datos"));
// }
return Result.fail(error as Error); return Result.fail(error as Error);
} }
}); });

View File

@ -1,7 +1,7 @@
import { ITransactionManager } from "@rdx/core"; import { ITransactionManager } from "@rdx/core";
import { UniqueID } from "@rdx/core"; import { UniqueID } from "@rdx/ddd-domain";
import { logger } from "@rdx/logger"; import { logger } from "@rdx/logger";
import { Collection, Result } from "@rdx/core"; import { Collection, Result } from "@rdx/utils";
import { IInvoiceService, Invoice, InvoiceItem } from "../domain"; import { IInvoiceService, Invoice, InvoiceItem } from "../domain";
import { IInvoiceProps, InvoiceNumber, InvoiceStatus } from "../domain"; import { IInvoiceProps, InvoiceNumber, InvoiceStatus } from "../domain";

View File

@ -1,4 +1,5 @@
import { AggregateRoot, Collection, MoneyValue, Result, UniqueID, UtcDate } from "@rdx/core"; import { AggregateRoot, MoneyValue, UniqueID, UtcDate } from "@rdx/ddd-domain";
import { Collection, Result } from "@rdx/utils";
import { InvoiceCustomer, InvoiceItem, InvoiceItems } from "../entities"; import { InvoiceCustomer, InvoiceItem, InvoiceItems } from "../entities";
import { InvoiceNumber, InvoiceSerie, InvoiceStatus } from "../value-objects"; import { InvoiceNumber, InvoiceSerie, InvoiceStatus } from "../value-objects";

View File

@ -1,4 +1,5 @@
import { EmailAddress, Name, PostalAddress, Result, ValueObject } from "@rdx/core"; import { EmailAddress, Name, PostalAddress, ValueObject } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { PhoneNumber } from "libphonenumber-js"; import { PhoneNumber } from "libphonenumber-js";
import { InvoiceAddressType } from "../../value-objects"; import { InvoiceAddressType } from "../../value-objects";

View File

@ -1,4 +1,5 @@
import { DomainEntity, Name, Result, TINNumber, UniqueID } from "@rdx/core"; import { DomainEntity, Name, TINNumber, UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { InvoiceAddress } from "./invoice-address"; import { InvoiceAddress } from "./invoice-address";
export interface IInvoiceCustomerProps { export interface IInvoiceCustomerProps {

View File

@ -1,4 +1,4 @@
import { MoneyValue, Quantity } from "@rdx/core"; import { MoneyValue, Quantity } from "@rdx/ddd-domain";
import { InvoiceItemDescription } from "../../../value-objects"; import { InvoiceItemDescription } from "../../../value-objects";
import { InvoiceItem } from "../invoice-item"; import { InvoiceItem } from "../invoice-item";

View File

@ -1,4 +1,5 @@
import { DomainEntity, MoneyValue, Percentage, Quantity, Result, UniqueID } from "@rdx/core"; import { DomainEntity, MoneyValue, Percentage, Quantity, UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { InvoiceItemDescription } from "../../value-objects"; import { InvoiceItemDescription } from "../../value-objects";
export interface IInvoiceItemProps { export interface IInvoiceItemProps {

View File

@ -1,4 +1,4 @@
import { Collection } from "@rdx/core"; import { Collection } from "@rdx/utils";
import { InvoiceItem } from "./invoice-item"; import { InvoiceItem } from "./invoice-item";
export class InvoiceItems extends Collection<InvoiceItem> { export class InvoiceItems extends Collection<InvoiceItem> {

View File

@ -1,4 +1,5 @@
import { Collection, Result, UniqueID } from "@rdx/core"; import { UniqueID } from "@rdx/ddd-domain";
import { Collection, Result } from "@rdx/utils";
import { Invoice } from "../aggregates"; import { Invoice } from "../aggregates";
export interface IInvoiceRepository { export interface IInvoiceRepository {

View File

@ -1,4 +1,5 @@
import { Collection, Result, UniqueID } from "@rdx/core"; import { UniqueID } from "@rdx/ddd-domain";
import { Collection, Result } from "@rdx/utils";
import { IInvoiceProps, Invoice } from "../aggregates"; import { IInvoiceProps, Invoice } from "../aggregates";
export interface IInvoiceService { export interface IInvoiceService {

View File

@ -1,4 +1,5 @@
import { Collection, Result, UniqueID } from "@rdx/core"; import { UniqueID } from "@rdx/ddd-domain";
import { Collection, Result } from "@rdx/utils";
import { Transaction } from "sequelize"; import { Transaction } from "sequelize";
import { IInvoiceProps, Invoice } from "../aggregates"; import { IInvoiceProps, Invoice } from "../aggregates";
import { IInvoiceRepository } from "../repositories"; import { IInvoiceRepository } from "../repositories";

View File

@ -1,4 +1,5 @@
import { Result, ValueObject } from "@rdx/core"; import { ValueObject } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
interface IInvoiceAddressTypeProps { interface IInvoiceAddressTypeProps {
value: string; value: string;

View File

@ -1,4 +1,5 @@
import { Maybe, Result, ValueObject } from "@rdx/core"; import { ValueObject } from "@rdx/ddd-domain";
import { Maybe, Result } from "@rdx/utils";
import { z } from "zod"; import { z } from "zod";
interface IInvoiceItemDescriptionProps { interface IInvoiceItemDescriptionProps {

View File

@ -1,4 +1,5 @@
import { Result, ValueObject } from "@rdx/core"; import { ValueObject } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { z } from "zod"; import { z } from "zod";
interface IInvoiceNumberProps { interface IInvoiceNumberProps {

View File

@ -1,4 +1,5 @@
import { Maybe, Result, ValueObject } from "@rdx/core"; import { ValueObject } from "@rdx/ddd-domain";
import { Maybe, Result } from "@rdx/utils";
import { z } from "zod"; import { z } from "zod";
interface IInvoiceSerieProps { interface IInvoiceSerieProps {

View File

@ -1,4 +1,5 @@
import { Result, ValueObject } from "@rdx/core"; import { ValueObject } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
interface IInvoiceStatusProps { interface IInvoiceStatusProps {
value: string; value: string;

View File

@ -1,6 +1,7 @@
/* import { getService } from "@apps/server/src/core/service-registry"; */ /* import { getService } from "@apps/server/src/core/service-registry"; */
import { IModuleServer, ModuleParams, logger } from "@rdx/core"; import { logger } from "@rdx/logger";
import { invoicesRouter, models } from "./intrastructure"; import { IModuleServer, ModuleParams } from "@rdx/modules";
import { initInvoiceModel, invoicesRouter } from "./intrastructure";
export const invoicesModule: IModuleServer = { export const invoicesModule: IModuleServer = {
metadata: { metadata: {
@ -17,7 +18,7 @@ export const invoicesModule: IModuleServer = {
const { database } = params; const { database } = params;
logger.info({ message: "🚀 Invoices module dependencies registered", label: "invoices" }); logger.info({ message: "🚀 Invoices module dependencies registered", label: "invoices" });
return { return {
models, models: [() => initInvoiceModel(database)],
services: { services: {
getInvoice: () => {}, getInvoice: () => {},
/*...*/ /*...*/

View File

@ -1,7 +1,14 @@
import { ModuleParams } from "@rdx/core"; import {
buildGetInvoiceController,
buildListInvoicesController,
ICreateInvoiceRequestSchema,
} from "../../presentation";
import { buildCreateInvoiceController } from "#/server/presentation/controllers/create-invoice";
import { validateAndParseBody } from "@rdx/core";
import { ModuleParams } from "@rdx/modules";
import { Application, NextFunction, Request, Response, Router } from "express"; import { Application, NextFunction, Request, Response, Router } from "express";
import { Sequelize } from "sequelize"; import { Sequelize } from "sequelize";
import { buildGetInvoiceController, buildListInvoicesController } from "../../presentation";
export const invoicesRouter = (params: ModuleParams) => { export const invoicesRouter = (params: ModuleParams) => {
const { app, database, baseRoutePath } = params as { const { app, database, baseRoutePath } = params as {
@ -30,7 +37,7 @@ export const invoicesRouter = (params: ModuleParams) => {
} }
); );
/*routes.post( routes.post(
"/", "/",
validateAndParseBody(ICreateInvoiceRequestSchema, { sanitize: false }), validateAndParseBody(ICreateInvoiceRequestSchema, { sanitize: false }),
//checkTabContext, //checkTabContext,
@ -40,6 +47,7 @@ export const invoicesRouter = (params: ModuleParams) => {
} }
); );
/*
routes.put( routes.put(
"/:invoiceId", "/:invoiceId",
validateAndParseBody(IUpdateInvoiceRequestSchema), validateAndParseBody(IUpdateInvoiceRequestSchema),

View File

@ -1,14 +1,7 @@
import { Invoice, InvoiceItem, InvoiceItemDescription } from "#/server/domain"; import { Invoice, InvoiceItem, InvoiceItemDescription } from "#/server/domain";
import { import { ISequelizeMapper, MapperParamsType, SequelizeMapper } from "@rdx/core";
ISequelizeMapper, import { MoneyValue, Percentage, Quantity, UniqueID } from "@rdx/ddd-domain";
MapperParamsType, import { Result } from "@rdx/utils";
MoneyValue,
Percentage,
Quantity,
Result,
SequelizeMapper,
UniqueID,
} from "@rdx/core";
import { InferCreationAttributes } from "sequelize"; import { InferCreationAttributes } from "sequelize";
import { InvoiceItemCreationAttributes, InvoiceItemModel, InvoiceModel } from "../sequelize"; import { InvoiceItemCreationAttributes, InvoiceItemModel, InvoiceModel } from "../sequelize";

View File

@ -1,12 +1,7 @@
import { Invoice, InvoiceNumber, InvoiceSerie, InvoiceStatus } from "#/server/domain"; import { Invoice, InvoiceNumber, InvoiceSerie, InvoiceStatus } from "#/server/domain";
import { import { ISequelizeMapper, MapperParamsType, SequelizeMapper } from "@rdx/core";
ISequelizeMapper, import { UniqueID, UtcDate } from "@rdx/ddd-domain";
MapperParamsType, import { Result } from "@rdx/utils";
Result,
SequelizeMapper,
UniqueID,
UtcDate,
} from "@rdx/core";
import { InvoiceCreationAttributes, InvoiceModel } from "../sequelize"; import { InvoiceCreationAttributes, InvoiceModel } from "../sequelize";
import { InvoiceItemMapper } from "./invoice-item.mapper"; import { InvoiceItemMapper } from "./invoice-item.mapper";

View File

@ -1,9 +1,11 @@
import invoiceItemModelInit from "./invoice-item.model"; import { IInvoiceRepository } from "../../domain";
import invoiceModelInit from "./invoice.model"; import { invoiceRepository } from "./invoice.repository";
export * from "./invoice-item.model"; // exporta las clases, tipos export * from "./invoice-item.model";
export * from "./invoice.model"; export * from "./invoice.model";
export * from "./invoice.repository"; export * from "./invoice.repository";
// Array de inicializadores para que registerModels() lo use export const createInvoiceRepository = (): IInvoiceRepository => {
export const models = [invoiceItemModelInit, invoiceModelInit]; return invoiceRepository;
};

View File

@ -4,20 +4,25 @@ import {
InferAttributes, InferAttributes,
InferCreationAttributes, InferCreationAttributes,
Model, Model,
NonAttribute,
Sequelize, Sequelize,
} from "sequelize"; } from "sequelize";
import { InvoiceModel } from "./invoice.model";
export type InvoiceItemCreationAttributes = InferCreationAttributes< export type InvoiceItemCreationAttributes = InferCreationAttributes<InvoiceItemModel, {}> & {};
InvoiceItemModel,
{ omit: "invoice" }
>;
export class InvoiceItemModel extends Model< export class InvoiceItemModel extends Model<
InferAttributes<InvoiceItemModel>, InferAttributes<InvoiceItemModel>,
InferCreationAttributes<InvoiceItemModel, { omit: "invoice" }> InvoiceItemCreationAttributes
> { > {
static associate(connection: Sequelize) {
/*const { Invoice_Model, InvoiceItem_Model } = connection.models;
InvoiceItem_Model.belongsTo(Invoice_Model, {
as: "invoice",
foreignKey: "invoice_id",
onDelete: "CASCADE",
});*/
}
declare item_id: string; declare item_id: string;
declare invoice_id: string; declare invoice_id: string;
@ -42,20 +47,10 @@ export class InvoiceItemModel extends Model<
declare total_amount: CreationOptional<number>; declare total_amount: CreationOptional<number>;
declare total_scale: CreationOptional<number>; declare total_scale: CreationOptional<number>;
declare invoice: NonAttribute<InvoiceModel>; //declare invoice?: NonAttribute<InvoiceModel>;
static associate(database: Sequelize) {
/*const { Invoice_Model, InvoiceItem_Model } = connection.models;
InvoiceItem_Model.belongsTo(Invoice_Model, {
as: "invoice",
foreignKey: "invoice_id",
onDelete: "CASCADE",
});*/
}
} }
export default (database: Sequelize) => { export default (sequelize: Sequelize) => {
InvoiceItemModel.init( InvoiceItemModel.init(
{ {
item_id: { item_id: {
@ -158,7 +153,7 @@ export default (database: Sequelize) => {
}, },
}, },
{ {
sequelize: database, sequelize,
tableName: "invoice_items", tableName: "invoice_items",
defaultScope: {}, defaultScope: {},

View File

@ -13,10 +13,17 @@ export type InvoiceCreationAttributes = InferCreationAttributes<InvoiceModel, {
items?: InvoiceItemCreationAttributes[]; items?: InvoiceItemCreationAttributes[];
}; };
export class InvoiceModel extends Model< export class InvoiceModel extends Model<InferAttributes<InvoiceModel>, InvoiceCreationAttributes> {
InferAttributes<InvoiceModel>, static associate(connection: Sequelize) {
InferCreationAttributes<InvoiceModel, { omit: "items" }> const { InvoiceModel, InvoiceItemModel } = connection.models;
> {
InvoiceModel.hasMany(InvoiceItemModel, {
as: "items",
foreignKey: "invoice_id",
onDelete: "CASCADE",
});
}
declare id: string; declare id: string;
declare invoice_status: string; declare invoice_status: string;
@ -35,23 +42,14 @@ export class InvoiceModel extends Model<
declare total_amount: CreationOptional<number>; declare total_amount: CreationOptional<number>;
declare total_scale: CreationOptional<number>; declare total_scale: CreationOptional<number>;
// Relaciones // Relationships
declare items: NonAttribute<InvoiceItemModel[]>; declare items: NonAttribute<InvoiceItemModel[]>;
//declare customer: NonAttribute<InvoiceParticipant_Model[]>; //declare customer: NonAttribute<InvoiceParticipant_Model[]>;
static associate(database: Sequelize) {
const { InvoiceModel, InvoiceItemModel } = database.models;
InvoiceModel.hasMany(InvoiceItemModel, {
as: "items",
foreignKey: "invoice_id",
onDelete: "CASCADE",
});
}
} }
export default (database: Sequelize) => { const initInvoiceModel = (sequelize: Sequelize) => {
InvoiceModel.init( return sequelize.define(
"InvoiceModel",
{ {
id: { id: {
type: new DataTypes.UUID(), type: new DataTypes.UUID(),
@ -120,7 +118,6 @@ export default (database: Sequelize) => {
}, },
}, },
{ {
sequelize: database,
tableName: "invoices", tableName: "invoices",
paranoid: true, // softs deletes paranoid: true, // softs deletes
@ -139,6 +136,6 @@ export default (database: Sequelize) => {
scopes: {}, scopes: {},
} }
); );
return InvoiceModel;
}; };
export { initInvoiceModel };

View File

@ -1,11 +1,13 @@
import { Collection, logger, Result, SequelizeRepository, UniqueID } from "@rdx/core"; import { SequelizeRepository } from "@rdx/core";
import { Sequelize, Transaction } from "sequelize"; import { UniqueID } from "@rdx/ddd-domain";
import { Collection, Result } from "@rdx/utils";
import { Transaction } from "sequelize";
import { IInvoiceRepository, Invoice } from "../../domain"; import { IInvoiceRepository, Invoice } from "../../domain";
import { IInvoiceMapper } from "../mappers/invoice.mapper"; import { IInvoiceMapper, invoiceMapper } from "../mappers/invoice.mapper";
import { InvoiceItemModel } from "./invoice-item.model"; import { InvoiceItemModel } from "./invoice-item.model";
import { InvoiceModel } from "./invoice.model"; import { InvoiceModel } from "./invoice.model";
export class InvoiceRepository extends SequelizeRepository<Invoice> implements IInvoiceRepository { class InvoiceRepository extends SequelizeRepository<Invoice> implements IInvoiceRepository {
private readonly _mapper!: IInvoiceMapper; private readonly _mapper!: IInvoiceMapper;
/** /**
@ -19,8 +21,8 @@ export class InvoiceRepository extends SequelizeRepository<Invoice> implements I
return null; return null;
} }
constructor(database: Sequelize, mapper: IInvoiceMapper) { constructor(mapper: IInvoiceMapper) {
super(database); super();
this._mapper = mapper; this._mapper = mapper;
} }
@ -36,28 +38,25 @@ export class InvoiceRepository extends SequelizeRepository<Invoice> implements I
async findAll(transaction?: Transaction): Promise<Result<Collection<Invoice>, Error>> { async findAll(transaction?: Transaction): Promise<Result<Collection<Invoice>, Error>> {
try { try {
const rawInvoices = await InvoiceModel.findAll({ const rawInvoices: any = await this._findAll(
include: [ InvoiceModel,
{ {
model: InvoiceItemModel, include: [
as: "items", {
}, model: InvoiceItemModel,
], as: "items",
transaction, },
}); ],
},
transaction
);
/*if (!rawInvoices === true) { if (!rawInvoices === true) {
return Result.fail(new Error("Invoice not exists")); return Result.fail(new Error("Invoice with email not exists"));
}*/ }
logger.debug({
message: "rawInvoices",
label: "InvoiceRepository",
meta: { data: rawInvoices },
});
return this._mapper.mapArrayToDomain(rawInvoices); return this._mapper.mapArrayToDomain(rawInvoices);
} catch (error: unknown) { } catch (error: any) {
return this._handleDatabaseError(error, this._customErrorMapper); return this._handleDatabaseError(error, this._customErrorMapper);
} }
} }
@ -107,3 +106,6 @@ export class InvoiceRepository extends SequelizeRepository<Invoice> implements I
await this._save(InvoiceModel, invoice.id, invoiceData, {}, transaction); await this._save(InvoiceModel, invoice.id, invoiceData, {}, transaction);
} }
} }
const invoiceRepository = new InvoiceRepository(invoiceMapper);
export { invoiceRepository };

View File

@ -1,4 +1,5 @@
import { ExpressController, UniqueID } from "@rdx/core"; import { ExpressController } from "@rdx/core";
import { UniqueID } from "@rdx/ddd-domain";
import { CreateInvoiceUseCase } from "../../../application"; import { CreateInvoiceUseCase } from "../../../application";
import { ICreateInvoiceRequestDTO } from "../../dto"; import { ICreateInvoiceRequestDTO } from "../../dto";
import { ICreateInvoicePresenter } from "./presenter"; import { ICreateInvoicePresenter } from "./presenter";

View File

@ -1,14 +1,13 @@
import { CreateInvoiceUseCase } from "#/server/application";
import { InvoiceService } from "#/server/domain"; import { InvoiceService } from "#/server/domain";
import { invoiceMapper, InvoiceRepository } from "#/server/intrastructure"; import { invoiceRepository } from "#/server/intrastructure";
import { SequelizeTransactionManager } from "@rdx/core"; import { SequelizeTransactionManager } from "@rdx/core";
import { Sequelize } from "sequelize"; import { Sequelize } from "sequelize";
import { CreateInvoiceUseCase } from "../../../application";
import { CreateInvoiceController } from "./create-invoice.controller"; import { CreateInvoiceController } from "./create-invoice.controller";
import { createInvoicePresenter } from "./presenter"; import { createInvoicePresenter } from "./presenter";
export const buildCreateInvoiceController = (database: Sequelize) => { export const buildCreateInvoiceController = (database: Sequelize) => {
const transactionManager = new SequelizeTransactionManager(database); const transactionManager = new SequelizeTransactionManager(database);
const invoiceRepository = new InvoiceRepository(database, invoiceMapper);
const invoiceService = new InvoiceService(invoiceRepository); const invoiceService = new InvoiceService(invoiceRepository);
const useCase = new CreateInvoiceUseCase(invoiceService, transactionManager); const useCase = new CreateInvoiceUseCase(invoiceService, transactionManager);

View File

@ -1,5 +1,6 @@
import { GetInvoiceUseCase } from "#/server/application"; import { GetInvoiceUseCase } from "#/server/application";
import { ExpressController, UniqueID } from "@rdx/core"; import { ExpressController } from "@rdx/core";
import { UniqueID } from "@rdx/ddd-domain";
import { IGetInvoicePresenter } from "./presenter"; import { IGetInvoicePresenter } from "./presenter";
export class GetInvoiceController extends ExpressController { export class GetInvoiceController extends ExpressController {

View File

@ -1,6 +1,6 @@
import { GetInvoiceUseCase } from "#/server/application"; import { GetInvoiceUseCase } from "#/server/application";
import { InvoiceService } from "#/server/domain"; import { InvoiceService } from "#/server/domain";
import { invoiceMapper, InvoiceRepository } from "#/server/intrastructure"; import { invoiceRepository } from "#/server/intrastructure";
import { SequelizeTransactionManager } from "@rdx/core"; import { SequelizeTransactionManager } from "@rdx/core";
import { Sequelize } from "sequelize"; import { Sequelize } from "sequelize";
import { GetInvoiceController } from "./get-invoice.controller"; import { GetInvoiceController } from "./get-invoice.controller";
@ -8,7 +8,6 @@ import { getInvoicePresenter } from "./presenter";
export const buildGetInvoiceController = (database: Sequelize) => { export const buildGetInvoiceController = (database: Sequelize) => {
const transactionManager = new SequelizeTransactionManager(database); const transactionManager = new SequelizeTransactionManager(database);
const invoiceRepository = new InvoiceRepository(database, invoiceMapper);
const invoiceService = new InvoiceService(invoiceRepository); const invoiceService = new InvoiceService(invoiceRepository);
const useCase = new GetInvoiceUseCase(invoiceService, transactionManager); const useCase = new GetInvoiceUseCase(invoiceService, transactionManager);

View File

@ -1,6 +1,6 @@
import { InvoiceItem } from "#/server/domain"; import { InvoiceItem } from "#/server/domain";
import { IInvoicingContext } from "#/server/intrastructure"; import { IInvoicingContext } from "#/server/intrastructure";
import { Collection } from "@rdx/core"; import { Collection } from "@rdx/utils";
export const invoiceItemPresenter = (items: Collection<InvoiceItem>, context: IInvoicingContext) => export const invoiceItemPresenter = (items: Collection<InvoiceItem>, context: IInvoicingContext) =>
items.totalCount > 0 items.totalCount > 0

View File

@ -1,6 +1,6 @@
import { ListInvoicesUseCase } from "#/server/application"; import { ListInvoicesUseCase } from "#/server/application";
import { InvoiceService } from "#/server/domain"; import { InvoiceService } from "#/server/domain";
import { invoiceMapper, InvoiceRepository } from "#/server/intrastructure"; import { invoiceRepository } from "#/server/intrastructure";
import { SequelizeTransactionManager } from "@rdx/core"; import { SequelizeTransactionManager } from "@rdx/core";
import { Sequelize } from "sequelize"; import { Sequelize } from "sequelize";
import { ListInvoicesController } from "./list-invoices.controller"; import { ListInvoicesController } from "./list-invoices.controller";
@ -8,7 +8,6 @@ import { listInvoicesPresenter } from "./presenter";
export const buildListInvoicesController = (database: Sequelize) => { export const buildListInvoicesController = (database: Sequelize) => {
const transactionManager = new SequelizeTransactionManager(database); const transactionManager = new SequelizeTransactionManager(database);
const invoiceRepository = new InvoiceRepository(database, invoiceMapper);
const invoiceService = new InvoiceService(invoiceRepository); const invoiceService = new InvoiceService(invoiceRepository);
const useCase = new ListInvoicesUseCase(invoiceService, transactionManager); const useCase = new ListInvoicesUseCase(invoiceService, transactionManager);

View File

@ -1,6 +1,6 @@
import { Invoice } from "#/server/domain"; import { Invoice } from "#/server/domain";
import { IListInvoicesResponseDTO } from "#/server/presentation/dto"; import { IListInvoicesResponseDTO } from "#/server/presentation/dto";
import { Collection } from "@rdx/core"; import { Collection } from "@rdx/utils";
export interface IListInvoicesPresenter { export interface IListInvoicesPresenter {
toDTO: (invoices: Collection<Invoice>) => IListInvoicesResponseDTO[]; toDTO: (invoices: Collection<Invoice>) => IListInvoicesResponseDTO[];

View File

@ -1,50 +1,9 @@
{ {
"extends": "@repo/typescript-config/base.json", "extends": "@repo/typescript-config/base.json",
"compilerOptions": { "compilerOptions": {
/* Basic Options */ "outDir": "./dist",
"target": "ES2022" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
"lib": ["ES2022", "dom"] /* Specify library files to be included in the compilation. */,
"allowJs": false /* Allow javascript files to be compiled. */,
"pretty": true,
// "checkJs": true, /* Report errors in .js files. */
"jsx": "preserve" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */,
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
"sourceMap": true /* Generates corresponding '.map' file. */,
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./dist/" /* Redirect output structure to the directory. */,
//"rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
// "composite": true, /* Enable project compilation */
"removeComments": true /* Do not emit comments to output. */,
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"skipLibCheck": false /* Skip type checking of declaration files. */,
"strict": true /* Enable all strict type-checking options. */,
"noImplicitAny": false /* Raise error on expressions and declarations with an implied 'any' type. */,
"strictNullChecks": true /* Enable strict null checks. */,
"strictFunctionTypes": true /* Enable strict checking of function types. */,
"strictPropertyInitialization": false /* Enable strict checking of property initialization in classes. */,
"noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
"noUnusedLocals": false /* Report errors on unused locals. */,
"noUnusedParameters": false /* Report errors on unused parameters. */,
"noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
/* Module Resolution Options */
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
//"baseUrl": "./" /* Base directory to resolve non-absolute module names. */,
"rootDir": "./src", "rootDir": "./src",
//"types": ["node", "jest"], "types": ["node", "jest"],
"baseUrl": "./", "baseUrl": "./",
"paths": { "paths": {

View File

@ -3,25 +3,20 @@
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev:server": "pnpm run dev --filter './apps/server'",
"dev:server:watch": "nodemon --watch ./apps/server --ext ts --exec ts-node-dev -r tsconfig-paths/register ./apps/server/src/index.ts",
"dev": "turbo run dev",
"build": "turbo run build", "build": "turbo run build",
"clean": "turbo run clean && rm -rf node_modules", "clean": "turbo run clean && rm -rf node_modules",
"dev": "turbo run dev",
"format": "prettier --write \"**/*.{ts,tsx,md}\"", "format": "prettier --write \"**/*.{ts,tsx,md}\"",
"lint": "turbo run lint", "lint": "turbo run lint",
"test": "turbo run test" "test": "turbo run test"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^9.25.1",
"nodemon": "^3.1.10",
"prettier": "^3.5.3", "prettier": "^3.5.3",
"ts-node": "^10.9.2", "turbo": "^2.5.2",
"ts-node-dev": "^2.0.0", "eslint": "^9.25.1"
"turbo": "^2.5.2"
}, },
"engines": { "engines": {
"node": ">=22.13.1" "node": ">=22.13.1"
}, },
"packageManager": "pnpm@10.10.0" "packageManager": "pnpm@10.9.0"
} }

View File

@ -10,7 +10,7 @@
], ],
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"clean": "rm -rf dist && rm -rf node_modules", "clean": "rm -rf dist && rm -rf node_modules",
"lint": "eslint src/", "lint": "eslint src/",
"lint:fix": "eslint src/ --fix", "lint:fix": "eslint src/ --fix",
"typecheck": "tsc --noEmit", "typecheck": "tsc --noEmit",
@ -52,6 +52,10 @@
}, },
"dependencies": { "dependencies": {
"@rdx/core": "workspace:*", "@rdx/core": "workspace:*",
"@rdx/ddd-domain": "workspace:*",
"@rdx/logger": "workspace:*",
"@rdx/modules": "workspace:*",
"@rdx/utils": "workspace:*",
"bcrypt": "^5.1.1", "bcrypt": "^5.1.1",
"body-parser": "^2.2.0", "body-parser": "^2.2.0",
"cors": "^2.8.5", "cors": "^2.8.5",
@ -71,7 +75,7 @@
"path": "^0.12.7", "path": "^0.12.7",
"reflect-metadata": "^0.2.2", "reflect-metadata": "^0.2.2",
"response-time": "^2.3.3", "response-time": "^2.3.3",
"sequelize": "^6.37.5", "sequelize": "^6.37.7",
"zod": "^3.24.3" "zod": "^3.24.3"
} }
} }

View File

@ -1,5 +1,6 @@
import { IUserService, User } from "@/domain"; import { IUserService, User } from "@/domain";
import { Collection, ITransactionManager, Result } from "@rdx/core"; import { ITransactionManager } from "@rdx/core";
import { Collection, Result } from "@rdx/utils";
export class ListUsersUseCase { export class ListUsersUseCase {
constructor( constructor(

View File

@ -1,6 +1,7 @@
import { IAuthService, RegisterData } from "@/domain"; import { IAuthService, RegisterData } from "@/domain";
import { ITransactionManager, Result } from "@rdx/core"; import { ITransactionManager } from "@rdx/core";
import { logger } from "@rdx/logger"; import { logger } from "@rdx/logger";
import { Result } from "@rdx/utils";
export class RegisterUseCase { export class RegisterUseCase {
constructor( constructor(

View File

@ -1,4 +1,5 @@
import { AggregateRoot, EmailAddress, Result, UniqueID } from "@rdx/core"; import { AggregateRoot, EmailAddress, UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { UserAuthenticatedEvent } from "../events"; import { UserAuthenticatedEvent } from "../events";
import { HashPassword, PlainPassword, Username } from "../value-objects"; import { HashPassword, PlainPassword, Username } from "../value-objects";

View File

@ -1,4 +1,5 @@
import { AggregateRoot, Result, UniqueID } from "@rdx/core"; import { AggregateRoot, UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
export interface IRoleProps {} export interface IRoleProps {}

View File

@ -1,4 +1,5 @@
import { AggregateRoot, EmailAddress, Result, UniqueID } from "@rdx/core"; import { AggregateRoot, EmailAddress, UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { UserAuthenticatedEvent } from "../events"; import { UserAuthenticatedEvent } from "../events";
import { Username } from "../value-objects"; import { Username } from "../value-objects";

View File

@ -1,4 +1,5 @@
import { DomainEntity, EmailAddress, Result, UniqueID } from "@rdx/core"; import { DomainEntity, EmailAddress, UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
export interface IJWTPayloadProps { export interface IJWTPayloadProps {
tabId: UniqueID; tabId: UniqueID;

View File

@ -1,4 +1,5 @@
import { DomainEntity, EmailAddress, Result, UniqueID } from "@rdx/core"; import { DomainEntity, EmailAddress, UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { PlainPassword } from "../value-objects"; import { PlainPassword } from "../value-objects";
export interface ILoginDataProps { export interface ILoginDataProps {

View File

@ -1,4 +1,5 @@
import { DomainEntity, EmailAddress, Result, UniqueID } from "@rdx/core"; import { DomainEntity, EmailAddress, UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
export interface ILogoutDataProps { export interface ILogoutDataProps {
email: EmailAddress; email: EmailAddress;

View File

@ -1,4 +1,5 @@
import { DomainEntity, EmailAddress, Result } from "@rdx/core"; import { DomainEntity, EmailAddress } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { HashPassword, Username } from "../value-objects"; import { HashPassword, Username } from "../value-objects";
export interface IRegisterDataProps { export interface IRegisterDataProps {

View File

@ -1,4 +1,5 @@
import { DomainEntity, Result, UniqueID } from "@rdx/core"; import { DomainEntity, UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
export interface ITabContextProps { export interface ITabContextProps {
tabId: UniqueID; tabId: UniqueID;

View File

@ -1,4 +1,4 @@
import { IDomainEvent, UniqueID } from "@rdx/core"; import { IDomainEvent, UniqueID } from "@rdx/ddd-domain";
export class UserAuthenticatedEvent implements IDomainEvent { export class UserAuthenticatedEvent implements IDomainEvent {
public readonly eventName = "UserAuthenticated"; public readonly eventName = "UserAuthenticated";

View File

@ -1,4 +1,5 @@
import { EmailAddress, Result } from "@rdx/core"; import { EmailAddress } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { AuthenticatedUser } from "../aggregates"; import { AuthenticatedUser } from "../aggregates";
import { Username } from "../value-objects"; import { Username } from "../value-objects";

View File

@ -1,4 +1,5 @@
import { Result, UniqueID } from "@rdx/core"; import { UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { Transaction } from "sequelize"; import { Transaction } from "sequelize";
import { TabContext } from "../entities"; import { TabContext } from "../entities";

View File

@ -1,4 +1,5 @@
import { Collection, EmailAddress, Result, UniqueID } from "@rdx/core"; import { EmailAddress, UniqueID } from "@rdx/ddd-domain";
import { Collection, Result } from "@rdx/utils";
import { User } from "../aggregates"; import { User } from "../aggregates";
export interface IUserRepository { export interface IUserRepository {

View File

@ -1,4 +1,5 @@
import { EmailAddress, Result } from "@rdx/core"; import { EmailAddress } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { import {
AuthenticatedUser, AuthenticatedUser,
IJWTPayload, IJWTPayload,

View File

@ -1,4 +1,5 @@
import { EmailAddress, Result, UniqueID } from "@rdx/core"; import { EmailAddress, UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { import {
AuthenticatedUser, AuthenticatedUser,
IAuthenticatedUserRepository, IAuthenticatedUserRepository,

View File

@ -1,4 +1,5 @@
import { Result, UniqueID } from "@rdx/core"; import { UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { TabContext } from "../entities"; import { TabContext } from "../entities";
export interface ITabContextService { export interface ITabContextService {

View File

@ -1,4 +1,5 @@
import { Result, UniqueID } from "@rdx/core"; import { UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { TabContext } from "../entities"; import { TabContext } from "../entities";
import { ITabContextRepository } from "../repositories"; import { ITabContextRepository } from "../repositories";
import { ITabContextService } from "./tab-context-service.interface"; import { ITabContextService } from "./tab-context-service.interface";

View File

@ -1,4 +1,5 @@
import { Collection, Result, UniqueID } from "@rdx/core"; import { UniqueID } from "@rdx/ddd-domain";
import { Collection, Result } from "@rdx/utils";
import { User } from "../aggregates"; import { User } from "../aggregates";
export interface IUserService { export interface IUserService {

View File

@ -1,4 +1,5 @@
import { Collection, Result, UniqueID } from "@rdx/core"; import { UniqueID } from "@rdx/ddd-domain";
import { Collection, Result } from "@rdx/utils";
import { IUserRepository, User } from ".."; import { IUserRepository, User } from "..";
import { IUserService } from "./user-service.interface"; import { IUserService } from "./user-service.interface";

View File

@ -1,4 +1,5 @@
import { Result, ValueObject } from "@rdx/core"; import { ValueObject } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { z } from "zod"; import { z } from "zod";
const RoleSchema = z.enum(["Admin", "User", "Manager", "Editor"]); const RoleSchema = z.enum(["Admin", "User", "Manager", "Editor"]);

View File

@ -1,4 +1,5 @@
import { Result, ValueObject } from "@rdx/core"; import { ValueObject } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import bcrypt from "bcrypt"; import bcrypt from "bcrypt";
import { z } from "zod"; import { z } from "zod";

View File

@ -1,4 +1,5 @@
import { Result, ValueObject } from "@rdx/core"; import { ValueObject } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { z } from "zod"; import { z } from "zod";
interface PlainPasswordProps { interface PlainPasswordProps {

View File

@ -1,4 +1,5 @@
import { Result, ValueObject } from "@rdx/core"; import { ValueObject } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { z } from "zod"; import { z } from "zod";
interface TokenProps { interface TokenProps {

View File

@ -1,4 +1,5 @@
import { Result, ValueObject } from "@rdx/core"; import { ValueObject } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { z } from "zod"; import { z } from "zod";
interface UsernameProps { interface UsernameProps {

View File

@ -1,4 +1,5 @@
import { Result, UniqueID } from "@rdx/core"; import { UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { ISequelizeMapper, MapperParamsType, SequelizeMapper } from "../../../common"; import { ISequelizeMapper, MapperParamsType, SequelizeMapper } from "../../../common";
import { TabContext } from "../../domain"; import { TabContext } from "../../domain";
import { TabContextCreationAttributes, TabContextModel } from "../sequelize"; import { TabContextCreationAttributes, TabContextModel } from "../sequelize";

View File

@ -1,4 +1,5 @@
import { EmailAddress, Result, UniqueID } from "@rdx/core"; import { EmailAddress, UniqueID } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { ISequelizeMapper, MapperParamsType, SequelizeMapper } from "../../../common"; import { ISequelizeMapper, MapperParamsType, SequelizeMapper } from "../../../common";
import { User, Username } from "../../domain"; import { User, Username } from "../../domain";
import { UserCreationAttributes, UserModel } from "../sequelize"; import { UserCreationAttributes, UserModel } from "../sequelize";

View File

@ -1,5 +1,5 @@
//import { authProvider } from "@contexts/auth/infraestructure"; //import { authProvider } from "@contexts/auth/infraestructure";
import { UniqueID } from "@rdx/core"; import { UniqueID } from "@rdx/ddd-domain";
import { NextFunction, Response } from "express"; import { NextFunction, Response } from "express";
import { ApiError, ExpressController } from "../../../common"; import { ApiError, ExpressController } from "../../../common";
import { AuthenticatedRequest } from "../../../common/presentation/express/types"; import { AuthenticatedRequest } from "../../../common/presentation/express/types";

View File

@ -1,4 +1,6 @@
import { EmailAddress, Result, SequelizeRepository } from "@rdx/core"; import { SequelizeRepository } from "@rdx/core";
import { EmailAddress } from "@rdx/ddd-domain";
import { Result } from "@rdx/utils";
import { Transaction } from "sequelize"; import { Transaction } from "sequelize";
import { AuthenticatedUser, IAuthenticatedUserRepository, Username } from "../../domain"; import { AuthenticatedUser, IAuthenticatedUserRepository, Username } from "../../domain";
import { authenticatedUserMapper, IAuthenticatedUserMapper } from "../mappers"; import { authenticatedUserMapper, IAuthenticatedUserMapper } from "../mappers";

View File

@ -1,5 +1,7 @@
import { IUserRepository, User } from "@/domain"; import { IUserRepository, User } from "@/domain";
import { Collection, EmailAddress, Result, SequelizeRepository, UniqueID } from "@rdx/core"; import { SequelizeRepository } from "@rdx/core";
import { EmailAddress, UniqueID } from "@rdx/ddd-domain";
import { Collection, Result } from "@rdx/utils";
import { Transaction } from "sequelize"; import { Transaction } from "sequelize";
import { IUserMapper, userMapper } from "../mappers"; import { IUserMapper, userMapper } from "../mappers";
import { UserModel } from "./user.model"; import { UserModel } from "./user.model";

View File

@ -1,4 +1,4 @@
import { Collection, ensureString } from "@rdx/core"; import { Collection, ensureString } from "@rdx/utils";
import { User } from "../../../domain"; import { User } from "../../../domain";
import { IListUsersResponseDTO } from "../../dto"; import { IListUsersResponseDTO } from "../../dto";

View File

@ -1,7 +1,6 @@
{ {
"extends": "@repo/typescript-config/base.json", "extends": "@repo/typescript-config/base.json",
"compilerOptions": { "compilerOptions": {
"sourceMap": true,
"outDir": "./dist", "outDir": "./dist",
"rootDir": "./src", "rootDir": "./src",
"types": ["node"], "types": ["node"],

View File

@ -42,8 +42,6 @@
"@types/supertest": "^6.0.3", "@types/supertest": "^6.0.3",
"@typescript-eslint/eslint-plugin": "^8.31.0", "@typescript-eslint/eslint-plugin": "^8.31.0",
"@typescript-eslint/parser": "^8.31.0", "@typescript-eslint/parser": "^8.31.0",
"@types/winston": "^2.4.4",
"@types/react": "^19.1.2",
"esbuild": "^0.25.3", "esbuild": "^0.25.3",
"esbuild-register": "^3.6.0", "esbuild-register": "^3.6.0",
"eslint": "^9.25.1", "eslint": "^9.25.1",
@ -53,6 +51,10 @@
"typescript": "5.8.3" "typescript": "5.8.3"
}, },
"dependencies": { "dependencies": {
"@rdx/ddd-domain": "workspace:*",
"@rdx/logger": "workspace:*",
"@rdx/modules": "workspace:*",
"@rdx/utils": "workspace:*",
"bcrypt": "^5.1.1", "bcrypt": "^5.1.1",
"body-parser": "^2.2.0", "body-parser": "^2.2.0",
"cors": "^2.8.5", "cors": "^2.8.5",
@ -72,14 +74,7 @@
"path": "^0.12.7", "path": "^0.12.7",
"reflect-metadata": "^0.2.2", "reflect-metadata": "^0.2.2",
"response-time": "^2.3.3", "response-time": "^2.3.3",
"zod": "^3.24.3", "sequelize": "^6.37.7",
"cls-rtracer": "^2.6.3", "zod": "^3.24.3"
"winston": "^3.17.0",
"winston-daily-rotate-file": "^5.0.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"sequelize": "^6.37.5",
"shallow-equal-object": "^1.1.1",
"uuid": "^11.1.0"
} }
} }

View File

@ -1,4 +1,2 @@
export * from "./domain";
export * from "./helpers";
export * from "./infrastructure"; export * from "./infrastructure";
export * from "./presentation"; export * from "./presentation";

View File

@ -1,3 +1,2 @@
export * from "./database"; export * from "./database";
export * from "./logger";
export * from "./sequelize"; export * from "./sequelize";

View File

@ -1,6 +1,6 @@
import { DomainEntity } from "@rdx/ddd-domain";
import { Collection, Result } from "@rdx/utils";
import { Model } from "sequelize"; import { Model } from "sequelize";
import { DomainEntity } from "../../domain";
import { Collection, Result } from "../../helpers";
export type MapperParamsType = Record<string, any>; export type MapperParamsType = Record<string, any>;

View File

@ -1,15 +1,9 @@
import { ModelDefined, Sequelize, Transaction } from "sequelize"; import { IAggregateRootRepository, UniqueID } from "@rdx/ddd-domain";
import { IAggregateRootRepository, UniqueID } from "../../domain"; import { logger } from "@rdx/logger";
import { Result } from "../../helpers"; import { Result } from "@rdx/utils";
import { logger } from "../logger"; import { ModelDefined, Transaction } from "sequelize";
export abstract class SequelizeRepository<T> implements IAggregateRootRepository<T> { export abstract class SequelizeRepository<T> implements IAggregateRootRepository<T> {
protected readonly _database!: Sequelize;
constructor(database: Sequelize) {
this._database = database;
}
protected async _findAll( protected async _findAll(
model: ModelDefined<any, any>, model: ModelDefined<any, any>,
//queryCriteria?: IQueryCriteria, //queryCriteria?: IQueryCriteria,
@ -141,7 +135,7 @@ export abstract class SequelizeRepository<T> implements IAggregateRootRepository
): Result<never, Error> { ): Result<never, Error> {
const _error = error as Error; const _error = error as Error;
logger.error({ message: `Database error: ${_error.message}`, label: "SequelizeRepository" }); logger.error(`Database error: ${_error.message}`);
// Si la clase hija proporciona un mapeo personalizado, lo usa // Si la clase hija proporciona un mapeo personalizado, lo usa
if (errorMapper) { if (errorMapper) {

View File

@ -1,6 +1,6 @@
import { logger } from "@rdx/logger";
import { NextFunction, Request, Response } from "express"; import { NextFunction, Request, Response } from "express";
import httpStatus from "http-status"; import httpStatus from "http-status";
import { logger } from "../../infrastructure";
import { ApiError } from "./api-error"; import { ApiError } from "./api-error";
export abstract class ExpressController { export abstract class ExpressController {

View File

@ -1,6 +1,6 @@
import { NextFunction, Request, Response } from "express"; import { NextFunction, Request, Response } from "express";
import { logger } from "../../../infrastructure";
import { ApiError } from "../api-error"; import { ApiError } from "../api-error";
import { logger } from "@rdx/logger";
export const globalErrorHandler = async ( export const globalErrorHandler = async (
error: Error, error: Error,

View File

@ -1,10 +1,13 @@
{ {
"extends": "@repo/typescript-config/base.json", "extends": "@repo/typescript-config/base.json",
"compilerOptions": { "compilerOptions": {
"sourceMap": true,
"outDir": "./dist", "outDir": "./dist",
"rootDir": "./src", "rootDir": "./src",
"types": ["node"] "types": ["node"],
"paths": {
"@/*": ["./src/*"]
}
}, },
"files": ["src/index.ts"], "files": ["src/index.ts"],
"include": ["src/index.ts"], "include": ["src/index.ts"],

View File

@ -1,7 +1,6 @@
{ {
"extends": "@repo/typescript-config/base.json", "extends": "@repo/typescript-config/base.json",
"compilerOptions": { "compilerOptions": {
"sourceMap": true,
"outDir": "./dist", "outDir": "./dist",
"rootDir": "./src", "rootDir": "./src",
"types": ["node"], "types": ["node"],

View File

@ -0,0 +1,40 @@
{
"name": "@rdx/ddd-domain",
"version": "0.0.0",
"private": true,
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"files": [
"dist/**"
],
"scripts": {
"build": "tsc",
"clean": "rm -rf dist && rm -rf node_modules",
"lint": "eslint src/",
"lint:fix": "eslint src/ --fix",
"typecheck": "tsc --noEmit",
"test": "jest"
},
"jest": {
"preset": "@repo/jest-presets/node"
},
"devDependencies": {
"@repo/eslint-config": "workspace:*",
"@repo/jest-presets": "workspace:*",
"@repo/typescript-config": "workspace:*",
"@types/dinero.js": "^1.9.4",
"@types/node": "^22.15.2",
"jest": "^29.7.0",
"typescript": "^5.8.3"
},
"dependencies": {
"@rdx/logger": "workspace:*",
"@rdx/utils": "workspace:*",
"dinero.js": "^1.9.1",
"libphonenumber-js": "^1.12.7",
"shallow-equal-object": "^1.1.1",
"uuid": "^11.1.0",
"zod": "^3.24.3"
}
}

View File

@ -1,4 +1,4 @@
import { logger } from "../infrastructure"; import { logger } from "@rdx/logger";
import { DomainEntity } from "./domain-entity"; import { DomainEntity } from "./domain-entity";
import { IDomainEvent } from "./events"; import { IDomainEvent } from "./events";

Some files were not shown because too many files have changed in this diff Show More