feat(rfa): complete RFA Approval Refactor - all 9 phases (T001-T080)

Phase 1-2: Setup, SQL schema, enums, queue constants, base entities
Phase 3 (US1): ReviewTeam, ReviewTeamMember, ReviewTask, TaskCreationService
Phase 4 (US2): ResponseCode, ResponseCodeRule, ImplicationsService, NotificationTriggerService
Phase 5 (US3): Delegation entity, CircularDetectionService, DelegationService/Controller/Module
Phase 6 (US4): ReminderRule, SchedulerService, EscalationService, ReminderProcessor, ReminderModule
Phase 7 (US5): DistributionMatrix, DistributionRecipient, ApprovalListenerService (Strangler),
               TransmittalCreatorService, DistributionProcessor, DistributionModule
Phase 8 (US6): MatrixManagementService, InheritanceService (global→project override)
Phase 9 (Polish): AggregateStatusService, ConsensusService, VetoOverrideService,
                  ParallelGatewayHandler, review-validators, optimistic locking in completeReview,
                  test stubs (unit/integration/e2e), jest.config.js updated for tests/ directory

Frontend: ReviewTaskInbox, ParallelProgress, VetoOverrideDialog, DelegationForm,
          DelegatedBadge, MatrixEditor, ProjectOverrideManager, DistributionStatus,
          ReminderHistory, ResponseCodeSelector, CodeImplications, CompleteReviewForm,
          ReviewTeamForm, ReviewTeamSelector, TeamMemberManager

Closes #1
This commit is contained in:
Nattanin
2026-05-12 16:17:27 +07:00
parent 3df8707b7f
commit ef20839f99
82 changed files with 7052 additions and 104 deletions
@@ -0,0 +1,75 @@
// File: lib/services/review-team.service.ts
import apiClient from '@/lib/api/client';
export interface CreateReviewTeamDto {
name: string;
description?: string;
projectPublicId: string;
defaultForRfaTypes?: string[];
}
export interface UpdateReviewTeamDto {
name?: string;
description?: string;
defaultForRfaTypes?: string[];
isActive?: boolean;
}
export interface AddTeamMemberDto {
userPublicId: string;
disciplinePublicId: string;
role: 'REVIEWER' | 'LEAD' | 'MANAGER';
priorityOrder?: number;
}
export interface SearchReviewTeamDto {
projectPublicId?: string;
isActive?: boolean;
search?: string;
}
export const reviewTeamService = {
/** ดึง Review Teams ตาม project */
getAll: async (params?: SearchReviewTeamDto) => {
const response = await apiClient.get('/review-teams', { params });
return response.data;
},
/** ดึง Review Team เดียว (ADR-019) */
getByPublicId: async (publicId: string) => {
const response = await apiClient.get(`/review-teams/${publicId}`);
return response.data;
},
/** สร้าง Review Team */
create: async (data: CreateReviewTeamDto) => {
const response = await apiClient.post('/review-teams', data);
return response.data;
},
/** อัปเดต Review Team */
update: async (publicId: string, data: UpdateReviewTeamDto) => {
const response = await apiClient.patch(`/review-teams/${publicId}`, data);
return response.data;
},
/** เพิ่มสมาชิก */
addMember: async (teamPublicId: string, data: AddTeamMemberDto) => {
const response = await apiClient.post(`/review-teams/${teamPublicId}/members`, data);
return response.data;
},
/** ลบสมาชิก */
removeMember: async (teamPublicId: string, memberPublicId: string) => {
const response = await apiClient.delete(
`/review-teams/${teamPublicId}/members/${memberPublicId}`,
);
return response.data;
},
/** Deactivate Review Team */
deactivate: async (publicId: string) => {
const response = await apiClient.delete(`/review-teams/${publicId}`);
return response.data;
},
};