limpieza
This commit is contained in:
parent
3b235c8cca
commit
b1f27e6f98
2
packages.bak/rdx-verifactu/.gitignore
vendored
2
packages.bak/rdx-verifactu/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
node_modules
|
||||
dist
|
||||
@ -1,12 +0,0 @@
|
||||
{
|
||||
"name": "rdx-verifactu",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"noEmit": false,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"incremental": false,
|
||||
"declaration": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"target": "ES2022"
|
||||
}
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
{
|
||||
"name": "@erp/{{kebabCase module}}",
|
||||
"version": "0.1.0",
|
||||
"main": "src/index.ts",
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"lint": "eslint . --ext .ts"
|
||||
}
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import { Presenter } from "@erp/core/api";
|
||||
import { {{pascalCase name}} } from "../../../domain";
|
||||
|
||||
export class {{pascalCase name}}FullPresenter extends Presenter<{{pascalCase name}}, any> {
|
||||
toOutput(entity: {{pascalCase name}}): any {
|
||||
return {
|
||||
id: entity.id.toPrimitive(),
|
||||
name: entity.name,
|
||||
metadata: { entity: "{{kebabCase name}}" }
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
import { Presenter } from "@erp/core/api";
|
||||
import { Criteria } from "@repo/rdx-criteria/server";
|
||||
import { Collection } from "@repo/rdx-utils";
|
||||
import { {{pascalCase name}} } from "../../../domain";
|
||||
|
||||
export class List{{pascalCase name}}sPresenter extends Presenter {
|
||||
private _mapEntity(entity: {{pascalCase name}}) {
|
||||
return { id: entity.id.toPrimitive(), name: entity.name };
|
||||
}
|
||||
|
||||
toOutput(params: { entities: Collection<{{pascalCase name}}>; criteria: Criteria }): any {
|
||||
const { entities, criteria } = params;
|
||||
return {
|
||||
page: criteria.pageNumber,
|
||||
per_page: criteria.pageSize,
|
||||
total_pages: Math.ceil(entities.total() / criteria.pageSize),
|
||||
total_items: entities.total(),
|
||||
items: entities.map((e) => this._mapEntity(e)),
|
||||
metadata: { entity: "{{kebabCase name}}s", criteria: criteria.toJSON() }
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
import { CompositeSpecification, UniqueID } from "@repo/rdx-ddd";
|
||||
import { I
|
||||
{
|
||||
pascalCase;
|
||||
name;
|
||||
}
|
||||
Repository;
|
||||
} from "../../domain/repositories"
|
||||
|
||||
export class {
|
||||
{
|
||||
pascalCase;
|
||||
name;
|
||||
}
|
||||
}NotExistsSpecification extends CompositeSpecification<UniqueID>
|
||||
{
|
||||
constructor(
|
||||
private readonly repo: I{{pascalCase name}}Repository,
|
||||
private readonly transaction?: unknown
|
||||
)
|
||||
super();
|
||||
|
||||
async;
|
||||
isSatisfiedBy(entityId: UniqueID)
|
||||
: Promise<boolean>
|
||||
{
|
||||
const existsOrError = await this.repo.existsById(entityId, this.transaction);
|
||||
if (existsOrError.isFailure) throw existsOrError.error;
|
||||
return existsOrError.data === false;
|
||||
}
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
import { CompositeSpecification } from "@repo/rdx-ddd";
|
||||
import { I
|
||||
{
|
||||
pascalCase;
|
||||
name;
|
||||
}
|
||||
Repository;
|
||||
} from "../../domain/repositories"
|
||||
|
||||
export class {
|
||||
{
|
||||
pascalCase;
|
||||
name;
|
||||
}
|
||||
}UniqueNameSpecification extends CompositeSpecification<string>
|
||||
{
|
||||
constructor(
|
||||
private readonly repo: I{{pascalCase name}}Repository,
|
||||
private readonly transaction?: unknown
|
||||
)
|
||||
super();
|
||||
|
||||
async;
|
||||
isSatisfiedBy(name: string)
|
||||
: Promise<boolean>
|
||||
{
|
||||
const criteria = { filters: { name } };
|
||||
const resultOrError = await this.repo.findByCriteria(criteria as any, this.transaction);
|
||||
if (resultOrError.isFailure) throw resultOrError.error;
|
||||
return resultOrError.data.total() === 0;
|
||||
}
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
import { IPresenterRegistry, ITransactionManager } from "@erp/core/api";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
import { I{{pascalCase name}}Repository } from "../../domain/repositories";
|
||||
import { {{pascalCase name}} } from "../../domain/aggregates";
|
||||
import { {{pascalCase name}}FullPresenter } from "../presenters";
|
||||
|
||||
type Create{{pascalCase name}}Input = { name: string };
|
||||
|
||||
export class Create{{pascalCase name}}UseCase {
|
||||
constructor(
|
||||
private readonly repo: I{{pascalCase name}}Repository,
|
||||
private readonly txManager: ITransactionManager,
|
||||
private readonly presenters: IPresenterRegistry
|
||||
) {}
|
||||
|
||||
public execute(params: Create{{pascalCase name}}Input) {
|
||||
return this.txManager.complete(async (tx) => {
|
||||
const entityOrError = {{pascalCase name}}.create({ name: params.name });
|
||||
if (entityOrError.isFailure) return Result.fail(entityOrError.error);
|
||||
|
||||
const savedOrError = await this.repo.save(entityOrError.data, tx);
|
||||
if (savedOrError.isFailure) return Result.fail(savedOrError.error);
|
||||
|
||||
const presenter = this.presenters.getPresenter({ resource: "{{kebabCase name}}", projection: "FULL" }) as {{pascalCase name}}FullPresenter;
|
||||
return Result.ok(presenter.toOutput(savedOrError.data));
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
import { AggregateRoot, UniqueID } from "@repo/rdx-ddd";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
|
||||
export interface I{{pascalCase name}}Props {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export class {{pascalCase name}} extends AggregateRoot<I{{pascalCase name}}Props> {
|
||||
static create(props: I{{pascalCase name}}Props, id?: UniqueID): Result<{{pascalCase name}}, Error> {
|
||||
const entity = new {{pascalCase name}}(props, id);
|
||||
return Result.ok(entity);
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
return this.props.name;
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
import { UniqueID } from "@repo/rdx-ddd";
|
||||
import { Result, Collection } from "@repo/rdx-utils";
|
||||
import { Criteria } from "@repo/rdx-criteria/server";
|
||||
import {
|
||||
{
|
||||
pascalCase;
|
||||
name;
|
||||
}
|
||||
} from "../aggregates"
|
||||
|
||||
export interface I{{pascalCase name}
|
||||
}Repository
|
||||
{
|
||||
save(entity: {{pascalCase name}}, transaction: unknown)
|
||||
: Promise<Result<
|
||||
pascalCase;
|
||||
name;
|
||||
, Error>>
|
||||
existsById(id: UniqueID, transaction?: unknown)
|
||||
: Promise<Result<boolean, Error>>
|
||||
getById(id: UniqueID, transaction?: unknown)
|
||||
: Promise<Result<
|
||||
pascalCase;
|
||||
name;
|
||||
, Error>>
|
||||
findByCriteria(criteria: Criteria, transaction?: unknown)
|
||||
: Promise<Result<Collection<
|
||||
pascalCase;
|
||||
name;
|
||||
>, Error>>
|
||||
deleteById(id: UniqueID, transaction: unknown)
|
||||
: Promise<Result<void, Error>>
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
import { ExpressController, authGuard, tenantGuard, forbidQueryFieldGuard } from "@erp/core/api";
|
||||
import { Create{{pascalCase name}}UseCase } from "../../../application";
|
||||
|
||||
/**
|
||||
* Controlador de creación
|
||||
* @remarks
|
||||
* - Aplica guards de autenticación, tenant y prohíbe `companyId` en query.
|
||||
*/
|
||||
export class Create{{pascalCase name}}Controller extends ExpressController {
|
||||
public constructor(private readonly useCase: Create{{pascalCase name}}UseCase) {
|
||||
super();
|
||||
this.useGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
protected async executeImpl() {
|
||||
const companyId = this.getTenantId();
|
||||
if (!companyId) return this.forbiddenError("Tenant ID not found");
|
||||
|
||||
// TODO: descomentar cuando exista DTO
|
||||
// const validation = validateRequest(Create{{pascalCase name}}Dto, this.req.body);
|
||||
// if (validation.isErr()) return this.badRequestError(validation.error.message);
|
||||
// const dto = validation.value;
|
||||
|
||||
const dto = this.req.body;
|
||||
const result = await this.useCase.execute({ companyId, ...dto });
|
||||
|
||||
return result.match(
|
||||
(data) => this.ok(data),
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
import { ExpressController, authGuard, tenantGuard, forbidQueryFieldGuard } from "@erp/core/api";
|
||||
import { Delete{{pascalCase name}}UseCase } from "../../../application";
|
||||
|
||||
/**
|
||||
* Controlador de borrado lógico/físico según políticas
|
||||
*/
|
||||
export class Delete{{pascalCase name}}Controller extends ExpressController {
|
||||
public constructor(private readonly useCase: Delete{{pascalCase name}}UseCase) {
|
||||
super();
|
||||
this.useGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
protected async executeImpl() {
|
||||
const companyId = this.getTenantId();
|
||||
if (!companyId) return this.forbiddenError("Tenant ID not found");
|
||||
|
||||
const { {{snakeCase name}}_id } = this.req.params as { {{snakeCase name}}_id: string };
|
||||
const result = await this.useCase.execute({ {{snakeCase name}}_id, companyId });
|
||||
|
||||
return result.match(
|
||||
(data) => this.ok(data),
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
import { ExpressController, authGuard, tenantGuard, forbidQueryFieldGuard } from "@erp/core/api";
|
||||
import { Get{{pascalCase name}}UseCase } from "../../../application";
|
||||
|
||||
/**
|
||||
* Controlador de lectura por id en el contexto del tenant
|
||||
*/
|
||||
export class Get{{pascalCase name}}Controller extends ExpressController {
|
||||
public constructor(private readonly useCase: Get{{pascalCase name}}UseCase) {
|
||||
super();
|
||||
this.useGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
protected async executeImpl() {
|
||||
const companyId = this.getTenantId();
|
||||
if (!companyId) return this.forbiddenError("Tenant ID not found");
|
||||
|
||||
const { {{snakeCase name}}_id } = this.req.params as { {{snakeCase name}}_id: string };
|
||||
const result = await this.useCase.execute({ {{snakeCase name}}_id, companyId });
|
||||
|
||||
return result.match(
|
||||
(data) => this.ok(data),
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
// Barrel de controllers
|
||||
export * from "./create-{{kebabCase name}}.controller";
|
||||
export * from "./delete-{{kebabCase name}}.controller";
|
||||
export * from "./get-{{kebabCase name}}.controller";
|
||||
export * from "./list-{{kebabCase name}}.controller";
|
||||
export * from "./update-{{kebabCase name}}.controller";
|
||||
@ -1,28 +0,0 @@
|
||||
import { ExpressController, authGuard, tenantGuard, forbidQueryFieldGuard } from "@erp/core/api";
|
||||
import { List{{pascalCase name}}UseCase } from "../../../application";
|
||||
|
||||
/**
|
||||
* Controlador de listado paginado por tenant
|
||||
*/
|
||||
export class List{{pascalCase name}}Controller extends ExpressController {
|
||||
public constructor(private readonly useCase: List{{pascalCase name}}UseCase) {
|
||||
super();
|
||||
this.useGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
protected async executeImpl() {
|
||||
const companyId = this.getTenantId();
|
||||
if (!companyId) return this.forbiddenError("Tenant ID not found");
|
||||
|
||||
// TODO: mapear query → criteria/pagination
|
||||
const criteria = this.req.query ?? {};
|
||||
const pagination = undefined;
|
||||
|
||||
const result = await this.useCase.execute({ companyId, criteria, pagination });
|
||||
|
||||
return result.match(
|
||||
(data) => this.ok(data),
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
import { ExpressController, authGuard, tenantGuard, forbidQueryFieldGuard } from "@erp/core/api";
|
||||
import { Update{{pascalCase name}}UseCase } from "../../../application";
|
||||
|
||||
/**
|
||||
* Controlador de actualización parcial/total
|
||||
*/
|
||||
export class Update{{pascalCase name}}Controller extends ExpressController {
|
||||
public constructor(private readonly useCase: Update{{pascalCase name}}UseCase) {
|
||||
super();
|
||||
this.useGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
protected async executeImpl() {
|
||||
const companyId = this.getTenantId();
|
||||
if (!companyId) return this.forbiddenError("Tenant ID not found");
|
||||
|
||||
const { {{snakeCase name}}_id } = this.req.params as { {{snakeCase name}}_id: string };
|
||||
|
||||
// TODO: descomentar cuando exista DTO
|
||||
// const validation = validateRequest(Update{{pascalCase name}}Dto, this.req.body);
|
||||
// if (validation.isErr()) return this.badRequestError(validation.error.message);
|
||||
// const dto = validation.value;
|
||||
|
||||
const dto = this.req.body;
|
||||
const result = await this.useCase.execute({ {{snakeCase name}}_id, companyId, ...dto });
|
||||
|
||||
return result.match(
|
||||
(data) => this.ok(data),
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
// Barrel de express
|
||||
export * from "./controllers";
|
||||
export * from "./{{kebabCase plural}}.routes";
|
||||
@ -1,33 +0,0 @@
|
||||
import { Router } from "express";
|
||||
import type { ModuleParams } from "@erp/core/api";
|
||||
import { build{{pascalCase name}}Dependencies } from "../repositories";
|
||||
import {
|
||||
Create{{pascalCase name}}Controller,
|
||||
Delete{{pascalCase name}}Controller,
|
||||
Get{{pascalCase name}}Controller,
|
||||
List{{pascalCase name}}Controller,
|
||||
Update{{pascalCase name}}Controller,
|
||||
} from "./controllers";
|
||||
|
||||
/**
|
||||
* Monta las rutas del módulo en `params.app` bajo `params.baseRoutePath/{{kebabCase plural}}`
|
||||
* @remarks
|
||||
* - Las validaciones DTO están comentadas hasta que existan en `common/dto`.
|
||||
*/
|
||||
export const mount{{pascalCase plural}}Routes = (params: ModuleParams) => {
|
||||
const router = Router();
|
||||
const deps = build{{pascalCase name}}Dependencies(params);
|
||||
|
||||
// TODO: descomentar cuando exista validateRequest y DTOs
|
||||
// const validateCreate = validateRequest(Create{{pascalCase name}}Dto);
|
||||
// const validateUpdate = validateRequest(Update{{pascalCase name}}Dto);
|
||||
|
||||
router.get("/", (req, res, next) => deps.build.list().bind(req, res, next));
|
||||
router.get("/:{{snakeCase name}}_id", (req, res, next) => deps.build.get().bind(req, res, next));
|
||||
router.post("/", /* validateCreate, */ (req, res, next) => deps.build.create().bind(req, res, next));
|
||||
router.patch("/:{{snakeCase name}}_id", /* validateUpdate, */ (req, res, next) => deps.build.update().bind(req, res, next));
|
||||
router.put("/:{{snakeCase name}}_id", /* validateUpdate, */ (req, res, next) => deps.build.update().bind(req, res, next));
|
||||
router.delete("/:{{snakeCase name}}_id", (req, res, next) => deps.build.delete().bind(req, res, next));
|
||||
|
||||
params.app.use(`${params.baseRoutePath}/{{kebabCase plural}}`, router);
|
||||
};
|
||||
@ -1,5 +0,0 @@
|
||||
// Barrel de infraestructura
|
||||
export * from "./express";
|
||||
export * from "./mappers";
|
||||
export * from "./repositories";
|
||||
export * from "./sequelize";
|
||||
@ -1 +0,0 @@
|
||||
export * from "./{{kebabCase name}}.mapper";
|
||||
@ -1,27 +0,0 @@
|
||||
import type { {{pascalCase name}} } from "../../../domain";
|
||||
import type { {{pascalCase name}}Model } from "../../sequelize/models/{{kebabCase name}}.model";
|
||||
|
||||
/**
|
||||
* Mapper de dominio ↔ ORM/DTO
|
||||
* @remarks
|
||||
* - SSOT: punto único de traducción entre capas.
|
||||
*/
|
||||
export const {{camelCase name}}DomainMapper = {
|
||||
toPersistence(entity: {{pascalCase name}}) {
|
||||
// TODO: mapear campos reales
|
||||
return {
|
||||
id: entity.id,
|
||||
company_id: entity.companyId,
|
||||
status: (entity as any).status ?? "active",
|
||||
};
|
||||
},
|
||||
|
||||
toDomain(model: {{pascalCase name}}Model): {{pascalCase name}} {
|
||||
// TODO: mapear campos reales
|
||||
return {
|
||||
id: model.id,
|
||||
companyId: model.company_id,
|
||||
status: (model as any).status,
|
||||
} as unknown as {{pascalCase name}};
|
||||
},
|
||||
};
|
||||
@ -1,2 +0,0 @@
|
||||
export * from "./domain";
|
||||
export * from "./queries";
|
||||
@ -1 +0,0 @@
|
||||
export * from "./{{kebabCase name}}.list.mapper";
|
||||
@ -1,13 +0,0 @@
|
||||
/**
|
||||
* Mapper para listados (read-models)
|
||||
*/
|
||||
export const {{camelCase name}}ListMapper = {
|
||||
toListItem(p: any) {
|
||||
// TODO: adaptar a la proyección real
|
||||
return {
|
||||
id: p.id,
|
||||
name: p.name ?? "",
|
||||
status: p.status ?? "active",
|
||||
};
|
||||
},
|
||||
};
|
||||
@ -1,43 +0,0 @@
|
||||
import { InMemoryMapperRegistry, InMemoryPresenterRegistry, SequelizeTransactionManager } from "@erp/core/api";
|
||||
import type { ModuleParams } from "@erp/core/api";
|
||||
import { {{pascalCase name}}Repository } from "./{{kebabCase name}}.repository";
|
||||
import { Create{{pascalCase name}}Controller, Delete{{pascalCase name}}Controller, Get{{pascalCase name}}Controller, List{{pascalCase name}}Controller, Update{{pascalCase name}}Controller } from "../express/controllers";
|
||||
// Los use-cases/servicios se resuelven desde application/domain (puede no compilar hasta que existan)
|
||||
import {
|
||||
Create{{pascalCase name}}UseCase,
|
||||
Delete{{pascalCase name}}UseCase,
|
||||
Get{{pascalCase name}}UseCase,
|
||||
List{{pascalCase name}}UseCase,
|
||||
Update{{pascalCase name}}UseCase,
|
||||
} from "../../application";
|
||||
import { {{pascalCase name}}Service } from "../../domain";
|
||||
|
||||
/**
|
||||
* Wiring/DI de infraestructura del módulo
|
||||
*/
|
||||
export const build{{pascalCase name}}Dependencies = (params: ModuleParams) => {
|
||||
const mapperRegistry = new InMemoryMapperRegistry();
|
||||
const presenterRegistry = new InMemoryPresenterRegistry();
|
||||
const transactionManager = new SequelizeTransactionManager(params.database);
|
||||
|
||||
const repository = new {{pascalCase name}}Repository(params.database);
|
||||
const service = new {{pascalCase name}}Service(repository);
|
||||
|
||||
// TODO: enlazar presenters reales cuando existan
|
||||
// presenterRegistry.register("{{camelCase name}}.created", ...);
|
||||
|
||||
return {
|
||||
mapperRegistry,
|
||||
presenterRegistry,
|
||||
transactionManager,
|
||||
repository,
|
||||
service,
|
||||
build: {
|
||||
list: () => new List{{pascalCase name}}Controller(new List{{pascalCase name}}UseCase(service)),
|
||||
get: () => new Get{{pascalCase name}}Controller(new Get{{pascalCase name}}UseCase(service)),
|
||||
create: () => new Create{{pascalCase name}}Controller(new Create{{pascalCase name}}UseCase(service)),
|
||||
update: () => new Update{{pascalCase name}}Controller(new Update{{pascalCase name}}UseCase(service)),
|
||||
delete: () => new Delete{{pascalCase name}}Controller(new Delete{{pascalCase name}}UseCase(service)),
|
||||
},
|
||||
};
|
||||
};
|
||||
@ -1,2 +0,0 @@
|
||||
export * from "./{{kebabCase name}}.repository";
|
||||
export * from "./dependencies";
|
||||
@ -1,36 +0,0 @@
|
||||
import type { Sequelize } from "sequelize";
|
||||
import { Result } from "@erp/core/api";
|
||||
import type { Criteria, Pagination } from "@erp/core/api";
|
||||
import type { I{{pascalCase name}}Repository, {{pascalCase name}} } from "../../domain";
|
||||
import type { {{pascalCase name}}Model } from "../sequelize/models/{{kebabCase name}}.model";
|
||||
|
||||
/**
|
||||
* Repositorio concreto (Sequelize)
|
||||
* @remarks
|
||||
* - Implementa métodos por tenant (companyId) desde el inicio.
|
||||
*/
|
||||
export class {{pascalCase name}}Repository implements I{{pascalCase name}}Repository {
|
||||
public constructor(private readonly database: Sequelize) {}
|
||||
|
||||
async create(entity: {{pascalCase name}}) {
|
||||
// TODO: usar mapper y modelo
|
||||
return Result.fail<{{pascalCase name}}>(new Error("Not implemented"));
|
||||
}
|
||||
|
||||
async update(entity: {{pascalCase name}}) {
|
||||
return Result.fail<{{pascalCase name}}>(new Error("Not implemented"));
|
||||
}
|
||||
|
||||
async deleteByIdInCompany(id: string, companyId: string) {
|
||||
return Result.fail<void>(new Error("Not implemented"));
|
||||
}
|
||||
|
||||
async findByIdInCompany(id: string, companyId: string) {
|
||||
return Result.fail<{{pascalCase name}}>(new Error("Not implemented"));
|
||||
}
|
||||
|
||||
async findByCriteriaInCompany(criteria: Criteria, companyId: string, pagination?: Pagination) {
|
||||
// TODO: aplicar where/order/limit/offset usando CriteriaToSequelizeConverter si existe en core
|
||||
return Result.fail<{ items: {{pascalCase name}}[]; total: number }>(new Error("Not implemented"));
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
// Barrel de sequelize y registro de modelos
|
||||
export * from "./models";
|
||||
import { init{{pascalCase name}}Model } from "./models";
|
||||
|
||||
export const models = [init{{pascalCase name}}Model];
|
||||
@ -1,2 +0,0 @@
|
||||
export { {{pascalCase name}}Model as {{pascalCase name}}Model } from "./{{kebabCase name}}.model";
|
||||
export { default as init{{pascalCase name}}Model } from "./{{kebabCase name}}.model";
|
||||
@ -1,64 +0,0 @@
|
||||
import {
|
||||
CreationOptional,
|
||||
DataTypes,
|
||||
InferAttributes,
|
||||
InferCreationAttributes,
|
||||
Model,
|
||||
Sequelize,
|
||||
} from "sequelize";
|
||||
|
||||
export type {{pascalCase name}}CreationAttributes = InferCreationAttributes<{{pascalCase name}}Model, {}> & {};
|
||||
|
||||
/**
|
||||
* Modelo Sequelize (infraestructura, no dominio)
|
||||
*/
|
||||
export class {{pascalCase name}}Model extends Model<
|
||||
InferAttributes<{{pascalCase name}}Model>,
|
||||
InferCreationAttributes<{{pascalCase name}}Model>
|
||||
> {
|
||||
declare id: string;
|
||||
declare company_id: string;
|
||||
declare status: CreationOptional<string>;
|
||||
declare created_at: CreationOptional<Date>;
|
||||
declare updated_at: CreationOptional<Date>;
|
||||
declare deleted_at: CreationOptional<Date | null>;
|
||||
|
||||
static associate(database: Sequelize) {
|
||||
// TODO: definir relaciones si aplica
|
||||
}
|
||||
|
||||
static hooks(database: Sequelize) {
|
||||
// TODO: definir hooks si aplica
|
||||
}
|
||||
}
|
||||
|
||||
export default (database: Sequelize) => {
|
||||
{{pascalCase name}}Model.init(
|
||||
{
|
||||
id: { type: DataTypes.UUID, primaryKey: true },
|
||||
company_id: { type: DataTypes.UUID, allowNull: false },
|
||||
status: { type: DataTypes.STRING, allowNull: false, defaultValue: "active" },
|
||||
created_at: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
||||
updated_at: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
||||
deleted_at: { type: DataTypes.DATE, allowNull: true, defaultValue: null },
|
||||
},
|
||||
{
|
||||
sequelize: database,
|
||||
tableName: "{{snakeCase plural}}",
|
||||
underscored: true,
|
||||
paranoid: true,
|
||||
timestamps: true,
|
||||
createdAt: "created_at",
|
||||
updatedAt: "updated_at",
|
||||
deletedAt: "deleted_at",
|
||||
indexes: [
|
||||
{ name: "company_idx", fields: ["company_id"], unique: false },
|
||||
{ name: "idx_company_idx", fields: ["id", "company_id"], unique: true },
|
||||
],
|
||||
whereMergeStrategy: "and",
|
||||
defaultScope: {},
|
||||
scopes: {},
|
||||
}
|
||||
);
|
||||
return {{pascalCase name}}Model;
|
||||
};
|
||||
@ -1,9 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"strict": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user