refactor: ajustar importaciones y tipos en varios archivos para mejorar la claridad y la consistencia
This commit is contained in:
parent
2f23d75b6f
commit
38fb6299b7
@ -1,8 +1,8 @@
|
||||
import type { ISequelizeTransactionContext } from "@erp/core/api";
|
||||
import type { AuditEntry, AuditRecordOptions, IAuditStore } from "@repo/rdx-audit";
|
||||
import { AuditStoreError } from "@repo/rdx-audit";
|
||||
import type { AuditEntry, IAuditStore } from "@repo/rdx-audit";
|
||||
import { type AuditRecordOptions, AuditStoreError } from "@repo/rdx-audit";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
import type { ModelStatic } from "sequelize";
|
||||
import type { ModelStatic, Transaction } from "sequelize";
|
||||
|
||||
import type { AuditChangeModel } from "./audit-change.model";
|
||||
import type { AuditEventModel } from "./audit-event.model";
|
||||
@ -19,8 +19,12 @@ export class SequelizeAuditStore implements IAuditStore {
|
||||
private readonly transactionContext: ISequelizeTransactionContext
|
||||
) {}
|
||||
|
||||
async append(entry: AuditEntry, options?: AuditRecordOptions): Promise<Result<void, AuditStoreError>> {
|
||||
const transaction = options?.transaction ?? this.transactionContext.current();
|
||||
async append(
|
||||
entry: AuditEntry,
|
||||
options?: AuditRecordOptions
|
||||
): Promise<Result<void, AuditStoreError>> {
|
||||
const transaction = (options?.transaction as Transaction) ?? this.transactionContext.current();
|
||||
|
||||
if (entry.kind === "mutation" && !transaction) {
|
||||
return Result.fail(
|
||||
new AuditStoreError("An active transaction is required for audit mutations.")
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { AuditEntry, IAuditStore } from "@repo/rdx-audit";
|
||||
import type { AuditEntry, AuditRecordOptions, IAuditStore } from "@repo/rdx-audit";
|
||||
import { AuditStoreError } from "@repo/rdx-audit";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
import type { ModelStatic } from "sequelize";
|
||||
import type { ModelStatic, Transaction } from "sequelize";
|
||||
|
||||
import type { ISequelizeTransactionContext } from "../../persistence/sequelize";
|
||||
|
||||
@ -18,7 +18,7 @@ export class SequelizeAuditStore implements IAuditStore {
|
||||
entry: AuditEntry,
|
||||
options?: AuditRecordOptions
|
||||
): Promise<Result<void, AuditStoreError>> {
|
||||
const transaction = options?.transaction ?? this.transactionContext.current();
|
||||
const transaction = (options?.transaction as Transaction) ?? this.transactionContext.current();
|
||||
if (entry.kind === "mutation" && !transaction)
|
||||
return Result.fail(
|
||||
new AuditStoreError("An active transaction is required for audit mutations.")
|
||||
|
||||
@ -1,11 +1,5 @@
|
||||
// core/api/infrastructure/documents/certificates/
|
||||
// env-company-signing-context-store.ts
|
||||
|
||||
import type {
|
||||
ICompanyCertificateContext,
|
||||
ISigningContextResolver,
|
||||
} from "@erp/core/api/application";
|
||||
import type { ModuleParams } from "@erp/core/api/modules";
|
||||
import type { ICompanyCertificateContext, ISigningContextResolver } from "../../../application";
|
||||
import type { ModuleParams } from "../../../modules";
|
||||
|
||||
import type { ICompanySigningContextRecord } from "./company-signing-context-record.interface";
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import type { IDocumentSigningService } from "@erp/core/api/application";
|
||||
import type { ICompanyCertificateContext } from "@erp/core/api/application/documents/application-models/company-certificate-context.interface";
|
||||
import type { ICompanyCertificateContext, IDocumentSigningService } from "../../../application";
|
||||
|
||||
import type { RestDocumentSigningConfig } from "./rest-document-signing-config";
|
||||
import { SimpleCircuitBreaker } from "./simple-circuit-breaker";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { DomainMapperWithBulk, IQueryMapperWithBulk } from "@erp/core/api/application";
|
||||
import type { DomainMapperWithBulk, IQueryMapperWithBulk } from "../../../../application";
|
||||
|
||||
export interface ISequelizeDomainMapper<TModel, TModelAttributes, TEntity>
|
||||
extends DomainMapperWithBulk<TModel | TModelAttributes, TEntity> {}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export * from "./module-server.interface";
|
||||
export * from "./module-runtime";
|
||||
export * from "./module-server.interface";
|
||||
export * from "./modules-runtime";
|
||||
export * from "./types";
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import type { ILogger } from "@repo/rdx-logger";
|
||||
import type { ModelStatic, Sequelize } from "sequelize";
|
||||
import type { Model, ModelStatic, Sequelize } from "sequelize";
|
||||
|
||||
import type { IModuleServer } from "./module-server.interface";
|
||||
import type { ModuleParams, ModuleSetupResult, StartParams, WarmupParams } from "./types";
|
||||
import type { ModulesRuntime } from "./modules-runtime";
|
||||
import type { ModuleParams, ModuleSetupResult, StartParams, WarmupParams } from "./types";
|
||||
|
||||
type ModelInitializer = (database: Sequelize) => ModelStatic;
|
||||
type ModelInitializer = (database: Sequelize) => ModelStatic<Model>;
|
||||
type ModelEntry = { initializer: ModelInitializer; moduleName: string };
|
||||
|
||||
const modules = new Map<string, IModuleServer>();
|
||||
@ -29,13 +29,28 @@ export function registerModels(initializers: ModelInitializer[], moduleName: str
|
||||
}
|
||||
|
||||
/** Inicializa únicamente infraestructura backend: setup, modelos y warmups. */
|
||||
export async function initModules(params: ModuleParams & { logger: ILogger; database: Sequelize; warmup: { timeoutMs: number; strict: boolean }; databaseSyncMode: string }): Promise<ModulesRuntime> {
|
||||
export async function initModules(
|
||||
params: ModuleParams & {
|
||||
logger: ILogger;
|
||||
database: Sequelize;
|
||||
warmup: { timeoutMs: number; strict: boolean };
|
||||
databaseSyncMode: string;
|
||||
}
|
||||
): Promise<ModulesRuntime> {
|
||||
for (const name of modules.keys()) await setupModule(name, params, []);
|
||||
await initializeModels(params.database, params.databaseSyncMode, params.logger);
|
||||
await warmupModules(params);
|
||||
validateDependencies();
|
||||
const customerInvoices = internals.get("customer-invoices") as { proformas: { recurringProformas: ModulesRuntime["customerInvoices"]["recurringProformas"] } } | undefined;
|
||||
if (!customerInvoices) throw new Error('Module "customer-invoices" did not expose recurring runtime capabilities');
|
||||
|
||||
const customerInvoices = internals.get("customer-invoices") as
|
||||
| {
|
||||
proformas: { recurringProformas: ModulesRuntime["customerInvoices"]["recurringProformas"] };
|
||||
}
|
||||
| undefined;
|
||||
|
||||
if (!customerInvoices)
|
||||
throw new Error('Module "customer-invoices" did not expose recurring runtime capabilities');
|
||||
|
||||
return { customerInvoices: customerInvoices.proformas.recurringProformas };
|
||||
}
|
||||
|
||||
@ -44,71 +59,228 @@ export async function startModules(params: ModuleParams & { logger: ILogger }):
|
||||
for (const name of setupOrder) {
|
||||
const module = modules.get(name);
|
||||
if (!module?.start) continue;
|
||||
await module.start({ ...params, getService: makeGetService(name, module), getInternal: makeGetInternal(name), listServices } as StartParams);
|
||||
await module.start({
|
||||
...params,
|
||||
getService: makeGetService(name, module),
|
||||
getInternal: makeGetInternal(name),
|
||||
listServices,
|
||||
} as StartParams);
|
||||
}
|
||||
validateDependencies();
|
||||
}
|
||||
|
||||
async function setupModule(name: string, params: ModuleParams & { logger: ILogger }, stack: string[]): Promise<void> {
|
||||
if (setupDone.has(name)) return;
|
||||
if (visiting.has(name)) throw new Error(`Cyclic dependency detected: ${[...stack, name].join(" -> ")}`);
|
||||
async function setupModule(
|
||||
name: string,
|
||||
params: ModuleParams & { logger: ILogger },
|
||||
stack: string[]
|
||||
): Promise<void> {
|
||||
if (setupDone.has(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (visiting.has(name)) {
|
||||
throw new Error(`Cyclic dependency detected: ${[...stack, name].join(" -> ")}`);
|
||||
}
|
||||
|
||||
const module = modules.get(name);
|
||||
if (!module) throw new Error(`Module "${name}" not found`);
|
||||
|
||||
if (!module) {
|
||||
throw new Error(`Module "${name}" not found`);
|
||||
}
|
||||
|
||||
visiting.add(name);
|
||||
for (const dependency of module.dependencies ?? []) await setupModule(dependency, params, [...stack, name]);
|
||||
const result = (await module.setup?.({ ...params, getService: makeGetService(name, module), listServices })) as ModuleSetupResult | undefined;
|
||||
for (const dependency of module.dependencies ?? []) {
|
||||
await setupModule(dependency, params, [...stack, name]);
|
||||
}
|
||||
|
||||
const result = (await module.setup?.({
|
||||
...params,
|
||||
getService: makeGetService(name, module),
|
||||
listServices,
|
||||
})) as ModuleSetupResult | undefined;
|
||||
|
||||
internals.set(name, result?.internal ?? {});
|
||||
if (result?.models) registerModels(result.models as ModelInitializer[], name);
|
||||
for (const [key, service] of Object.entries(result?.services ?? {})) registerService(`${name}:${key}`, service);
|
||||
|
||||
if (result?.models) {
|
||||
registerModels(result.models as ModelInitializer[], name);
|
||||
}
|
||||
|
||||
for (const [key, service] of Object.entries(result?.services ?? {})) {
|
||||
registerService(`${name}:${key}`, service);
|
||||
}
|
||||
|
||||
setupDone.add(name);
|
||||
|
||||
setupOrder.push(name);
|
||||
|
||||
visiting.delete(name);
|
||||
}
|
||||
|
||||
async function initializeModels(database: Sequelize, syncMode: string, logger: ILogger): Promise<void> {
|
||||
if (modelsInitialized) return;
|
||||
const registered = new Map<string, { model: ModelStatic; moduleName: string }>();
|
||||
async function initializeModels(
|
||||
database: Sequelize,
|
||||
syncMode: string,
|
||||
logger: ILogger
|
||||
): Promise<void> {
|
||||
if (modelsInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
const registered = new Map<string, { model: ModelStatic<Model>; moduleName: string }>();
|
||||
|
||||
for (const entry of models) {
|
||||
const model = entry.initializer(database);
|
||||
if (!model?.name) throw new Error(`Invalid model initializer from "${entry.moduleName}"`);
|
||||
if (registered.has(model.name)) throw new Error(`Model name collision: "${model.name}"`);
|
||||
if (!model?.name) {
|
||||
throw new Error(`Invalid model initializer from "${entry.moduleName}"`);
|
||||
}
|
||||
if (registered.has(model.name)) {
|
||||
throw new Error(`Model name collision: "${model.name}"`);
|
||||
}
|
||||
registered.set(model.name, { model, moduleName: entry.moduleName });
|
||||
}
|
||||
|
||||
for (const { model } of registered.values()) {
|
||||
const associate = model as ModelStatic & { associate?: (sequelize: Sequelize) => void };
|
||||
const associate = model as ModelStatic<Model> & { associate?: (sequelize: Sequelize) => void };
|
||||
associate.associate?.(database);
|
||||
}
|
||||
if (syncMode === "alter") await database.sync({ force: false, alter: true });
|
||||
if (syncMode === "force") await database.sync({ force: true, alter: false });
|
||||
logger.info("Backend module models initialized", { label: "moduleRuntime", modelCount: registered.size });
|
||||
|
||||
if (syncMode === "alter") {
|
||||
await database.sync({ force: false, alter: true });
|
||||
}
|
||||
|
||||
if (syncMode === "force") {
|
||||
await database.sync({ force: true, alter: false });
|
||||
}
|
||||
|
||||
logger.info("Backend module models initialized", {
|
||||
label: "moduleRuntime",
|
||||
modelCount: registered.size,
|
||||
});
|
||||
modelsInitialized = true;
|
||||
}
|
||||
|
||||
async function warmupModules(params: ModuleParams & { logger: ILogger; warmup: { timeoutMs: number; strict: boolean } }): Promise<void> {
|
||||
async function warmupModules(
|
||||
params: ModuleParams & { logger: ILogger; warmup: { timeoutMs: number; strict: boolean } }
|
||||
): Promise<void> {
|
||||
for (const name of setupOrder) {
|
||||
const module = modules.get(name);
|
||||
if (!module?.warmup) continue;
|
||||
try {
|
||||
await withTimeout(Promise.resolve(module.warmup({ ...params, getService: makeGetService(name, module), getInternal: makeGetInternal(name), listServices } as WarmupParams)), params.warmup.timeoutMs, `${name}.warmup`);
|
||||
await withTimeout(
|
||||
Promise.resolve(
|
||||
module.warmup({
|
||||
...params,
|
||||
getService: makeGetService(name, module),
|
||||
getInternal: makeGetInternal(name),
|
||||
listServices,
|
||||
} as WarmupParams)
|
||||
),
|
||||
params.warmup.timeoutMs,
|
||||
`${name}.warmup`
|
||||
);
|
||||
} catch (error) {
|
||||
if (params.warmup.strict) throw error;
|
||||
params.logger.warn("Module warmup failed but continuing", { label: "moduleRuntime", module: name, error });
|
||||
params.logger.warn("Module warmup failed but continuing", {
|
||||
label: "moduleRuntime",
|
||||
module: name,
|
||||
error,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function registerService(name: string, service: unknown): void { if (services[name]) throw new Error(`Service "${name}" already registered`); services[name] = service; }
|
||||
function makeGetService(moduleName: string, module: IModuleServer) { return <T>(name: string): T => { const [dependency, ...key] = name.split(":"); if (dependency !== "self") { if (!(module.dependencies ?? []).includes(dependency)) throw new Error(`Module "${moduleName}" tried to access service "${name}" without declaring dependency on "${dependency}"`); trackDependency(moduleName, dependency); return getService<T>(name); } return getService<T>(`${moduleName}:${key.join(":")}`); }; }
|
||||
function makeGetInternal(moduleName: string) { return <T>(requestedModule: string, key?: string): T => { if (requestedModule !== moduleName) throw new Error(`Module "${moduleName}" attempted to access private internal state`); const internal = internals.get(moduleName) ?? {}; return (key ? internal[key] : internal) as T; }; }
|
||||
function getService<T>(name: string): T { const service = services[name]; if (!service) throw new Error(`Service "${name}" not found`); return service as T; }
|
||||
function trackDependency(moduleName: string, dependency: string): void { const used = usedDependencies.get(moduleName) ?? new Set<string>(); used.add(dependency); usedDependencies.set(moduleName, used); }
|
||||
function validateDependencies(): void { for (const [name, module] of modules) { const declared = new Set(module.dependencies ?? []); const used = usedDependencies.get(name) ?? new Set<string>(); const undeclared = [...used].filter((dependency) => !declared.has(dependency)); if (undeclared.length) throw new Error(`Module "${name}" used undeclared dependencies: ${undeclared.join(", ")}`); } }
|
||||
function withTimeout<T>(promise: Promise<T>, timeoutMs: number, label: string): Promise<T> { let timeout: NodeJS.Timeout | undefined; const timeoutPromise = new Promise<T>((_, reject) => { timeout = setTimeout(() => reject(new Error(`Timeout after ${timeoutMs}ms (${label})`)), timeoutMs); }); return Promise.race([promise, timeoutPromise]).finally(() => { if (timeout) clearTimeout(timeout); }) as Promise<T>; }
|
||||
export function listServices(): string[] { return Object.keys(services); }
|
||||
export function getServiceScoped<T>(requesterModule: string, allowedDependencies: readonly string[], name: string): T {
|
||||
const [moduleName, ...key] = name.split(":");
|
||||
if (moduleName === "self") return getService<T>(`${requesterModule}:${key.join(":")}`);
|
||||
if (!allowedDependencies.includes(moduleName)) throw new Error(`Module "${requesterModule}" tried to access service "${name}" without declaring dependency on "${moduleName}"`);
|
||||
function registerService(name: string, service: unknown): void {
|
||||
if (services[name]) throw new Error(`Service "${name}" already registered`);
|
||||
services[name] = service;
|
||||
}
|
||||
|
||||
function makeGetService(moduleName: string, module: IModuleServer) {
|
||||
return <T>(name: string): T => {
|
||||
const [dependency, ...key] = name.split(":");
|
||||
if (dependency !== "self") {
|
||||
if (!(module.dependencies ?? []).includes(dependency))
|
||||
throw new Error(
|
||||
`Module "${moduleName}" tried to access service "${name}" without declaring dependency on "${dependency}"`
|
||||
);
|
||||
trackDependency(moduleName, dependency);
|
||||
return getService<T>(name);
|
||||
}
|
||||
export function resetModuleRuntimeForTests(): void { modules.clear(); models.length = 0; setupOrder.length = 0; setupDone.clear(); visiting.clear(); internals.clear(); usedDependencies.clear(); for (const key of Object.keys(services)) delete services[key]; modelsInitialized = false; }
|
||||
return getService<T>(`${moduleName}:${key.join(":")}`);
|
||||
};
|
||||
}
|
||||
|
||||
function makeGetInternal(moduleName: string) {
|
||||
return <T>(requestedModule: string, key?: string): T => {
|
||||
if (requestedModule !== moduleName)
|
||||
throw new Error(`Module "${moduleName}" attempted to access private internal state`);
|
||||
const internal = internals.get(moduleName) ?? {};
|
||||
return (key ? internal[key] : internal) as T;
|
||||
};
|
||||
}
|
||||
|
||||
function getService<T>(name: string): T {
|
||||
const service = services[name];
|
||||
if (!service) throw new Error(`Service "${name}" not found`);
|
||||
return service as T;
|
||||
}
|
||||
|
||||
function trackDependency(moduleName: string, dependency: string): void {
|
||||
const used = usedDependencies.get(moduleName) ?? new Set<string>();
|
||||
used.add(dependency);
|
||||
usedDependencies.set(moduleName, used);
|
||||
}
|
||||
|
||||
function validateDependencies(): void {
|
||||
for (const [name, module] of modules) {
|
||||
const declared = new Set(module.dependencies ?? []);
|
||||
const used = usedDependencies.get(name) ?? new Set<string>();
|
||||
const undeclared = [...used].filter((dependency) => !declared.has(dependency));
|
||||
if (undeclared.length)
|
||||
throw new Error(`Module "${name}" used undeclared dependencies: ${undeclared.join(", ")}`);
|
||||
}
|
||||
}
|
||||
|
||||
function withTimeout<T>(promise: Promise<T>, timeoutMs: number, label: string): Promise<T> {
|
||||
let timeout: NodeJS.Timeout | undefined;
|
||||
const timeoutPromise = new Promise<T>((_, reject) => {
|
||||
timeout = setTimeout(
|
||||
() => reject(new Error(`Timeout after ${timeoutMs}ms (${label})`)),
|
||||
timeoutMs
|
||||
);
|
||||
});
|
||||
return Promise.race([promise, timeoutPromise]).finally(() => {
|
||||
if (timeout) clearTimeout(timeout);
|
||||
}) as Promise<T>;
|
||||
}
|
||||
|
||||
export function listServices(): string[] {
|
||||
return Object.keys(services);
|
||||
}
|
||||
|
||||
export function getServiceScoped<T>(
|
||||
requesterModule: string,
|
||||
allowedDependencies: readonly string[],
|
||||
name: string
|
||||
): T {
|
||||
const [moduleName, ...key] = name.split(":");
|
||||
if (moduleName === "self") return getService<T>(`${requesterModule}:${key.join(":")}`);
|
||||
if (!allowedDependencies.includes(moduleName))
|
||||
throw new Error(
|
||||
`Module "${requesterModule}" tried to access service "${name}" without declaring dependency on "${moduleName}"`
|
||||
);
|
||||
return getService<T>(name);
|
||||
}
|
||||
|
||||
export function resetModuleRuntimeForTests(): void {
|
||||
modules.clear();
|
||||
models.length = 0;
|
||||
setupOrder.length = 0;
|
||||
setupDone.clear();
|
||||
visiting.clear();
|
||||
internals.clear();
|
||||
usedDependencies.clear();
|
||||
|
||||
for (const key of Object.keys(services)) {
|
||||
delete services[key];
|
||||
}
|
||||
modelsInitialized = false;
|
||||
}
|
||||
|
||||
@ -8,10 +8,17 @@ export interface RecurringProformaOccurrenceProcessorCapability {
|
||||
}
|
||||
|
||||
export interface RecurringProformaDiscoveryCapability {
|
||||
findDue(dueThrough: Date, limit: number): Promise<{
|
||||
findDue(
|
||||
dueThrough: Date,
|
||||
limit: number
|
||||
): Promise<{
|
||||
isFailure: boolean;
|
||||
error: Error;
|
||||
data: readonly { recurringProformaId: UniqueID; companyId: UniqueID; nextOccurrenceDate: Date }[];
|
||||
data: readonly {
|
||||
recurringProformaId: UniqueID;
|
||||
companyId: UniqueID;
|
||||
nextOccurrenceDate: Date;
|
||||
}[];
|
||||
}>;
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
import Dinero, { type Currency } from "dinero.js";
|
||||
|
||||
import type { MoneyDTO } from "../dto";
|
||||
|
||||
type DineroPlain = { amount: number; precision: number; currency: string };
|
||||
//type DineroPlain = { amount: number; precision: number; currency: string };
|
||||
|
||||
const isEmptyMoneyDTO = (dto?: MoneyDTO | null) =>
|
||||
!dto || dto.value?.trim?.() === "" || dto.scale?.trim?.() === "";
|
||||
@ -149,40 +147,40 @@ export const MoneyDTOHelper = {
|
||||
/**
|
||||
* Convierte un DTO a una instancia Dinero.js.
|
||||
*/
|
||||
function dineroFromDTO(dto: MoneyDTO, fallbackCurrency = "EUR"): Dinero.Dinero {
|
||||
/*function dineroFromDTO(dto: MoneyDTO, fallbackCurrency = "EUR"): Dinero.Dinero {
|
||||
const n = normalizeDTO(dto, fallbackCurrency);
|
||||
return Dinero({
|
||||
amount: Number.parseInt(n.value, 10),
|
||||
precision: Number.parseInt(n.scale, 10),
|
||||
currency: n.currency_code as Currency,
|
||||
});
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Convierte una instancia Dinero a un DTO.
|
||||
*/
|
||||
function dtoFromDinero(d: Dinero.Dinero): MoneyDTO {
|
||||
/*function dtoFromDinero(d: Dinero.Dinero): MoneyDTO {
|
||||
const { amount, precision, currency } = d.toObject() as DineroPlain;
|
||||
return {
|
||||
value: amount.toString(),
|
||||
scale: precision.toString(),
|
||||
currency_code: currency,
|
||||
};
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Suma una lista de MoneyDTO.
|
||||
*/
|
||||
function sumDTO(list: MoneyDTO[], fallbackCurrency = "EUR"): MoneyDTO {
|
||||
/*function sumDTO(list: MoneyDTO[], fallbackCurrency = "EUR"): MoneyDTO {
|
||||
if (list.length === 0) return { value: "0", scale: "2", currency_code: fallbackCurrency };
|
||||
const sum = list.map((x) => dineroFromDTO(x, fallbackCurrency)).reduce((a, b) => a.add(b));
|
||||
return dtoFromDinero(sum);
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Multiplica un MoneyDTO por un número.
|
||||
*/
|
||||
function multiplyDTO(
|
||||
/*function multiplyDTO(
|
||||
dto: MoneyDTO,
|
||||
multiplier: number,
|
||||
rounding: Dinero.RoundingMode = "HALF_EVEN",
|
||||
@ -190,12 +188,12 @@ function multiplyDTO(
|
||||
): MoneyDTO {
|
||||
const d = dineroFromDTO(dto, fallbackCurrency).multiply(multiplier, rounding);
|
||||
return dtoFromDinero(d);
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Calcula un porcentaje de un MoneyDTO.
|
||||
*/
|
||||
function percentageDTO(
|
||||
/*function percentageDTO(
|
||||
dto: MoneyDTO,
|
||||
percent: number,
|
||||
rounding: Dinero.RoundingMode = "HALF_EVEN",
|
||||
@ -203,4 +201,4 @@ function percentageDTO(
|
||||
): MoneyDTO {
|
||||
const d = dineroFromDTO(dto, fallbackCurrency).percentage(percent, rounding);
|
||||
return dtoFromDinero(d);
|
||||
}
|
||||
}*/
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
export { Audit, type AuditDependencies } from "./audit";
|
||||
export type { AuditArray, AuditObject, AuditScalar, AuditState, AuditValue } from "./audit-state.types";
|
||||
export type {
|
||||
AuditActor,
|
||||
AuditChange,
|
||||
@ -11,6 +10,7 @@ export type {
|
||||
AuditMutationEntry,
|
||||
AuditMutationTarget,
|
||||
AuditOperation,
|
||||
AuditRecordOptions,
|
||||
AuditScope,
|
||||
AuditSource,
|
||||
IAudit,
|
||||
@ -22,6 +22,13 @@ export type {
|
||||
RecordAuditMutationInput,
|
||||
RecordAuditMutationShortcutInput,
|
||||
} from "./audit.types";
|
||||
export type {
|
||||
AuditArray,
|
||||
AuditObject,
|
||||
AuditScalar,
|
||||
AuditState,
|
||||
AuditValue,
|
||||
} from "./audit-state.types";
|
||||
export {
|
||||
AuditContextUnavailableError,
|
||||
AuditError,
|
||||
|
||||
@ -75,7 +75,7 @@ export class CriteriaFromUrlConverter {
|
||||
});
|
||||
|
||||
return Object.values(tempFilters).filter(
|
||||
(filter) =>
|
||||
(filter): filter is FiltersPrimitives =>
|
||||
filter.field !== undefined &&
|
||||
filter.operator !== undefined &&
|
||||
(filter.value !== undefined ||
|
||||
|
||||
@ -1 +1,4 @@
|
||||
export type IAggregateRootRepository = {};
|
||||
// biome-ignore lint/correctness/noUnusedVariables: <se necesita para definir la interfaz, aunque no se use directamente>
|
||||
export type IAggregateRootRepository<T> = {
|
||||
// Define the methods for the aggregate root repository
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user