[TS-FIX] fix: Fix TypeScript errors in admin and bidding modules

- Add ServiceContext interface to base.service.ts
- Fix admin module: audit-log, backup, cost-center, system-setting
  - Define ServiceContext and PaginatedResult locally
  - Convert services from extends BaseService to standalone
  - Change PaginatedResult from meta format to flat format
  - Fix controllers to use flat pagination format
- Fix bidding module: bid, bid-budget, opportunity
  - Change PaginatedResult from meta format to flat format
  - Fix controllers to use flat pagination format

Modules with remaining errors: finance, payment-terminals, estimates,
mcp, reports, progress, budgets, ai, hse (563 errors total)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Adrian Flores Cortes 2026-01-25 10:10:00 -06:00
parent f14829d2ce
commit 99064f5f24
15 changed files with 212 additions and 65 deletions

View File

@ -15,7 +15,11 @@ import { AuditLog } from '../entities/audit-log.entity';
import { User } from '../../core/entities/user.entity';
import { Tenant } from '../../core/entities/tenant.entity';
import { RefreshToken } from '../../auth/entities/refresh-token.entity';
import { ServiceContext } from '../../../shared/services/base.service';
interface ServiceContext {
tenantId: string;
userId?: string;
}
export function createAuditLogController(dataSource: DataSource): Router {
const router = Router();
@ -74,7 +78,7 @@ export function createAuditLogController(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);
@ -164,7 +168,7 @@ export function createAuditLogController(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);
@ -194,7 +198,7 @@ export function createAuditLogController(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

@ -15,7 +15,11 @@ import { Backup } from '../entities/backup.entity';
import { User } from '../../core/entities/user.entity';
import { Tenant } from '../../core/entities/tenant.entity';
import { RefreshToken } from '../../auth/entities/refresh-token.entity';
import { ServiceContext } from '../../../shared/services/base.service';
interface ServiceContext {
tenantId: string;
userId?: string;
}
export function createBackupController(dataSource: DataSource): Router {
const router = Router();
@ -69,7 +73,7 @@ export function createBackupController(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

@ -15,7 +15,11 @@ import { CostCenter } from '../entities/cost-center.entity';
import { User } from '../../core/entities/user.entity';
import { Tenant } from '../../core/entities/tenant.entity';
import { RefreshToken } from '../../auth/entities/refresh-token.entity';
import { ServiceContext } from '../../../shared/services/base.service';
interface ServiceContext {
tenantId: string;
userId?: string;
}
export function createCostCenterController(dataSource: DataSource): Router {
const router = Router();
@ -69,7 +73,7 @@ export function createCostCenterController(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

@ -15,7 +15,11 @@ import { SystemSetting } from '../entities/system-setting.entity';
import { User } from '../../core/entities/user.entity';
import { Tenant } from '../../core/entities/tenant.entity';
import { RefreshToken } from '../../auth/entities/refresh-token.entity';
import { ServiceContext } from '../../../shared/services/base.service';
interface ServiceContext {
tenantId: string;
userId?: string;
}
export function createSystemSettingController(dataSource: DataSource): Router {
const router = Router();
@ -65,7 +69,7 @@ export function createSystemSettingController(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,9 +7,21 @@
*/
import { Repository } from 'typeorm';
import { ServiceContext, PaginatedResult } from '../../../shared/services/base.service';
import { AuditLog, AuditCategory, AuditAction, AuditSeverity } from '../entities/audit-log.entity';
interface ServiceContext {
tenantId: string;
userId?: string;
}
interface PaginatedResult<T> {
data: T[];
total: number;
page: number;
limit: number;
totalPages: number;
}
export interface CreateAuditLogDto {
userId?: string;
category: AuditCategory;
@ -138,12 +150,10 @@ export class AuditLogService {
return {
data,
meta: {
total,
page,
limit,
totalPages: Math.ceil(total / limit),
},
total,
page,
limit,
totalPages: Math.ceil(total / limit),
};
}

View File

@ -7,9 +7,21 @@
*/
import { Repository } from 'typeorm';
import { BaseService, ServiceContext, PaginatedResult } from '../../../shared/services/base.service';
import { Backup, BackupType, BackupStatus, BackupStorage } from '../entities/backup.entity';
interface ServiceContext {
tenantId: string;
userId?: string;
}
interface PaginatedResult<T> {
data: T[];
total: number;
page: number;
limit: number;
totalPages: number;
}
export interface CreateBackupDto {
backupType: BackupType;
name: string;
@ -33,9 +45,38 @@ export interface BackupFilters {
dateTo?: Date;
}
export class BackupService extends BaseService<Backup> {
export class BackupService {
private repository: Repository<Backup>;
constructor(repository: Repository<Backup>) {
super(repository);
this.repository = repository;
}
async create(ctx: ServiceContext, data: Partial<Backup>): Promise<Backup> {
const entity = this.repository.create({
...data,
tenantId: ctx.tenantId,
createdById: ctx.userId,
});
return this.repository.save(entity);
}
async findById(ctx: ServiceContext, id: string): Promise<Backup | null> {
return this.repository.findOne({
where: { id, tenantId: ctx.tenantId } as any,
});
}
async update(ctx: ServiceContext, id: string, data: Partial<Backup>): Promise<Backup | 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 result = await this.repository.delete({ id, tenantId: ctx.tenantId } as any);
return (result.affected || 0) > 0;
}
/**
@ -81,12 +122,10 @@ export class BackupService extends BaseService<Backup> {
return {
data,
meta: {
total,
page,
limit,
totalPages: Math.ceil(total / limit),
},
total,
page,
limit,
totalPages: Math.ceil(total / limit),
};
}

View File

@ -7,9 +7,21 @@
*/
import { Repository } from 'typeorm';
import { BaseService, ServiceContext, PaginatedResult } from '../../../shared/services/base.service';
import { CostCenter, CostCenterType, CostCenterLevel } from '../entities/cost-center.entity';
interface ServiceContext {
tenantId: string;
userId?: string;
}
interface PaginatedResult<T> {
data: T[];
total: number;
page: number;
limit: number;
totalPages: number;
}
export interface CreateCostCenterDto {
code: string;
name: string;
@ -42,9 +54,41 @@ export interface CostCenterFilters {
search?: string;
}
export class CostCenterService extends BaseService<CostCenter> {
export class CostCenterService {
private repository: Repository<CostCenter>;
constructor(repository: Repository<CostCenter>) {
super(repository);
this.repository = repository;
}
async create(ctx: ServiceContext, data: Partial<CostCenter>): Promise<CostCenter> {
const entity = this.repository.create({
...data,
tenantId: ctx.tenantId,
createdById: ctx.userId,
});
return this.repository.save(entity);
}
async findById(ctx: ServiceContext, id: string): Promise<CostCenter | null> {
return this.repository.findOne({
where: { id, tenantId: ctx.tenantId, deletedAt: null } as any,
});
}
async update(ctx: ServiceContext, id: string, data: Partial<CostCenter>): Promise<CostCenter | 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;
}
/**
@ -100,12 +144,10 @@ export class CostCenterService extends BaseService<CostCenter> {
return {
data,
meta: {
total,
page,
limit,
totalPages: Math.ceil(total / limit),
},
total,
page,
limit,
totalPages: Math.ceil(total / limit),
};
}

View File

@ -7,9 +7,21 @@
*/
import { Repository } from 'typeorm';
import { BaseService, ServiceContext, PaginatedResult } from '../../../shared/services/base.service';
import { SystemSetting, SettingCategory, SettingDataType } from '../entities/system-setting.entity';
interface ServiceContext {
tenantId: string;
userId?: string;
}
interface PaginatedResult<T> {
data: T[];
total: number;
page: number;
limit: number;
totalPages: number;
}
export interface CreateSettingDto {
key: string;
name: string;
@ -43,9 +55,37 @@ export interface SettingFilters {
search?: string;
}
export class SystemSettingService extends BaseService<SystemSetting> {
export class SystemSettingService {
private repository: Repository<SystemSetting>;
constructor(repository: Repository<SystemSetting>) {
super(repository);
this.repository = repository;
}
async create(ctx: ServiceContext, data: Partial<SystemSetting>): Promise<SystemSetting> {
const entity = this.repository.create({
...data,
tenantId: ctx.tenantId,
});
return this.repository.save(entity);
}
async findById(ctx: ServiceContext, id: string): Promise<SystemSetting | null> {
return this.repository.findOne({
where: { id, tenantId: ctx.tenantId } as any,
});
}
async update(ctx: ServiceContext, id: string, data: Partial<SystemSetting>): Promise<SystemSetting | null> {
const entity = await this.findById(ctx, id);
if (!entity) return null;
Object.assign(entity, data);
return this.repository.save(entity);
}
async hardDelete(ctx: ServiceContext, id: string): Promise<boolean> {
const result = await this.repository.delete({ id, tenantId: ctx.tenantId } as any);
return (result.affected || 0) > 0;
}
/**
@ -117,12 +157,10 @@ export class SystemSettingService extends BaseService<SystemSetting> {
return {
data,
meta: {
total,
page,
limit,
totalPages: Math.ceil(total / limit),
},
total,
page,
limit,
totalPages: Math.ceil(total / limit),
};
}

View File

@ -74,7 +74,7 @@ export function createBidBudgetController(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

@ -76,7 +76,7 @@ export function createBidController(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

@ -77,7 +77,7 @@ export function createOpportunityController(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

@ -190,12 +190,10 @@ export class BidBudgetService {
return {
data,
meta: {
total,
page,
limit,
totalPages: Math.ceil(total / limit),
},
total,
page,
limit,
totalPages: Math.ceil(total / limit),
};
}

View File

@ -162,12 +162,10 @@ export class BidService {
return {
data,
meta: {
total,
page,
limit,
totalPages: Math.ceil(total / limit),
},
total,
page,
limit,
totalPages: Math.ceil(total / limit),
};
}

View File

@ -200,12 +200,10 @@ export class OpportunityService {
return {
data,
meta: {
total,
page,
limit,
totalPages: Math.ceil(total / limit),
},
total,
page,
limit,
totalPages: Math.ceil(total / limit),
};
}

View File

@ -2,6 +2,14 @@ import { query, queryOne, getClient, PoolClient } from '../../config/database.js
import { NotFoundError, ValidationError } from '../errors/index.js';
import { PaginationMeta } from '../types/index.js';
/**
* Contexto de servicio para multi-tenant
*/
export interface ServiceContext {
tenantId: string;
userId?: string;
}
/**
* Resultado paginado genérico
*/