690414:1113 Update README.md /.agents/skills, /.windsurf/workflows
This commit is contained in:
@@ -1,11 +1,36 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { circulationService } from '@/lib/services/circulation.service';
|
||||
import { Circulation } from '@/types/circulation';
|
||||
|
||||
export const circulationKeys = {
|
||||
all: ['circulations'] as const,
|
||||
detail: (uuid: string) => ['circulations', 'detail', uuid] as const,
|
||||
byCorrespondence: (uuid: string) => ['circulations', 'byCorrespondence', uuid] as const,
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook สำหรับดึงข้อมูล Circulation รายเอกสาร (พร้อม workflowInstanceId)
|
||||
* ADR-021 / v1.8.7 — ใช้ใน circulation/[uuid]/page.tsx
|
||||
*/
|
||||
export function useCirculation(uuid: string | undefined) {
|
||||
const query = useQuery<Circulation>({
|
||||
queryKey: circulationKeys.detail(uuid ?? ''),
|
||||
queryFn: async () => {
|
||||
const res = await circulationService.getByUuid(uuid!);
|
||||
return (res?.data ?? res) as Circulation;
|
||||
},
|
||||
enabled: !!uuid,
|
||||
staleTime: 60_000,
|
||||
});
|
||||
|
||||
return {
|
||||
circulation: query.data,
|
||||
isLoading: query.isLoading,
|
||||
error: query.error,
|
||||
refetch: query.refetch,
|
||||
};
|
||||
}
|
||||
|
||||
export function useCirculationsByCorrespondence(correspondencePublicId: string) {
|
||||
return useQuery({
|
||||
queryKey: circulationKeys.byCorrespondence(correspondencePublicId),
|
||||
|
||||
@@ -6,6 +6,9 @@ import { SubmitCorrespondenceDto } from '@/types/dto/correspondence/submit-corre
|
||||
import { WorkflowActionDto } from '@/types/dto/correspondence/workflow-action.dto';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
// ADR-021: Re-export useWorkflowHistory เพื่อให้ page import ได้จาก use-correspondence
|
||||
export { useWorkflowHistory } from './use-workflow-history';
|
||||
|
||||
// Error type for axios errors
|
||||
type ApiError = Error & { response?: { data?: { message?: string } } };
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ import { WorkflowActionDto } from '@/lib/services/rfa.service';
|
||||
import { toast } from 'sonner';
|
||||
import { getApiErrorMessage } from '@/types/api-error';
|
||||
|
||||
// ADR-021: Re-export useWorkflowHistory เพื่อให้ page import ได้จาก use-rfa
|
||||
export { useWorkflowHistory } from './use-workflow-history';
|
||||
|
||||
// Keys
|
||||
export const rfaKeys = {
|
||||
all: ['rfas'] as const,
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// hooks/use-translations.ts
|
||||
// ADR-021 Phase 7: React hook สำหรับ i18n — คืน t() function สำหรับใช้ใน Client Components
|
||||
'use client';
|
||||
|
||||
import { createT } from '@/lib/i18n';
|
||||
|
||||
// ค่า default locale ของโปรเจกต์คือ 'th'
|
||||
// เมื่อต้องการรองรับ multi-locale ให้เชื่อมกับ Context หรือ cookie ในอนาคต
|
||||
const defaultT = createT('th');
|
||||
|
||||
export function useTranslations() {
|
||||
return defaultT;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// File: hooks/use-transmittal.ts
|
||||
// ADR-021 / v1.8.7: TanStack Query hook สำหรับ Transmittal detail page
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { transmittalService } from '@/lib/services/transmittal.service';
|
||||
import { Transmittal } from '@/types/transmittal';
|
||||
|
||||
export const transmittalKeys = {
|
||||
all: ['transmittals'] as const,
|
||||
detail: (uuid: string) => ['transmittals', 'detail', uuid] as const,
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook สำหรับดึงข้อมูล Transmittal รายเอกสาร (พร้อม workflowInstanceId)
|
||||
* ใช้ใน transmittals/[uuid]/page.tsx
|
||||
*/
|
||||
export function useTransmittal(uuid: string | undefined) {
|
||||
const query = useQuery<Transmittal>({
|
||||
queryKey: transmittalKeys.detail(uuid ?? ''),
|
||||
queryFn: async () => {
|
||||
const res = await transmittalService.getByUuid(uuid!);
|
||||
return (res?.data ?? res) as Transmittal;
|
||||
},
|
||||
enabled: !!uuid,
|
||||
staleTime: 60_000,
|
||||
});
|
||||
|
||||
return {
|
||||
transmittal: query.data,
|
||||
isLoading: query.isLoading,
|
||||
error: query.error,
|
||||
refetch: query.refetch,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// ADR-021 T027: useWorkflowAction — hook สำหรับส่ง Approve/Reject/Return action
|
||||
// สร้าง Idempotency-Key ครั้งเดียวต่อ action intent (via useState) ป้องกัน duplicate submission
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { toast } from 'sonner';
|
||||
import { workflowEngineService } from '@/lib/services/workflow-engine.service';
|
||||
import type { WorkflowTransitionWithAttachmentsDto } from '@/types/dto/workflow-engine/workflow-engine.dto';
|
||||
|
||||
export function useWorkflowAction(instanceId: string | undefined) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
// สร้าง idempotency key ครั้งแรก — reset หลัง submit สำเร็จ เพื่อป้องกัน replay
|
||||
const [idempotencyKey, setIdempotencyKey] = useState(() => uuidv4());
|
||||
|
||||
const mutation = useMutation({
|
||||
mutationFn: (dto: WorkflowTransitionWithAttachmentsDto) => {
|
||||
if (!instanceId) {
|
||||
return Promise.reject(new Error('ไม่พบ Workflow Instance ID'));
|
||||
}
|
||||
return workflowEngineService.transition(instanceId, dto, idempotencyKey);
|
||||
},
|
||||
onSuccess: () => {
|
||||
// Reset key สำหรับ action ครั้งถัดไป
|
||||
setIdempotencyKey(uuidv4());
|
||||
|
||||
// Invalidate ประวัติ Workflow ของ Instance นี้
|
||||
if (instanceId) {
|
||||
void queryClient.invalidateQueries({
|
||||
queryKey: ['workflow-history', instanceId],
|
||||
});
|
||||
}
|
||||
|
||||
// Invalidate รายการเอกสารหลักทั้งหมด (RFA, Correspondence)
|
||||
void queryClient.invalidateQueries({ queryKey: ['rfas'] });
|
||||
void queryClient.invalidateQueries({ queryKey: ['correspondences'] });
|
||||
void queryClient.invalidateQueries({ queryKey: ['transmittals'] });
|
||||
void queryClient.invalidateQueries({ queryKey: ['circulations'] });
|
||||
|
||||
toast.success('ดำเนินการเรียบร้อยแล้ว');
|
||||
},
|
||||
onError: (error: Error) => {
|
||||
toast.error(error.message || 'เกิดข้อผิดพลาด กรุณาลองใหม่');
|
||||
},
|
||||
});
|
||||
|
||||
return mutation;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// ADR-021: Hook สำหรับดึงประวัติ Workflow พร้อมไฟล์แนบประจำ Step (US2)
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { workflowEngineService } from '@/lib/services/workflow-engine.service';
|
||||
import type { WorkflowHistoryItem } from '@/types/workflow';
|
||||
|
||||
export const workflowHistoryKeys = {
|
||||
all: ['workflow-history'] as const,
|
||||
instance: (instanceId: string) =>
|
||||
[...workflowHistoryKeys.all, instanceId] as const,
|
||||
};
|
||||
|
||||
/**
|
||||
* ดึงประวัติการเดินเรื่องของ Workflow Instance
|
||||
* disabled อัตโนมัติถ้า instanceId ไม่มีค่า
|
||||
*/
|
||||
export function useWorkflowHistory(instanceId: string | undefined) {
|
||||
return useQuery<WorkflowHistoryItem[]>({
|
||||
queryKey: workflowHistoryKeys.instance(instanceId ?? ''),
|
||||
queryFn: () => workflowEngineService.getHistory(instanceId!),
|
||||
enabled: !!instanceId,
|
||||
staleTime: 60_000, // 1 นาที — ประวัติไม่เปลี่ยนบ่อย
|
||||
retry: false, // ถ้า 404 (endpoint ยังไม่มี) ไม่ต้อง retry
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user