// File: frontend/app/(admin)/admin/ai/prompt-management/page.tsx // Change Log: // - 2026-06-14: Created unified prompt management page (conforming to tasks T019, T029, T038) 'use client'; import React, { useState, useEffect } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { adminAiService } from '@/lib/services/admin-ai.service'; import { PromptType, PromptVersion, ContextConfig } from '@/lib/types/ai-prompts'; import PromptTypeDropdown from '@/components/admin/ai/PromptTypeDropdown'; import VersionHistory from '@/components/admin/ai/VersionHistory'; import PromptEditor from '@/components/admin/ai/PromptEditor'; import ContextConfigEditor from '@/components/admin/ai/ContextConfigEditor'; import SandboxTabs from '@/components/admin/ai/SandboxTabs'; import RuntimeParametersPanel from '@/components/admin/ai/RuntimeParametersPanel'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { toast } from 'sonner'; import { Brain, Sliders, Play, Settings } from 'lucide-react'; export default function UnifiedPromptManagementPage() { const queryClient = useQueryClient(); const [selectedType, setSelectedType] = useState('ocr_extraction'); const [selectedVersion, setSelectedVersion] = useState(null); // ดึงข้อมูลประวัติเวอร์ชันทั้งหมดของ prompt_type ที่เลือก const { data: versions = [], isLoading } = useQuery({ queryKey: ['admin-ai-prompts', selectedType], queryFn: async () => { if (selectedType === 'all') return []; const res = await adminAiService.listPrompts(selectedType); return res || []; }, enabled: selectedType !== 'all', }); // อัปเดต selectedVersion เมื่อเปลี่ยนประเภทหรือข้อมูลรีเฟรช useEffect(() => { if (versions.length > 0) { const active = versions.find((v) => v.isActive) || versions[0]; setSelectedVersion(active); } else { setSelectedVersion(null); } }, [versions, selectedType]); // สร้างเวอร์ชันใหม่ const createMutation = useMutation({ mutationFn: async (payload: { template: string; manualNote: string }) => { if (selectedType === 'all') throw new Error('Cannot create prompt for "All Types"'); return await adminAiService.createPrompt(selectedType, { template: payload.template, manualNote: payload.manualNote, }); }, onSuccess: () => { toast.success('สร้าง Prompt Version ใหม่สำเร็จ'); queryClient.invalidateQueries({ queryKey: ['admin-ai-prompts', selectedType] }); }, onError: (err: unknown) => { const errorMsg = (err as { response?: { data?: { message?: string; userMessage?: string; recoveryAction?: string } } })?.response?.data?.message; const userMessage = (err as { response?: { data?: { userMessage?: string } } })?.response?.data?.userMessage; const recoveryAction = (err as { response?: { data?: { recoveryAction?: string } } })?.response?.data?.recoveryAction; // ADR-007 layered error handling (T073) if (userMessage) { toast.error(userMessage, { description: recoveryAction || 'กรุณาตรวจสอบข้อมูลและลองใหม่', }); } else { toast.error(errorMsg || 'ไม่สามารถสร้าง Prompt Version ใหม่ได้'); } }, }); // เปิดใช้งานเวอร์ชัน const activateMutation = useMutation({ mutationFn: async (versionNumber: number) => { if (selectedType === 'all') throw new Error('Cannot activate prompt for "All Types"'); return await adminAiService.activatePrompt(selectedType, versionNumber); }, onSuccess: () => { toast.success('เปิดใช้งาน Prompt Version สำเร็จ'); queryClient.invalidateQueries({ queryKey: ['admin-ai-prompts', selectedType] }); }, onError: (err: unknown) => { const errorMsg = (err as { response?: { data?: { message?: string; userMessage?: string; recoveryAction?: string } } })?.response?.data?.message; const userMessage = (err as { response?: { data?: { userMessage?: string } } })?.response?.data?.userMessage; const recoveryAction = (err as { response?: { data?: { recoveryAction?: string } } })?.response?.data?.recoveryAction; // ADR-007 layered error handling (T073) if (userMessage) { toast.error(userMessage, { description: recoveryAction || 'กรุณาตรวจสอบข้อมูลและลองใหม่', }); } else { toast.error(errorMsg || 'ไม่สามารถเปิดใช้งาน Prompt Version ได้'); } }, }); // ลบเวอร์ชัน const deleteMutation = useMutation({ mutationFn: async (versionNumber: number) => { if (selectedType === 'all') throw new Error('Cannot delete prompt for "All Types"'); return await adminAiService.deletePrompt(selectedType, versionNumber); }, onSuccess: () => { toast.success('ลบ Prompt Version สำเร็จ'); queryClient.invalidateQueries({ queryKey: ['admin-ai-prompts', selectedType] }); }, onError: (err: unknown) => { const errorMsg = (err as { response?: { data?: { message?: string; userMessage?: string; recoveryAction?: string } } })?.response?.data?.message; const userMessage = (err as { response?: { data?: { userMessage?: string } } })?.response?.data?.userMessage; const recoveryAction = (err as { response?: { data?: { recoveryAction?: string } } })?.response?.data?.recoveryAction; // ADR-007 layered error handling (T073) if (userMessage) { toast.error(userMessage, { description: recoveryAction || 'กรุณาตรวจสอบข้อมูลและลองใหม่', }); } else { toast.error(errorMsg || 'ไม่สามารถลบ Prompt Version ได้'); } }, }); // อัปเดตบริบทข้อมูล (Context Config) const updateConfigMutation = useMutation({ mutationFn: async (payload: { versionNumber: number; config: ContextConfig }) => { if (selectedType === 'all') throw new Error('Cannot update config for "All Types"'); return await adminAiService.updateContextConfig( selectedType, payload.versionNumber, payload.config ); }, onSuccess: () => { toast.success('อัปเดตการตั้งค่าบริบทสำเร็จ'); queryClient.invalidateQueries({ queryKey: ['admin-ai-prompts', selectedType] }); }, onError: (err: unknown) => { const errorMsg = (err as { response?: { data?: { message?: string; userMessage?: string; recoveryAction?: string } } })?.response?.data?.message; const userMessage = (err as { response?: { data?: { userMessage?: string } } })?.response?.data?.userMessage; const recoveryAction = (err as { response?: { data?: { recoveryAction?: string } } })?.response?.data?.recoveryAction; // ADR-007 layered error handling (T073) if (userMessage) { toast.error(userMessage, { description: recoveryAction || 'กรุณาตรวจสอบข้อมูลและลองใหม่', }); } else { toast.error(errorMsg || 'ไม่สามารถอัปเดตบริบทได้'); } }, }); return (

