Refactor controllers to remove redundant guards and improve code clarity

- Removed authentication and company context guards from multiple controllers in the customer, proforma, document series, and supplier modules.
- Consolidated guard registration logic in routes to enforce company ID restrictions globally.
- Cleaned up imports and ensured consistent error handling across controllers.
This commit is contained in:
David Arranz 2026-09-09 00:43:34 +02:00
parent bf1dd43c78
commit b2a9836436
90 changed files with 157 additions and 846 deletions

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { CreatePaymentMethodRequestDTO } from "../../../../../common";
import type { CreatePaymentMethodUseCase } from "../../../../application";
@ -16,11 +11,6 @@ export class CreatePaymentMethodController extends ExpressController {
this.errorMapper = paymentMethodsApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { DeletePaymentMethodByIdUseCase } from "../../../../application";
import { paymentMethodsApiErrorMapper } from "../payment-methods-api-error-mapper";
@ -15,11 +10,6 @@ export class DeletePaymentMethodByIdController extends ExpressController {
this.errorMapper = paymentMethodsApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { DisablePaymentMethodByIdUseCase } from "../../../../application";
import { paymentMethodsApiErrorMapper } from "../payment-methods-api-error-mapper";
@ -15,11 +10,6 @@ export class DisablePaymentMethodByIdController extends ExpressController {
this.errorMapper = paymentMethodsApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { EnablePaymentMethodByIdUseCase } from "../../../../application";
import { paymentMethodsApiErrorMapper } from "../payment-methods-api-error-mapper";
@ -15,11 +10,6 @@ export class EnablePaymentMethodByIdController extends ExpressController {
this.errorMapper = paymentMethodsApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { GetPaymentMethodByIdUseCase } from "../../../../application";
import { paymentMethodsApiErrorMapper } from "../payment-methods-api-error-mapper";
@ -15,11 +10,6 @@ export class GetPaymentMethodByIdController extends ExpressController {
this.errorMapper = paymentMethodsApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import { Criteria } from "@repo/rdx-criteria/server";
import type { ListPaymentMethodsUseCase } from "../../../../application";
@ -15,11 +10,6 @@ export class ListPaymentMethodsController extends ExpressController {
this.errorMapper = paymentMethodsApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
private getCriteriaWithDefaultOrder() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { SetDefaultPaymentMethodByIdUseCase } from "../../../../application";
import { paymentMethodsApiErrorMapper } from "../payment-methods-api-error-mapper";
@ -13,12 +8,6 @@ export class SetDefaultPaymentMethodByIdController extends ExpressController {
super();
this.errorMapper = paymentMethodsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,10 +1,5 @@
import type { UpdatePaymentMethodByIdRequestDTO } from "@erp/catalogs/common";
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UpdatePaymentMethodByIdUseCase } from "../../../../application";
import { paymentMethodsApiErrorMapper } from "../payment-methods-api-error-mapper";
@ -16,11 +11,6 @@ export class UpdatePaymentMethodByIdController extends ExpressController {
this.errorMapper = paymentMethodsApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {
const companyId = this.getTenantId();

View File

@ -1,4 +1,4 @@
import { type StartParams, validateRequest } from "@erp/core/api";
import { type StartParams, forbidQueryFieldGuard, validateRequest } from "@erp/core/api";
import { requireIdentityTenantMembership } from "@erp/identity/api";
import { type NextFunction, type Request, type Response, Router } from "express";
@ -33,6 +33,7 @@ export const paymentMethodsRouter = (params: StartParams) => {
// ----------------------------------------------
router.use(...requireIdentityTenantMembership(params));
router.use(forbidQueryFieldGuard("companyId"));
// ----------------------------------------------

View File

@ -1,10 +1,5 @@
import type { CreatePaymentTermRequestDTO } from "@erp/catalogs/common";
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { CreatePaymentTermUseCase } from "../../../../application/payment-terms";
import { paymentTermsApiErrorMapper } from "../payment-terms-api-error-mapper";
@ -14,12 +9,6 @@ export class CreatePaymentTermController extends ExpressController {
super();
this.errorMapper = paymentTermsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { DeletePaymentTermByIdUseCase } from "../../../../application/payment-terms";
import { paymentTermsApiErrorMapper } from "../payment-terms-api-error-mapper";
@ -13,12 +8,6 @@ export class DeletePaymentTermByIdController extends ExpressController {
super();
this.errorMapper = paymentTermsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { DisablePaymentTermByIdUseCase } from "../../../../application/payment-terms";
import { paymentTermsApiErrorMapper } from "../payment-terms-api-error-mapper";
@ -13,12 +8,6 @@ export class DisablePaymentTermByIdController extends ExpressController {
super();
this.errorMapper = paymentTermsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { EnablePaymentTermByIdUseCase } from "../../../../application/payment-terms";
import { paymentTermsApiErrorMapper } from "../payment-terms-api-error-mapper";
@ -13,12 +8,6 @@ export class EnablePaymentTermByIdController extends ExpressController {
super();
this.errorMapper = paymentTermsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { GetPaymentTermByIdUseCase } from "../../../../application/payment-terms";
import { paymentTermsApiErrorMapper } from "../payment-terms-api-error-mapper";
@ -13,12 +8,6 @@ export class GetPaymentTermByIdController extends ExpressController {
super();
this.errorMapper = paymentTermsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import { Criteria } from "@repo/rdx-criteria/server";
import type { ListPaymentTermsUseCase } from "../../../../application/payment-terms";
@ -14,12 +9,6 @@ export class ListPaymentTermsController extends ExpressController {
super();
this.errorMapper = paymentTermsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
private getCriteriaWithDefaultOrder() {

View File

@ -1,10 +1,5 @@
import type { UpdatePaymentTermByIdRequestDTO } from "@erp/catalogs/common";
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UpdatePaymentTermByIdUseCase } from "../../../../application/payment-terms";
import { paymentTermsApiErrorMapper } from "../payment-terms-api-error-mapper";
@ -14,12 +9,6 @@ export class UpdatePaymentTermByIdController extends ExpressController {
super();
this.errorMapper = paymentTermsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,4 +1,4 @@
import { type StartParams, validateRequest } from "@erp/core/api";
import { type StartParams, forbidQueryFieldGuard, validateRequest } from "@erp/core/api";
import { requireIdentityTenantMembership } from "@erp/identity/api";
import type { NextFunction, Request, Response } from "express";
import { Router } from "express";
@ -30,6 +30,7 @@ export const paymentTermsRouter = (params: StartParams) => {
const router = Router({ mergeParams: true });
router.use(...requireIdentityTenantMembership(params));
router.use(forbidQueryFieldGuard("companyId"));
router.get(
"/",

View File

@ -1,10 +1,5 @@
import type { CreateTaxDefinitionRequestDTO } from "@erp/catalogs/common";
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { CreateTaxDefinitionUseCase } from "../../../../application/tax-definitions";
import { taxDefinitionsApiErrorMapper } from "../tax-definitions-api-error-mapper";
@ -14,12 +9,6 @@ export class CreateTaxDefinitionController extends ExpressController {
super();
this.errorMapper = taxDefinitionsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { DeleteTaxDefinitionByIdUseCase } from "../../../../application/tax-definitions";
import { taxDefinitionsApiErrorMapper } from "../tax-definitions-api-error-mapper";
@ -13,12 +8,6 @@ export class DeleteTaxDefinitionByIdController extends ExpressController {
super();
this.errorMapper = taxDefinitionsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { DisableTaxDefinitionByIdUseCase } from "../../../../application/tax-definitions";
import { taxDefinitionsApiErrorMapper } from "../tax-definitions-api-error-mapper";
@ -13,12 +8,6 @@ export class DisableTaxDefinitionByIdController extends ExpressController {
super();
this.errorMapper = taxDefinitionsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { EnableTaxDefinitionByIdUseCase } from "../../../../application/tax-definitions";
import { taxDefinitionsApiErrorMapper } from "../tax-definitions-api-error-mapper";
@ -13,12 +8,6 @@ export class EnableTaxDefinitionByIdController extends ExpressController {
super();
this.errorMapper = taxDefinitionsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { GetTaxDefinitionByIdUseCase } from "../../../../application/tax-definitions";
import { taxDefinitionsApiErrorMapper } from "../tax-definitions-api-error-mapper";
@ -13,12 +8,6 @@ export class GetTaxDefinitionByIdController extends ExpressController {
super();
this.errorMapper = taxDefinitionsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import { Criteria } from "@repo/rdx-criteria/server";
import type { ListTaxDefinitionsUseCase } from "../../../../application/tax-definitions";
@ -14,12 +9,6 @@ export class ListTaxDefinitionsController extends ExpressController {
super();
this.errorMapper = taxDefinitionsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
private getCriteriaWithDefaultOrder() {

View File

@ -1,10 +1,5 @@
import type { UpdateTaxDefinitionByIdRequestDTO } from "@erp/catalogs/common";
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UpdateTaxDefinitionByIdUseCase } from "../../../../application/tax-definitions";
import { taxDefinitionsApiErrorMapper } from "../tax-definitions-api-error-mapper";
@ -14,12 +9,6 @@ export class UpdateTaxDefinitionByIdController extends ExpressController {
super();
this.errorMapper = taxDefinitionsApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,4 +1,4 @@
import { type StartParams, validateRequest } from "@erp/core/api";
import { type StartParams, forbidQueryFieldGuard, validateRequest } from "@erp/core/api";
import { requireIdentityTenantMembership } from "@erp/identity/api";
import type { NextFunction, Request, Response } from "express";
import { Router } from "express";
@ -30,6 +30,7 @@ export const taxDefinitionsRouter = (params: StartParams) => {
const router = Router({ mergeParams: true });
router.use(...requireIdentityTenantMembership(params));
router.use(forbidQueryFieldGuard("companyId"));
router.get(
"/",

View File

@ -1,10 +1,5 @@
import type { CreateTaxRegimeRequestDTO } from "@erp/catalogs/common";
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { CreateTaxRegimeUseCase } from "../../../../application/tax-regimes";
import { taxRegimesApiErrorMapper } from "../tax-regime-api-error-mapper";
@ -14,12 +9,6 @@ export class CreateTaxRegimeController extends ExpressController {
super();
this.errorMapper = taxRegimesApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { DeleteTaxRegimeByIdUseCase } from "../../../../application";
import { taxRegimesApiErrorMapper } from "../tax-regime-api-error-mapper";
@ -13,12 +8,6 @@ export class DeleteTaxRegimeByIdController extends ExpressController {
super();
this.errorMapper = taxRegimesApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { DisableTaxRegimeByIdUseCase } from "../../../../application";
import { taxRegimesApiErrorMapper } from "../tax-regime-api-error-mapper";
@ -13,12 +8,6 @@ export class DisableTaxRegimeByIdController extends ExpressController {
super();
this.errorMapper = taxRegimesApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { EnableTaxRegimeByIdUseCase } from "../../../../application";
import { taxRegimesApiErrorMapper } from "../tax-regime-api-error-mapper";
@ -13,12 +8,6 @@ export class EnableTaxRegimeByIdController extends ExpressController {
super();
this.errorMapper = taxRegimesApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { GetTaxRegimeByIdUseCase } from "../../../../application";
import { taxRegimesApiErrorMapper } from "../tax-regime-api-error-mapper";
@ -13,12 +8,6 @@ export class GetTaxRegimeByIdController extends ExpressController {
super();
this.errorMapper = taxRegimesApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import { Criteria } from "@repo/rdx-criteria/server";
import type { ListTaxRegimesUseCase } from "../../../../application";
@ -14,12 +9,6 @@ export class ListTaxRegimesController extends ExpressController {
super();
this.errorMapper = taxRegimesApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
private getCriteriaWithDefaultOrder() {

View File

@ -1,10 +1,5 @@
import type { UpdateTaxRegimeByIdRequestDTO } from "@erp/catalogs/common";
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UpdateTaxRegimeByIdUseCase } from "../../../../application";
import { taxRegimesApiErrorMapper } from "../tax-regime-api-error-mapper";
@ -14,12 +9,6 @@ export class UpdateTaxRegimeByIdController extends ExpressController {
super();
this.errorMapper = taxRegimesApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,4 +1,4 @@
import { type StartParams, validateRequest } from "@erp/core/api";
import { type StartParams, forbidQueryFieldGuard, validateRequest } from "@erp/core/api";
import { requireIdentityTenantMembership } from "@erp/identity/api";
import type { NextFunction, Request, Response } from "express";
import { Router } from "express";
@ -30,6 +30,7 @@ export const taxRegimesRouter = (params: StartParams) => {
const router = Router({ mergeParams: true });
router.use(...requireIdentityTenantMembership(params));
router.use(forbidQueryFieldGuard("companyId"));
router.get(
"/",

View File

@ -1,4 +1,4 @@
import { ExpressController, requireAuthenticatedGuard } from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { CreateCompanyRequestDTO } from "../../../../common";
import type { CreateCompanyUseCase } from "../../../application";
@ -8,7 +8,6 @@ export class CreateCompanyController extends ExpressController {
public constructor(private readonly useCase: CreateCompanyUseCase) {
super();
this.errorMapper = companiesApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard());
}
protected async executeImpl() {

View File

@ -1,8 +1,4 @@
import {
ExpressController,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { DisableCompanyUseCase } from "../../../application";
import { companiesApiErrorMapper } from "../companies-api-error-mapper";
@ -11,13 +7,12 @@ export class DisableCompanyController extends ExpressController {
public constructor(private readonly useCase: DisableCompanyUseCase) {
super();
this.errorMapper = companiesApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard(), requireCompanyContextGuard());
}
protected async executeImpl() {
const tenantId = this.getTenantId();
const { company_id } = this.req.params;
if (!company_id || !tenantId) {
if (!(company_id && tenantId)) {
return this.invalidInputError("Company ID missing");
}

View File

@ -1,8 +1,4 @@
import {
ExpressController,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { EnableCompanyUseCase } from "../../../application";
import { companiesApiErrorMapper } from "../companies-api-error-mapper";
@ -11,13 +7,12 @@ export class EnableCompanyController extends ExpressController {
public constructor(private readonly useCase: EnableCompanyUseCase) {
super();
this.errorMapper = companiesApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard(), requireCompanyContextGuard());
}
protected async executeImpl() {
const tenantId = this.getTenantId();
const { company_id } = this.req.params;
if (!company_id || !tenantId) {
if (!(company_id && tenantId)) {
return this.invalidInputError("Company ID missing");
}

View File

@ -1,4 +1,4 @@
import { ExpressController, requireAuthenticatedGuard } from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { FindAvailableCompaniesForAccountUseCase } from "../../../application";
import { companiesApiErrorMapper } from "../companies-api-error-mapper";
@ -7,7 +7,6 @@ export class FindAvailableCompaniesController extends ExpressController {
public constructor(private readonly useCase: FindAvailableCompaniesForAccountUseCase) {
super();
this.errorMapper = companiesApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard());
}
protected async executeImpl() {

View File

@ -1,8 +1,4 @@
import {
ExpressController,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { GetCompanyByIdUseCase } from "../../../application";
import { companiesApiErrorMapper } from "../companies-api-error-mapper";
@ -11,13 +7,12 @@ export class GetCompanyByIdController extends ExpressController {
public constructor(private readonly useCase: GetCompanyByIdUseCase) {
super();
this.errorMapper = companiesApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard(), requireCompanyContextGuard());
}
protected async executeImpl() {
const tenantId = this.getTenantId();
const { company_id } = this.req.params;
if (!company_id || !tenantId) {
if (!(company_id && tenantId)) {
return this.invalidInputError("Company ID missing");
}

View File

@ -1,8 +1,4 @@
import {
ExpressController,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { GetCurrentCompanyUseCase } from "../../../application";
import { companiesApiErrorMapper } from "../companies-api-error-mapper";
@ -11,7 +7,6 @@ export class GetCurrentCompanyController extends ExpressController {
public constructor(private readonly useCase: GetCurrentCompanyUseCase) {
super();
this.errorMapper = companiesApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard(), requireCompanyContextGuard());
}
protected async executeImpl() {

View File

@ -1,8 +1,4 @@
import {
ExpressController,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UpdateCompanyRequestDTO } from "../../../../common";
import type { UpdateCompanyUseCase } from "../../../application";
@ -12,13 +8,12 @@ export class UpdateCompanyController extends ExpressController {
public constructor(private readonly useCase: UpdateCompanyUseCase) {
super();
this.errorMapper = companiesApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard(), requireCompanyContextGuard());
}
protected async executeImpl() {
const tenantId = this.getTenantId();
const { company_id } = this.req.params;
if (!company_id || !tenantId) {
if (!(company_id && tenantId)) {
return this.invalidInputError("Company ID missing");
}

View File

@ -1,8 +1,4 @@
import {
ExpressController,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UpdateCurrentCompanyRequestDTO } from "../../../../common";
import type { UpdateCurrentCompanyUseCase } from "../../../application";
@ -12,7 +8,6 @@ export class UpdateCurrentCompanyController extends ExpressController {
public constructor(private readonly useCase: UpdateCurrentCompanyUseCase) {
super();
this.errorMapper = companiesApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard(), requireCompanyContextGuard());
}
protected async executeImpl() {

View File

@ -1,5 +1,5 @@
import type { Criteria } from "@repo/rdx-criteria/server";
import type { NextFunction, Request, Response } from "express";
import type { NextFunction, Request, RequestHandler, Response } from "express";
import {
type ApiError,
@ -7,7 +7,7 @@ import {
UnauthorizedApiError,
ValidationApiError,
} from "./errors";
import type { ExpressController } from "./express-controller";
import { ExpressController } from "./express-controller";
export type GuardResultLike = { isFailure: boolean; error?: ApiError };
@ -53,12 +53,16 @@ export function requireCompanyContextGuard(): GuardFn {
Impide que el cliente intente fijar el 'companyId' vía query (?companyId=...).
La política de scoping real debe hacerse en repos/servicios; esto es defensa adicional.
*/
export function forbidQueryFieldGuard(field = "companyId"): GuardFn {
return ({ req }: GuardContext) => {
if (Object.hasOwn(req.query, field)) {
return guardFail(new ValidationApiError(`Query param "${field}" is not allowed`));
export function forbidQueryFieldGuard(field = "companyId"): RequestHandler {
return (req, res, next) => {
if (Object.hasOwn(req.query ?? {}, field)) {
return ExpressController.errorResponse(
new ValidationApiError(`Query param "${field}" is not allowed`),
req,
res
);
}
return guardOk();
return next();
};
}

View File

@ -1,9 +1,10 @@
import { type StartParams, validateRequest } from "@erp/core/api";
import { type StartParams, forbidQueryFieldGuard, validateRequest } from "@erp/core/api";
import { requireIdentityTenant } from "@erp/identity/api";
import { type NextFunction, type Request, type Response, Router } from "express";
import { UpdateCompanyVerifactuProfileRequestSchema } from "../../../../common";
import type { CompanyVerifactuProfileInternalDeps } from "../di";
import {
GetCompanyVerifactuProfileController,
UpdateCompanyVerifactuProfileController,
@ -19,6 +20,8 @@ export const companyVerifactuProfileRouter = (params: StartParams) => {
const router = Router({ mergeParams: true });
router.use(...requireIdentityTenant(params));
router.use(forbidQueryFieldGuard("companyId"));
router.use(forbidQueryFieldGuard("company_id"));
router.get("/", (req: Request, res: Response, next: NextFunction) => {
const controller = new GetCompanyVerifactuProfileController(

View File

@ -1,21 +1,10 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { GetCompanyVerifactuProfileUseCase } from "../../../../application";
export class GetCompanyVerifactuProfileController extends ExpressController {
public constructor(private readonly useCase: GetCompanyVerifactuProfileUseCase) {
super();
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId"),
forbidQueryFieldGuard("company_id")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UpdateCompanyVerifactuProfileRequestDTO } from "../../../../../common";
import type { UpdateCompanyVerifactuProfileUseCase } from "../../../../application";
@ -11,12 +6,6 @@ import type { UpdateCompanyVerifactuProfileUseCase } from "../../../../applicati
export class UpdateCompanyVerifactuProfileController extends ExpressController {
public constructor(private readonly useCase: UpdateCompanyVerifactuProfileUseCase) {
super();
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId"),
forbidQueryFieldGuard("company_id")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { GetIssuedInvoiceByIdUseCase } from "../../../../application/issued-invoices/index.ts";
import { issuedInvoicesApiErrorMapper } from "../issued-invoices-api-error-mapper.ts";
@ -14,11 +9,6 @@ export class GetIssuedInvoiceByIdController extends ExpressController {
this.errorMapper = issuedInvoicesApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import { Criteria } from "@repo/rdx-criteria/server";
import { ListIssuedInvoicesResponseSchema } from "../../../../../common/index.ts";
@ -16,11 +11,6 @@ export class ListIssuedInvoicesController extends ExpressController {
this.errorMapper = issuedInvoicesApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
private getCriteriaWithDefaultOrder() {

View File

@ -1,10 +1,4 @@
import {
ExpressController,
type RendererFormat,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { ReportIssueInvoiceByIdQueryRequestDTO } from "../../../../../common";
import type { ReportIssuedInvoiceUseCase } from "../../../../application/index.ts";
@ -16,11 +10,6 @@ export class ReportIssuedInvoiceController extends ExpressController {
this.errorMapper = issuedInvoicesApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,4 +1,4 @@
import { type StartParams, validateRequest } from "@erp/core/api";
import { type StartParams, forbidQueryFieldGuard, validateRequest } from "@erp/core/api";
import { requireIdentityTenant } from "@erp/identity/api";
import { type NextFunction, type Request, type Response, Router } from "express";
@ -17,7 +17,7 @@ import {
} from "./controllers";
export const issuedInvoicesRouter = (params: StartParams) => {
const { app, config, getService, getInternal } = params;
const { app, config, getInternal } = params;
const deps = getInternal<IssuedInvoicesInternalDeps>("customer-invoices", "issuedInvoices");
@ -26,6 +26,7 @@ export const issuedInvoicesRouter = (params: StartParams) => {
// ----------------------------------------------
router.use(...requireIdentityTenant(params));
router.use(forbidQueryFieldGuard("companyId"));
// ----------------------------------------------

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { ArchiveProformaByIdUseCase } from "../../../../application";
import { proformasApiErrorMapper } from "../proformas-api-error-mapper";
@ -12,11 +7,6 @@ export class ArchiveProformaByIdController extends ExpressController {
public constructor(private readonly useCase: ArchiveProformaByIdUseCase) {
super();
this.errorMapper = proformasApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { ChangeStatusProformaByIdRequestDTO } from "../../../../../common/dto";
import type { ChangeStatusProformaUseCase } from "../../../../application";
@ -15,11 +10,6 @@ export class ChangeStatusProformaController extends ExpressController {
this.errorMapper = proformasApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { CreateProformaRequestDTO } from "../../../../../common/dto/index.ts";
import type { CreateProformaUseCase } from "../../../../application/index.ts";
@ -15,11 +10,6 @@ export class CreateProformaController extends ExpressController {
this.errorMapper = proformasApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { DeleteProformaByIdUseCase } from "../../../../application/index.ts";
import { proformasApiErrorMapper } from "../proformas-api-error-mapper.ts";
@ -14,11 +9,6 @@ export class DeleteProformaController extends ExpressController {
this.errorMapper = proformasApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,14 +1,9 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import {
type DuplicateProformaByIdParamsRequestDTO,
DuplicateProformaByIdParamsRequestSchema,
DuplicateProformaByIdResponseSchema,
type DuplicateProformaByIdParamsRequestDTO,
} from "../../../../../common";
import type { DuplicateProformaByIdUseCase } from "../../../../application";
import { proformasApiErrorMapper } from "../proformas-api-error-mapper";
@ -17,12 +12,6 @@ export class DuplicateProformaByIdController extends ExpressController {
public constructor(private readonly useCase: DuplicateProformaByIdUseCase) {
super();
this.errorMapper = proformasApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { GetProformaByIdUseCase } from "../../../../application/index.ts";
import { proformasApiErrorMapper } from "../proformas-api-error-mapper.ts";
@ -14,11 +9,6 @@ export class GetProformaByIdController extends ExpressController {
this.errorMapper = proformasApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import { GetProformaIssuanceReadinessResponseSchema } from "../../../../../common";
import type { GetProformaIssuanceReadinessUseCase } from "../../../../application";
@ -13,12 +8,6 @@ export class GetProformaIssuanceReadinessController extends ExpressController {
public constructor(private readonly useCase: GetProformaIssuanceReadinessUseCase) {
super();
this.errorMapper = proformasApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import { IssueProformaByIdResponseSchema } from "../../../../../common";
import type { IssueProformaUseCase } from "../../../../application/proformas";
@ -19,11 +14,6 @@ export class IssueProformaController extends ExpressController {
this.errorMapper = proformasApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import { Criteria } from "@repo/rdx-criteria/server";
import type { ListProformasUseCase, ProformaListScope } from "../../../../application/index.ts";
@ -31,11 +26,6 @@ export class ListProformasController extends ExpressController {
this.errorMapper = proformasApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
private getCriteriaWithDefaultOrder() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { PreviewProformaReportUseCase } from "../../../../application";
import { proformasApiErrorMapper } from "../proformas-api-error-mapper.ts";
@ -12,11 +7,6 @@ export class PreviewProformaReportController extends ExpressController {
public constructor(private readonly useCase: PreviewProformaReportUseCase) {
super();
this.errorMapper = proformasApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { ReportProformaPdfUseCase } from "../../../../application";
import { proformasApiErrorMapper } from "../proformas-api-error-mapper.ts";
@ -12,11 +7,6 @@ export class ReportProformaPdfController extends ExpressController {
public constructor(private readonly useCase: ReportProformaPdfUseCase) {
super();
this.errorMapper = proformasApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UnarchiveProformaByIdUseCase } from "../../../../application";
import { proformasApiErrorMapper } from "../proformas-api-error-mapper";
@ -12,11 +7,6 @@ export class UnarchiveProformaByIdController extends ExpressController {
public constructor(private readonly useCase: UnarchiveProformaByIdUseCase) {
super();
this.errorMapper = proformasApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UpdateProformaByIdRequestDTO } from "../../../../../common/dto";
import type { UpdateProformaByIdUseCase } from "../../../../application";
@ -15,11 +10,6 @@ export class UpdateProformaController extends ExpressController {
this.errorMapper = proformasApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,4 +1,4 @@
import { type StartParams, validateRequest } from "@erp/core/api";
import { type StartParams, forbidQueryFieldGuard, validateRequest } from "@erp/core/api";
import { requireIdentityTenant } from "@erp/identity/api";
import { type NextFunction, type Request, type Response, Router } from "express";
@ -20,6 +20,7 @@ import {
ChangeStatusProformaByIdParamsRequestSchema,
ChangeStatusProformaByIdRequestSchema,
CreateProformaRequestSchema,
CreateRecurringProformaFromProformaRequestSchema,
DeleteProformaByIdParamsRequestSchema,
DuplicateProformaByIdParamsRequestSchema,
GetProformaByIdRequestSchema,
@ -32,7 +33,6 @@ import {
UnarchiveProformaByIdParamsRequestSchema,
UpdateProformaByIdParamsRequestSchema,
UpdateProformaByIdRequestSchema,
CreateRecurringProformaFromProformaRequestSchema,
} from "../../../../common";
import type { IIssuedInvoicePublicServices } from "../../../application";
import { CreateRecurringProformaFromProformaController } from "../../recurring-proformas/express/controllers";
@ -59,6 +59,7 @@ export const proformasRouter = (params: StartParams) => {
// ----------------------------------------------
router.use(...requireIdentityTenant(params));
router.use(forbidQueryFieldGuard("companyId"));
// ----------------------------------------------
@ -181,6 +182,7 @@ export const proformasRouter = (params: StartParams) => {
router.post(
"/:proforma_id/recurring-proforma",
validateRequest(GetProformaByIdRequestSchema, "params"),
forbidQueryFieldGuard("company_id"),
validateRequest(CreateRecurringProformaFromProformaRequestSchema, "body"),
(req: Request, res: Response, next: NextFunction) => {
const controller = new CreateRecurringProformaFromProformaController(

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import { UniqueID } from "@repo/rdx-ddd";
import type { CreateRecurringProformaFromProformaRequestDTO } from "../../../../../common";
@ -12,17 +7,9 @@ import { proformasApiErrorMapper } from "../../../proformas/express/proformas-ap
import { parseDateOnly } from "../mappers/parse-date-only";
export class CreateRecurringProformaFromProformaController extends ExpressController {
public constructor(
private readonly fromProforma: RecurringProformaCommands["fromProforma"]
) {
public constructor(private readonly fromProforma: RecurringProformaCommands["fromProforma"]) {
super();
this.errorMapper = proformasApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId"),
forbidQueryFieldGuard("company_id")
);
}
protected async executeImpl() {
@ -37,8 +24,7 @@ export class CreateRecurringProformaFromProformaController extends ExpressContro
if (startDate.isFailure) return this.invalidInputError(startDate.error.message);
const endDate = body.schedule.endDate;
const parsedEndDate =
typeof endDate === "string" ? parseDateOnly(endDate) : undefined;
const parsedEndDate = typeof endDate === "string" ? parseDateOnly(endDate) : undefined;
if (parsedEndDate?.isFailure) {
return this.invalidInputError(parsedEndDate.error.message);
}

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { CreateCustomerRequestDTO } from "../../../../common/dto";
import type { CreateCustomerUseCase } from "../../../application";
@ -13,13 +8,6 @@ export class CreateCustomerController extends ExpressController {
public constructor(private readonly useCase: CreateCustomerUseCase) {
super();
this.errorMapper = customersApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { DeleteCustomerUseCase } from "../../../application";
import { customersApiErrorMapper } from "../customer-api-error-mapper";
@ -12,13 +7,6 @@ export class DeleteCustomerController extends ExpressController {
public constructor(private readonly useCase: DeleteCustomerUseCase) {
super();
this.errorMapper = customersApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
async executeImpl(): Promise<any> {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { GetCustomerByIdUseCase } from "@erp/customers/api/application";
import { customersApiErrorMapper } from "../customer-api-error-mapper";
@ -12,13 +7,6 @@ export class GetCustomerController extends ExpressController {
public constructor(private readonly useCase: GetCustomerByIdUseCase) {
super();
this.errorMapper = customersApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import { Criteria } from "@repo/rdx-criteria/server";
import type { ListCustomersUseCase } from "../../../application";
@ -13,13 +8,6 @@ export class ListCustomersController extends ExpressController {
public constructor(private readonly useCase: ListCustomersUseCase) {
super();
this.errorMapper = customersApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
private getCriteriaWithDefaultOrder() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UpdateCustomerByIdRequestDTO } from "../../../../common/dto";
import type { UpdateCustomerUseCase } from "../../../application";
@ -13,13 +8,6 @@ export class UpdateCustomerController extends ExpressController {
public constructor(private readonly useCase: UpdateCustomerUseCase) {
super();
this.errorMapper = customersApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,4 +1,4 @@
import { type StartParams, validateRequest } from "@erp/core/api";
import { type StartParams, forbidQueryFieldGuard, validateRequest } from "@erp/core/api";
import { requireIdentityTenant } from "@erp/identity/api";
import { type NextFunction, type Request, type Response, Router } from "express";
@ -30,6 +30,7 @@ export const customersRouter = (params: StartParams) => {
// 🔐 Autenticación + Tenancy para TODO el router
router.use(...requireIdentityTenant(params));
router.use(forbidQueryFieldGuard("companyId"));
// ----------------------------------------------

View File

@ -1,9 +1,4 @@
import {
ExpressController,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { buildTransactionManager } from "@erp/core/api";
import { ExpressController, type buildTransactionManager } from "@erp/core/api";
import type { AssignNextDocumentNumberRequestDTO } from "../../../../common";
import type { AssignNextDocumentNumberUseCase } from "../../../application";
@ -16,15 +11,11 @@ export class AssignNextDocumentNumberController extends ExpressController {
) {
super();
this.errorMapper = documentSeriesApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard(), requireCompanyContextGuard());
}
protected async executeImpl() {
const companyId = this.getTenantId();
if (!companyId) {
return this.forbiddenError("Tenant ID not found");
}
if (!companyId) return this.forbiddenError("Tenant ID not found");
const result = await this.transactionManager.complete((transaction: unknown) =>
this.useCase.execute({
companyId: companyId.toString(),
@ -32,7 +23,6 @@ export class AssignNextDocumentNumberController extends ExpressController {
transaction,
})
);
return result.match(
(data) => this.ok(data),
(error) => this.handleError(error)

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { CreateDocumentSeriesRequestDTO } from "../../../../common";
import type { CreateDocumentSeriesUseCase } from "../../../application";
@ -13,12 +8,6 @@ export class CreateDocumentSeriesController extends ExpressController {
public constructor(private readonly useCase: CreateDocumentSeriesUseCase) {
super();
this.errorMapper = documentSeriesApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId"),
forbidQueryFieldGuard("company_id")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { DisableDocumentSeriesUseCase } from "../../../application";
import { documentSeriesApiErrorMapper } from "../document-series-api-error-mapper";
@ -12,12 +7,6 @@ export class DisableDocumentSeriesController extends ExpressController {
public constructor(private readonly useCase: DisableDocumentSeriesUseCase) {
super();
this.errorMapper = documentSeriesApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId"),
forbidQueryFieldGuard("company_id")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { GetDocumentSeriesByIdUseCase } from "../../../application";
import { documentSeriesApiErrorMapper } from "../document-series-api-error-mapper";
@ -12,12 +7,6 @@ export class GetDocumentSeriesByIdController extends ExpressController {
public constructor(private readonly useCase: GetDocumentSeriesByIdUseCase) {
super();
this.errorMapper = documentSeriesApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId"),
forbidQueryFieldGuard("company_id")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import { Criteria } from "@repo/rdx-criteria/server";
import type { ListDocumentSeriesUseCase } from "../../../application";
@ -13,12 +8,6 @@ export class ListDocumentSeriesController extends ExpressController {
public constructor(private readonly useCase: ListDocumentSeriesUseCase) {
super();
this.errorMapper = documentSeriesApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId"),
forbidQueryFieldGuard("company_id")
);
}
protected async executeImpl() {
@ -28,7 +17,14 @@ export class ListDocumentSeriesController extends ExpressController {
}
const { filters, pageNumber, pageSize, quickSearch } = this.criteria;
const criteria = Criteria.fromPrimitives(filters.toPrimitives(), "code", "ASC", pageSize, pageNumber, quickSearch);
const criteria = Criteria.fromPrimitives(
filters.toPrimitives(),
"code",
"ASC",
pageSize,
pageNumber,
quickSearch
);
const result = await this.useCase.execute({
companyId: companyId.toString(),

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UpdateDocumentSeriesRequestDTO } from "../../../../common";
import type { UpdateDocumentSeriesUseCase } from "../../../application";
@ -13,12 +8,6 @@ export class UpdateDocumentSeriesController extends ExpressController {
public constructor(private readonly useCase: UpdateDocumentSeriesUseCase) {
super();
this.errorMapper = documentSeriesApiErrorMapper;
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId"),
forbidQueryFieldGuard("company_id")
);
}
protected async executeImpl() {

View File

@ -1,4 +1,9 @@
import { type StartParams, buildTransactionManager, validateRequest } from "@erp/core/api";
import {
type StartParams,
buildTransactionManager,
forbidQueryFieldGuard,
validateRequest,
} from "@erp/core/api";
import { requireIdentityTenant } from "@erp/identity/api";
import { type NextFunction, type Request, type Response, Router } from "express";
@ -28,13 +33,20 @@ export const documentSeriesRouter = (params: StartParams) => {
router.use(...requireIdentityTenant(params));
router.get("/", (req: Request, res: Response, next: NextFunction) => {
const controller = new ListDocumentSeriesController(deps.useCases.listDocumentSeries());
return controller.execute(req, res, next);
});
router.get(
"/",
forbidQueryFieldGuard("companyId"),
forbidQueryFieldGuard("company_id"),
(req: Request, res: Response, next: NextFunction) => {
const controller = new ListDocumentSeriesController(deps.useCases.listDocumentSeries());
return controller.execute(req, res, next);
}
);
router.get(
"/:id",
forbidQueryFieldGuard("companyId"),
forbidQueryFieldGuard("company_id"),
validateRequest(GetDocumentSeriesByIdRequestSchema, "params"),
(req: Request, res: Response, next: NextFunction) => {
const controller = new GetDocumentSeriesByIdController(deps.useCases.getDocumentSeriesById());
@ -44,6 +56,8 @@ export const documentSeriesRouter = (params: StartParams) => {
router.post(
"/",
forbidQueryFieldGuard("companyId"),
forbidQueryFieldGuard("company_id"),
validateRequest(CreateDocumentSeriesRequestSchema, "body"),
(req: Request, res: Response, next: NextFunction) => {
const controller = new CreateDocumentSeriesController(deps.useCases.createDocumentSeries());

View File

@ -9,13 +9,6 @@ export class CreateProformaFromFactugesController extends ExpressController {
public constructor(private readonly useCase: CreateProformaFromFactugesUseCase) {
super();
this.errorMapper = factugesApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
/*this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);*/
}
protected async executeImpl() {

View File

@ -1,7 +1,10 @@
import { ExpressController, requireAuthenticatedGuard } from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UtcDateTime } from "@repo/rdx-ddd";
import type { ChangeAccountPasswordRequestDTO, ChangeAccountPasswordResponseDTO } from "../../../../common";
import type {
ChangeAccountPasswordRequestDTO,
ChangeAccountPasswordResponseDTO,
} from "../../../../common";
import type { ChangeCurrentAccountPasswordUseCase } from "../../../application/accounts";
import { identityAccountApiErrorMapper } from "../identity-account-api-error-mapper";
@ -12,7 +15,6 @@ export class ChangeCurrentAccountPasswordController extends ExpressController {
) {
super();
this.errorMapper = identityAccountApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard());
}
protected async executeImpl() {

View File

@ -1,4 +1,4 @@
import { ExpressController, requireAuthenticatedGuard } from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { GetAccountProfileResponseDTO } from "../../../../common";
import type { GetCurrentAccountUseCase } from "../../../application/accounts";
@ -8,7 +8,6 @@ export class GetCurrentAccountController extends ExpressController {
public constructor(private readonly useCase: GetCurrentAccountUseCase) {
super();
this.errorMapper = identityAccountApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard());
}
protected async executeImpl() {

View File

@ -1,4 +1,4 @@
import { ExpressController, requireAuthenticatedGuard } from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { CurrentSessionResponseDTO } from "../../../../common";
import type { GetCurrentSessionUseCase } from "../../../application";
@ -8,7 +8,6 @@ export class GetCurrentSessionController extends ExpressController {
public constructor(private readonly useCase: GetCurrentSessionUseCase) {
super();
this.errorMapper = identityAuthApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard());
}
protected async executeImpl() {

View File

@ -1,4 +1,4 @@
import { ExpressController, requireAuthenticatedGuard } from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UtcDateTime } from "@repo/rdx-ddd";
import type { LogoutRequestDTO, LogoutResponseDTO } from "../../../../common";
@ -12,7 +12,6 @@ export class LogoutController extends ExpressController {
) {
super();
this.errorMapper = identityAuthApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard());
}
protected async executeImpl() {

View File

@ -1,7 +1,10 @@
import { ExpressController, requireAuthenticatedGuard } from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UtcDateTime } from "@repo/rdx-ddd";
import type { UpdateAccountProfileRequestDTO, UpdateAccountProfileResponseDTO } from "../../../../common";
import type {
UpdateAccountProfileRequestDTO,
UpdateAccountProfileResponseDTO,
} from "../../../../common";
import type { UpdateCurrentAccountUseCase } from "../../../application/accounts";
import { identityAccountApiErrorMapper } from "../identity-account-api-error-mapper";
@ -12,7 +15,6 @@ export class UpdateCurrentAccountController extends ExpressController {
) {
super();
this.errorMapper = identityAccountApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard());
}
protected async executeImpl() {

View File

@ -1,8 +1,4 @@
import {
ExpressController,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { ChangeSupplierStatusUseCase } from "../../../application";
import { suppliersApiErrorMapper } from "../supplier-api-error-mapper";
@ -11,7 +7,6 @@ export class ChangeSupplierStatusController extends ExpressController {
public constructor(private readonly useCase: ChangeSupplierStatusUseCase) {
super();
this.errorMapper = suppliersApiErrorMapper;
this.registerGuards(requireAuthenticatedGuard(), requireCompanyContextGuard());
}
protected async executeImpl() {

View File

@ -1,14 +1,9 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { CreateSupplierRequestDTO } from "../../../../common/dto";
import type { CreateSupplierUseCase } from "../../../application";
import { suppliersApiErrorMapper } from "../supplier-api-error-mapper";
import type { CreateSupplierRequestMapper } from "../mappers/create-supplier-request.mapper";
import { suppliersApiErrorMapper } from "../supplier-api-error-mapper";
export class CreateSupplierController extends ExpressController {
public constructor(
@ -17,13 +12,6 @@ export class CreateSupplierController extends ExpressController {
) {
super();
this.errorMapper = suppliersApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { GetSupplierByIdUseCase } from "../../../application";
import { suppliersApiErrorMapper } from "../supplier-api-error-mapper";
@ -12,13 +7,6 @@ export class GetSupplierController extends ExpressController {
public constructor(private readonly useCase: GetSupplierByIdUseCase) {
super();
this.errorMapper = suppliersApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,9 +1,4 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import { Criteria } from "@repo/rdx-criteria/server";
import type { ListSuppliersUseCase } from "../../../application";
@ -13,13 +8,6 @@ export class ListSuppliersController extends ExpressController {
public constructor(private readonly listSuppliers: ListSuppliersUseCase) {
super();
this.errorMapper = suppliersApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
private getCriteriaWithDefaultOrder() {

View File

@ -10,6 +10,7 @@ import {
UpdateSupplierByIdRequestSchema,
} from "../../../../common";
import { UpdateSupplierByIdRequestMapper } from "../mappers/update-supplier-by-id-request.mapper";
import { UpdateSupplierController } from "./update-supplier.controller";
const companyId = UniqueID.create("22222222-2222-4222-8222-222222222222").data;

View File

@ -1,14 +1,9 @@
import {
ExpressController,
forbidQueryFieldGuard,
requireAuthenticatedGuard,
requireCompanyContextGuard,
} from "@erp/core/api";
import { ExpressController } from "@erp/core/api";
import type { UpdateSupplierByIdRequestDTO } from "../../../../common/dto";
import type { UpdateSupplierUseCase } from "../../../application";
import { suppliersApiErrorMapper } from "../supplier-api-error-mapper";
import type { UpdateSupplierByIdRequestMapper } from "../mappers/update-supplier-by-id-request.mapper";
import { suppliersApiErrorMapper } from "../supplier-api-error-mapper";
export class UpdateSupplierController extends ExpressController {
public constructor(
@ -17,13 +12,6 @@ export class UpdateSupplierController extends ExpressController {
) {
super();
this.errorMapper = suppliersApiErrorMapper;
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
this.registerGuards(
requireAuthenticatedGuard(),
requireCompanyContextGuard(),
forbidQueryFieldGuard("companyId")
);
}
protected async executeImpl() {

View File

@ -1,4 +1,4 @@
import { type StartParams, validateRequest } from "@erp/core/api";
import { type StartParams, forbidQueryFieldGuard, validateRequest } from "@erp/core/api";
import { requireIdentityTenant } from "@erp/identity/api";
import { type NextFunction, type Request, type Response, Router } from "express";
@ -34,6 +34,7 @@ export const suppliersRouter = (params: StartParams) => {
// Mantiene el mismo pipeline de identidad y tenant que los módulos HTTP actuales.
router.use(...requireIdentityTenant(params));
router.use(forbidQueryFieldGuard("companyId"));
// ----------------------------------------------