Files
lcbp3/backend/src/modules/ai/tool/drawing-tool.service.ts
T
admin a0b9b55130
CI / CD Pipeline / build (push) Failing after 4m8s
CI / CD Pipeline / deploy (push) Has been skipped
690519:2118 224 to 226 AI #03
2026-05-19 21:18:48 +07:00

90 lines
3.6 KiB
TypeScript

// File: src/modules/ai/tool/drawing-tool.service.ts
// Change Log
// - 2026-05-19: สร้าง DrawingToolService — Tool Handler สำหรับ Intent GET_DRAWING (ADR-025, ADR-016, ADR-019).
import { Injectable, Logger } from '@nestjs/common';
import { AbilityFactory } from '../../../common/auth/casl/ability.factory';
import { ShopDrawingService } from '../../drawing/shop-drawing.service';
import { UuidResolverService } from '../../../common/services/uuid-resolver.service';
import { ToolCallResult } from './types/tool-call-result.type';
import { ToolHandlerContext } from './types/tool-handler-context.type';
import { DrawingToolResult } from './types/drawing-tool-result.type';
interface ShopDrawingTransformed {
publicId: string;
drawingNumber?: string;
title?: string;
status?: string;
currentRevision?: {
revisionLabel?: string;
};
}
@Injectable()
export class DrawingToolService {
private readonly logger = new Logger(DrawingToolService.name);
constructor(
private readonly shopDrawingService: ShopDrawingService,
private readonly abilityFactory: AbilityFactory,
private readonly uuidResolver: UuidResolverService
) {}
/**
* ดึงข้อมูล Drawing (Shop Drawing) สำหรับ LLM context
* - ตรวจสอบสิทธิ์ด้วย CASL (ADR-016)
* - คืนเฉพาะ publicId + metadata ตาม ADR-019
* - จัดการ error แบบ Graceful Degradation (ADR-007)
*/
async getDrawing(
context: ToolHandlerContext
): Promise<ToolCallResult<DrawingToolResult[]>> {
// ตรวจสอบสิทธิ์ด้วย CASL ก่อนดึงข้อมูล
const ability = this.abilityFactory.createForUser(context.requestUser, {});
if (!ability.can('read', 'drawing')) {
this.logger.warn(
`ผู้ใช้ ${context.requestUser.publicId} ไม่มีสิทธิ์อ่าน Drawing`
);
return {
ok: false,
reason: 'FORBIDDEN',
message: 'คุณไม่มีสิทธิ์อ่านข้อมูล Drawing ในโครงการนี้',
};
}
try {
// ดึงข้อมูล Shop Drawing (ใช้ projectUuid ตาม ADR-019)
const result = await this.shopDrawingService.findAll({
projectUuid: context.projectPublicId,
page: 1,
limit: 20,
});
// Map ผลลัพธ์ไปยัง DrawingToolResult — ห้าม expose integer id (ADR-019)
const data = result.data as unknown as ShopDrawingTransformed[];
const toolResults: DrawingToolResult[] = data
.filter((drawing) => drawing.publicId)
.map((drawing) => {
const latestRev = drawing.currentRevision;
return {
publicId: drawing.publicId,
drawingNumber: drawing.drawingNumber ?? '',
title: drawing.title ?? '',
statusCode: drawing.status ?? 'UNKNOWN',
drawingType: 'SHOP' as const,
latestRevision: latestRev?.revisionLabel ?? null,
contractPublicId: '', // เพิ่มภายหลังเมื่อ contract มี publicId
};
});
return { ok: true, data: toolResults };
} catch (error: unknown) {
this.logger.error(
`DrawingToolService.getDrawing เกิดข้อผิดพลาด: ${(error as Error).message}`
);
return {
ok: false,
reason: 'SERVICE_ERROR',
message: 'เกิดข้อผิดพลาดในการดึงข้อมูล Drawing กรุณาลองใหม่',
};
}
}
}