ระบบจัดการ Prompt และบริบท (Prompt & Context Manager) Prompt Manager

จัดการเทมเพลตพรอมต์และตัวกรองข้อมูล Master Data เพื่อส่งให้ระบบ AI ประมวลผลอย่างแม่นยำ

{/* Sidebar: รายการประวัติเวอร์ชัน */}
activateMutation.mutate(v)} onDeleteVersion={(v) => deleteMutation.mutate(v)} isActivating={activateMutation.isPending} isDeleting={deleteMutation.isPending} />
{/* Main Panel: แผงแก้ไขและทดสอบ Sandbox */}
ตัวแก้ไขและบริบท (Editor & Context) Editor บอร์ดทดลอง (3-Step Sandbox) Sandbox พารามิเตอร์รันไทม์ (Runtime Params) Params {selectedType !== 'all' && ( <> { await createMutation.mutateAsync({ template: tmpl, manualNote: note }); }} isSaving={createMutation.isPending} /> {selectedVersion && ( { await updateConfigMutation.mutateAsync({ versionNumber: selectedVersion.versionNumber, config, }); }} isSaving={updateConfigMutation.isPending} /> )} )} {selectedType === 'all' && (
กรุณาเลือกประเภท Prompt เพื่อแก้ไข
)}
activateMutation.mutate(v)} />
); }