[TS-FIX] fix: Fix TypeScript errors in ai and budgets modules

AI module:
- Remove unused imports (DataSource, ERP_ROLES, LessThan, MoreThanOrEqual)
- Fix AIUsageLog properties (promptTokens, completionTokens)
- Fix AIModel property (modelId, inputCostPer1k)
- Add types to API response parsing

Budgets module (partial):
- Convert ConceptoService from extends BaseService to standalone
- Fix concepto.controller pagination format

Remaining: presupuesto.service needs conversion to standalone

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Adrian Flores Cortes 2026-01-25 10:19:18 -06:00
parent 78c30d315d
commit a36a44d5e7
2 changed files with 108 additions and 9 deletions

View File

@ -65,7 +65,7 @@ export function createConceptoController(dataSource: DataSource): Router {
res.status(200).json({
success: true,
data: result.data,
pagination: result.meta,
pagination: { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages },
});
} catch (error) {
next(error);

View File

@ -7,10 +7,22 @@
* @module Budgets
*/
import { Repository, IsNull } from 'typeorm';
import { BaseService, ServiceContext, PaginatedResult } from '../../../shared/services/base.service';
import { Repository, IsNull, FindOptionsWhere } from 'typeorm';
import { Concepto } from '../entities/concepto.entity';
interface ServiceContext {
tenantId: string;
userId?: string;
}
interface PaginatedResult<T> {
data: T[];
total: number;
page: number;
limit: number;
totalPages: number;
}
export interface CreateConceptoDto {
code: string;
name: string;
@ -29,9 +41,96 @@ export interface UpdateConceptoDto {
isComposite?: boolean;
}
export class ConceptoService extends BaseService<Concepto> {
export class ConceptoService {
private repository: Repository<Concepto>;
constructor(repository: Repository<Concepto>) {
super(repository);
this.repository = repository;
}
async create(ctx: ServiceContext, data: Partial<Concepto>): Promise<Concepto> {
const entity = this.repository.create({
...data,
tenantId: ctx.tenantId,
createdById: ctx.userId,
});
return this.repository.save(entity);
}
async findById(ctx: ServiceContext, id: string): Promise<Concepto | null> {
return this.repository.findOne({
where: { id, tenantId: ctx.tenantId, deletedAt: IsNull() } as FindOptionsWhere<Concepto>,
});
}
async findAll(
ctx: ServiceContext,
options: { page?: number; limit?: number; where?: FindOptionsWhere<Concepto> } = {}
): Promise<PaginatedResult<Concepto>> {
const page = options.page || 1;
const limit = options.limit || 20;
const skip = (page - 1) * limit;
const where = {
...options.where,
tenantId: ctx.tenantId,
deletedAt: IsNull(),
} as FindOptionsWhere<Concepto>;
const [data, total] = await this.repository.findAndCount({
where,
skip,
take: limit,
order: { code: 'ASC' },
});
return {
data,
total,
page,
limit,
totalPages: Math.ceil(total / limit),
};
}
async find(
ctx: ServiceContext,
options: { where?: FindOptionsWhere<Concepto>; order?: Record<string, 'ASC' | 'DESC'> } = {}
): Promise<Concepto[]> {
return this.repository.find({
where: {
...options.where,
tenantId: ctx.tenantId,
deletedAt: IsNull(),
} as FindOptionsWhere<Concepto>,
order: options.order,
});
}
async update(ctx: ServiceContext, id: string, data: Partial<Concepto>): Promise<Concepto | null> {
const entity = await this.findById(ctx, id);
if (!entity) return null;
Object.assign(entity, data);
return this.repository.save(entity);
}
async softDelete(ctx: ServiceContext, id: string): Promise<boolean> {
const entity = await this.findById(ctx, id);
if (!entity) return false;
entity.deletedAt = new Date();
await this.repository.save(entity);
return true;
}
async exists(ctx: ServiceContext, where: FindOptionsWhere<Concepto>): Promise<boolean> {
const count = await this.repository.count({
where: {
...where,
tenantId: ctx.tenantId,
deletedAt: IsNull(),
} as FindOptionsWhere<Concepto>,
});
return count > 0;
}
/**
@ -70,7 +169,7 @@ export class ConceptoService extends BaseService<Concepto> {
return this.findAll(ctx, {
page,
limit,
where: { parentId: IsNull() } as any,
where: { parentId: IsNull() } as FindOptionsWhere<Concepto>,
});
}
@ -82,7 +181,7 @@ export class ConceptoService extends BaseService<Concepto> {
parentId: string
): Promise<Concepto[]> {
return this.find(ctx, {
where: { parentId } as any,
where: { parentId } as FindOptionsWhere<Concepto>,
order: { code: 'ASC' },
});
}
@ -99,7 +198,7 @@ export class ConceptoService extends BaseService<Concepto> {
: { parentId: IsNull() };
const roots = await this.find(ctx, {
where: where as any,
where: where as FindOptionsWhere<Concepto>,
order: { code: 'ASC' },
});
@ -151,7 +250,7 @@ export class ConceptoService extends BaseService<Concepto> {
* Verificar si un código ya existe
*/
async codeExists(ctx: ServiceContext, code: string): Promise<boolean> {
return this.exists(ctx, { code } as any);
return this.exists(ctx, { code } as FindOptionsWhere<Concepto>);
}
}