feat(ai): add ADR-036 unified OCR architecture and frontend test coverage
CI / CD Pipeline / build (push) Failing after 6m24s
CI / CD Pipeline / deploy (push) Has been skipped

- Add ADR-036 unified OCR architecture (typhoon-ocr via Ollama)
- Extend AI execution profiles for OCR sandbox configuration
- Add comprehensive frontend test coverage (components, hooks, services)
- Add backend test coverage for document-numbering services
- Update OCR sidecar with typhoon-ocr integration
- Add AI policy service and execution profile management
- Update AGENTS.md and architecture documentation
This commit is contained in:
2026-06-14 06:34:07 +07:00
parent e3503b6a77
commit 7e8f4859cd
108 changed files with 33914 additions and 339 deletions
@@ -0,0 +1,28 @@
// File: backend/src/modules/ai/dto/apply-profile.dto.ts
// Change Log:
// - 2026-06-13: ADR-036 — DTO สำหรับ apply sandbox draft ไป production
import { ApiPropertyOptional } from '@nestjs/swagger';
import { IsEnum, IsOptional, IsString, MaxLength } from 'class-validator';
/**
* DTO สำหรับคำสั่ง Apply to Production
*/
export class ApplyProfileDto {
@ApiPropertyOptional({
enum: ['np-dms-ai', 'np-dms-ocr'],
description: 'Canonical model ที่ต้องการ apply',
})
@IsOptional()
@IsEnum(['np-dms-ai', 'np-dms-ocr'])
canonicalModel?: 'np-dms-ai' | 'np-dms-ocr';
@ApiPropertyOptional({
description: 'เหตุผลในการ apply สำหรับ audit trail',
maxLength: 500,
})
@IsOptional()
@IsString()
@MaxLength(500)
reason?: string;
}
@@ -0,0 +1,31 @@
// File: backend/src/modules/ai/dto/apply-result.dto.ts
// Change Log:
// - 2026-06-13: ADR-036 — DTO ผลลัพธ์สำหรับ apply sandbox draft ไป production
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean, IsDateString, IsObject, IsString } from 'class-validator';
/**
* DTO สำหรับผลลัพธ์ของการ Apply to Production
*/
export class ApplyResultDto {
@ApiProperty({ description: 'สถานะการ apply สำเร็จหรือไม่' })
@IsBoolean()
success!: boolean;
@ApiProperty({ description: 'ชื่อโปรไฟล์ที่ถูก apply' })
@IsString()
profileName!: string;
@ApiProperty({ description: 'ค่าก่อน apply' })
@IsObject()
oldValues!: Record<string, unknown>;
@ApiProperty({ description: 'ค่าหลัง apply' })
@IsObject()
newValues!: Record<string, unknown>;
@ApiProperty({ description: 'เวลาที่ apply เสร็จ', format: 'date-time' })
@IsDateString()
appliedAt!: string;
}