690409:0953 Done Task-BE-AI-02
CI / CD Pipeline / build (push) Successful in 4m30s
CI / CD Pipeline / deploy (push) Successful in 1m6s

This commit is contained in:
2026-04-09 09:53:57 +07:00
parent 4f34aeae6b
commit 99c8d61856
18 changed files with 1791 additions and 60 deletions
@@ -0,0 +1,71 @@
// File: src/modules/ai/entities/ai-audit-log.entity.ts
// Entity สำหรับตาราง ai_audit_logs — บันทึก AI Interaction ทุกครั้งตาม ADR-018 Rule 5
import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
Index,
} from 'typeorm';
import { UuidBaseEntity } from '../../../common/entities/uuid-base.entity';
// สถานะการประมวลผลของ AI
export enum AiAuditStatus {
SUCCESS = 'SUCCESS', // ประมวลผลสำเร็จ
FAILED = 'FAILED', // ประมวลผลล้มเหลว
TIMEOUT = 'TIMEOUT', // หมดเวลา
}
@Entity('ai_audit_logs')
export class AiAuditLog extends UuidBaseEntity {
@PrimaryGeneratedColumn()
id!: number;
// UUID ของ MigrationLog ที่เกี่ยวข้อง (ใช้ UUID string ไม่ใช่ INT FK)
@Index('idx_ai_audit_document')
@Column({ name: 'document_public_id', type: 'uuid', nullable: true })
documentPublicId?: string;
// ชื่อ AI Model ที่ใช้ประมวลผล เช่น 'gemma4', 'paddleocr'
@Index('idx_ai_audit_model')
@Column({ name: 'ai_model', type: 'varchar', length: 50 })
aiModel!: string;
// เวลาประมวลผลเป็น milliseconds
@Column({ name: 'processing_time_ms', type: 'int', nullable: true })
processingTimeMs?: number;
// คะแนนความมั่นใจของ AI (0.00-1.00)
@Column({
name: 'confidence_score',
type: 'decimal',
precision: 3,
scale: 2,
nullable: true,
})
confidenceScore?: number;
// SHA-256 hash ของ Input เพื่อ Audit Trail (ADR-018)
@Column({ name: 'input_hash', type: 'varchar', length: 64, nullable: true })
inputHash?: string;
// SHA-256 hash ของ Output เพื่อ Audit Trail (ADR-018)
@Column({ name: 'output_hash', type: 'varchar', length: 64, nullable: true })
outputHash?: string;
// สถานะการประมวลผล
@Index('idx_ai_audit_status')
@Column({
type: 'enum',
enum: AiAuditStatus,
})
status!: AiAuditStatus;
// ข้อความ Error (ถ้ามี)
@Column({ name: 'error_message', type: 'text', nullable: true })
errorMessage?: string;
@CreateDateColumn({ name: 'created_at' })
createdAt!: Date;
}
@@ -0,0 +1,93 @@
// File: src/modules/ai/entities/migration-log.entity.ts
// Entity สำหรับตาราง migration_logs — ติดตาม AI Processing ของแต่ละเอกสาร (ADR-020)
import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
Index,
} from 'typeorm';
import { UuidBaseEntity } from '../../../common/entities/uuid-base.entity';
// สถานะของ Migration Log ตาม State Machine ใน ADR-020
export enum MigrationLogStatus {
PENDING_REVIEW = 'PENDING_REVIEW', // รอ Admin ตรวจสอบ
VERIFIED = 'VERIFIED', // Admin ตรวจสอบแล้ว ยืนยันถูกต้อง
IMPORTED = 'IMPORTED', // นำเข้าระบบสำเร็จ (Terminal State)
FAILED = 'FAILED', // ล้มเหลว สามารถ retry ได้
}
// Transition Rules: ห้าม import โดยตรงจาก FAILED หรือ PENDING ไปยัง IMPORTED
export const MIGRATION_STATUS_TRANSITIONS: Record<
MigrationLogStatus,
MigrationLogStatus[]
> = {
[MigrationLogStatus.PENDING_REVIEW]: [
MigrationLogStatus.VERIFIED,
MigrationLogStatus.FAILED,
],
[MigrationLogStatus.VERIFIED]: [
MigrationLogStatus.IMPORTED,
MigrationLogStatus.PENDING_REVIEW,
],
[MigrationLogStatus.IMPORTED]: [], // Terminal State — ไม่สามารถเปลี่ยนได้
[MigrationLogStatus.FAILED]: [MigrationLogStatus.PENDING_REVIEW], // Retry ได้
};
@Entity('migration_logs')
export class MigrationLog extends UuidBaseEntity {
@PrimaryGeneratedColumn()
id!: number;
// ไฟล์ต้นทางที่นำเข้า (path หรือ filename)
@Column({ name: 'source_file', type: 'varchar', length: 255 })
sourceFile!: string;
// Metadata จากแหล่งข้อมูลต้นทาง (Excel, manual input)
@Column({ name: 'source_metadata', type: 'json', nullable: true })
sourceMetadata?: Record<string, unknown>;
// Metadata ที่ AI สกัดได้จากเอกสาร
@Column({ name: 'ai_extracted_metadata', type: 'json', nullable: true })
aiExtractedMetadata?: Record<string, unknown>;
// คะแนนความมั่นใจของ AI (0.00-1.00)
@Index('idx_migration_logs_confidence')
@Column({
name: 'confidence_score',
type: 'decimal',
precision: 3,
scale: 2,
nullable: true,
})
confidenceScore?: number;
// สถานะปัจจุบันของ Migration Log
@Index('idx_migration_logs_status')
@Column({
type: 'enum',
enum: MigrationLogStatus,
default: MigrationLogStatus.PENDING_REVIEW,
})
status!: MigrationLogStatus;
// ความเห็นของ Admin ผู้ตรวจสอบ
@Column({ name: 'admin_feedback', type: 'text', nullable: true })
adminFeedback?: string;
// User ID ของ Admin ที่ตรวจสอบ (Internal INT, ไม่ expose ใน API)
@Column({ name: 'reviewed_by', type: 'int', nullable: true })
reviewedBy?: number;
// เวลาที่ตรวจสอบ
@Column({ name: 'reviewed_at', type: 'timestamp', nullable: true })
reviewedAt?: Date;
@CreateDateColumn({ name: 'created_at' })
createdAt!: Date;
@UpdateDateColumn({ name: 'updated_at' })
updatedAt!: Date;
}