260326:1726 Fixing Refactor ADR-019 Naming convention uuid #06
CI / CD Pipeline / build (push) Successful in 15m6s
CI / CD Pipeline / deploy (push) Successful in 8m56s

This commit is contained in:
admin
2026-03-26 17:26:28 +07:00
parent 29922aec1f
commit 25ea2fcd0f
25 changed files with 65 additions and 61 deletions
@@ -17,7 +17,7 @@ import { useProjects, useCorrespondenceTypes, useContracts, useDisciplines } fro
interface ProjectItem {
id: number | string;
uuid?: string;
publicId?: string; // ADR-019: exposed as 'id' in API responses
projectName: string;
projectCode: string;
}
@@ -54,7 +54,7 @@ export default function NumberingPage() {
// Master Data
const { data: correspondenceTypes = [] } = useCorrespondenceTypes();
const { data: contracts = [] } = useContracts(selectedProjectId);
const firstContract = contracts[0] as { id?: number; uuid?: string } | undefined;
const firstContract = contracts[0] as { id?: number; publicId?: string } | undefined;
const contractId = firstContract?.publicId ?? firstContract?.id;
const { data: disciplines = [] } = useDisciplines(contractId);
@@ -143,7 +143,7 @@ export default function CirculationDetailPage() {
<div>
<p className="text-sm text-muted-foreground">Linked Document</p>
<Link
href={`/correspondences/${circulation.correspondence.uuid}`}
href={`/correspondences/${circulation.correspondence.publicId}`}
className="font-medium text-primary hover:underline"
>
{circulation.correspondence.correspondenceNumber}
@@ -23,7 +23,7 @@ type DrawingType = 'CONTRACT' | 'SHOP' | 'AS_BUILT';
interface FetchedDrawing {
_type: DrawingType;
uuid: string;
publicId: string;
contractDrawingNo?: string;
drawingNumber?: string;
title?: string;
@@ -33,7 +33,7 @@ interface FetchedDrawing {
currentRevision?: { title?: string; revisionNumber?: string; legacyDrawingNumber?: string };
revisions?: {
revisionId?: number;
uuid: string;
publicId: string;
revisionNumber: string;
title?: string;
legacyDrawingNumber?: string;
@@ -109,7 +109,7 @@ export default function DrawingDetailPage({ params }: { params: Promise<{ uuid:
<h1 className="text-2xl font-bold">Drawing Not Found</h1>
</div>
<p className="text-muted-foreground">
The drawing with UUID <code>{uuid}</code> could not be found.
The drawing with ID <code>{uuid}</code> could not be found.
</p>
</div>
);
@@ -101,7 +101,7 @@ export default function TransmittalDetailPage() {
<p className="text-sm text-muted-foreground">Generated From</p>
{transmittal.correspondence ? (
<Link
href={`/correspondences/${transmittal.correspondence.uuid}`}
href={`/correspondences/${transmittal.correspondence.publicId}`}
className="font-medium text-primary hover:underline"
>
{transmittal.correspondence.correspondenceNumber}
@@ -84,7 +84,7 @@ export function OrganizationDialog({ open, onOpenChange, organization }: Organiz
};
if (organization) {
updateOrg.mutate({ uuid: organization.uuid, data: submitData }, { onSuccess: () => onOpenChange(false) });
updateOrg.mutate({ uuid: organization.publicId, data: submitData }, { onSuccess: () => onOpenChange(false) });
} else {
createOrg.mutate(submitData, {
onSuccess: () => onOpenChange(false),
+3 -3
View File
@@ -153,7 +153,7 @@ export function UserDialog({ open, onOpenChange, user }: UserDialogProps) {
}
if (user) {
updateUser.mutate({ uuid: user.uuid, data: payload }, { onSuccess: () => onOpenChange(false) });
updateUser.mutate({ uuid: user.publicId, data: payload }, { onSuccess: () => onOpenChange(false) });
} else {
// Create req: Password mandatory
if (!payload.password) return; // Should allow Zod to catch or show error
@@ -231,8 +231,8 @@ export function UserDialog({ open, onOpenChange, user }: UserDialogProps) {
<SelectContent>
<SelectItem value={ALL_ORGANIZATIONS_VALUE}>All Organizations</SelectItem>
{Array.isArray(organizations) &&
organizations.map((org: { uuid: string; organizationCode: string; organizationName: string }) => (
<SelectItem key={org.uuid} value={org.uuid}>
organizations.map((org: { publicId: string; organizationCode: string; organizationName: string }) => (
<SelectItem key={org.publicId} value={org.publicId}>
{org.organizationCode} - {org.organizationName}
</SelectItem>
))}
@@ -104,7 +104,7 @@ export function CirculationList({ data }: CirculationListProps) {
const item = row.original;
return (
<div className="flex gap-1">
<Link href={`/circulation/${item.uuid}`}>
<Link href={`/circulation/${item.publicId}`}>
<Button variant="ghost" size="icon" title="View Details">
<Eye className="h-4 w-4" />
</Button>
@@ -76,7 +76,7 @@ function CirculationItem({ circ }: { circ: Circulation }) {
</div>
)}
<Link href={`/circulation/${circ.uuid}`}>
<Link href={`/circulation/${circ.publicId}`}>
<Button variant="ghost" size="sm" className="w-full h-7 text-xs mt-1">
View Details
<ChevronRight className="h-3 w-3 ml-1" />
@@ -118,7 +118,7 @@ export function CirculationStatusCard({ correspondenceUuid }: CirculationStatusC
<p className="text-sm text-muted-foreground">No circulations yet</p>
) : (
circulations.map((circ) => (
<CirculationItem key={circ.uuid} circ={circ} />
<CirculationItem key={circ.publicId} circ={circ} />
))
)}
@@ -44,7 +44,7 @@ export function CorrespondenceDetail({ data }: CorrespondenceDetailProps) {
const handleSubmit = () => {
if (confirm('Are you sure you want to submit this correspondence?')) {
submitMutation.mutate({ uuid: data.uuid, data: {} });
submitMutation.mutate({ uuid: data.publicId, data: {} });
}
};
@@ -52,7 +52,7 @@ export function CorrespondenceDetail({ data }: CorrespondenceDetailProps) {
if (!actionState || actionState === 'cancel') return;
const action = actionState === 'approve' ? 'APPROVE' : 'REJECT';
processMutation.mutate(
{ uuid: data.uuid, data: { action, comments } },
{ uuid: data.publicId, data: { action, comments } },
{ onSuccess: () => { setActionState(null); setComments(''); } }
);
};
@@ -60,7 +60,7 @@ export function CorrespondenceDetail({ data }: CorrespondenceDetailProps) {
const handleCancel = () => {
if (!cancelReason.trim()) return;
cancelMutation.mutate(
{ uuid: data.uuid, reason: cancelReason },
{ uuid: data.publicId, reason: cancelReason },
{ onSuccess: () => { setActionState(null); setCancelReason(''); } }
);
};
@@ -97,7 +97,7 @@ export function CorrespondenceDetail({ data }: CorrespondenceDetailProps) {
</div>
<div className="flex gap-2">
{status === 'DRAFT' && (
<Link href={`/correspondences/${data.uuid}/edit`}>
<Link href={`/correspondences/${data.publicId}/edit`}>
<Button variant="outline">
<Edit className="mr-2 h-4 w-4" />
Edit
@@ -256,7 +256,7 @@ export function CorrespondenceDetail({ data }: CorrespondenceDetailProps) {
<div className="grid gap-2">
{attachments.map((file, index) => (
<div
key={file.uuid || index}
key={file.publicId || index}
className="flex items-center justify-between p-3 border rounded-lg bg-muted/20"
>
<div className="flex items-center gap-3">
@@ -376,17 +376,17 @@ export function CorrespondenceDetail({ data }: CorrespondenceDetailProps) {
</Card>
{/* Circulations */}
<CirculationStatusCard correspondenceUuid={data.uuid} />
<CirculationStatusCard correspondenceUuid={data.publicId} />
{/* Tags */}
<TagManager
uuid={data.uuid}
uuid={data.publicId}
canEdit={status !== 'CANCELLED'}
/>
{/* References */}
<ReferenceSelector
uuid={data.uuid}
uuid={data.publicId}
canEdit={status !== 'CANCELLED'}
/>
+9 -9
View File
@@ -458,7 +458,7 @@ export function CorrespondenceForm({ initialData, uuid }: { initialData?: Initia
</SelectTrigger>
<SelectContent>
{organizationOptions.map((org) => (
<SelectItem key={org.uuid} value={org.uuid}>
<SelectItem key={org.publicId} value={org.publicId}>
{org.organizationName} ({org.organizationCode})
</SelectItem>
))}
@@ -479,7 +479,7 @@ export function CorrespondenceForm({ initialData, uuid }: { initialData?: Initia
</SelectTrigger>
<SelectContent>
{organizationOptions.map((org) => (
<SelectItem key={org.uuid} value={org.uuid}>
<SelectItem key={org.publicId} value={org.publicId}>
{org.organizationName} ({org.organizationCode})
</SelectItem>
))}
@@ -492,22 +492,22 @@ export function CorrespondenceForm({ initialData, uuid }: { initialData?: Initia
<Label>CC Organizations (Optional)</Label>
<div className="space-y-2 max-h-32 overflow-y-auto border rounded-md p-3">
{organizationOptions
.filter(org => org.uuid !== toOrgId) // Exclude TO organization
.filter(org => org.publicId !== toOrgId) // Exclude TO organization
.map((org) => (
<div key={org.uuid} className="flex items-center space-x-2">
<div key={org.publicId} className="flex items-center space-x-2">
<Checkbox
id={`cc-${org.uuid}`}
checked={watch('ccOrganizationIds')?.includes(org.uuid) || false}
id={`cc-${org.publicId}`}
checked={watch('ccOrganizationIds')?.includes(org.publicId) || false}
onCheckedChange={(checked) => {
const currentCC = watch('ccOrganizationIds') || [];
if (checked) {
setValue('ccOrganizationIds', [...currentCC, org.uuid]);
setValue('ccOrganizationIds', [...currentCC, org.publicId]);
} else {
setValue('ccOrganizationIds', currentCC.filter(id => id !== org.uuid));
setValue('ccOrganizationIds', currentCC.filter(id => id !== org.publicId));
}
}}
/>
<Label htmlFor={`cc-${org.uuid}`} className="text-sm">
<Label htmlFor={`cc-${org.publicId}`} className="text-sm">
{org.organizationName} ({org.organizationCode})
</Label>
</div>
+3 -3
View File
@@ -87,10 +87,10 @@ export function CorrespondenceList({ data }: CorrespondenceListProps) {
id: 'actions',
cell: ({ row }) => {
const item = row.original;
// Edit/View link goes to the DOCUMENT detail (correspondence.uuid)
// Ideally we might pass ?revId=item.uuid to view specific revision, but detail page defaults to latest.
// Edit/View link goes to the DOCUMENT detail (correspondence.publicId)
// Ideally we might pass ?revId=item.publicId to view specific revision, but detail page defaults to latest.
// For editing, we edit the document.
const docUuid = item.correspondence.uuid;
const docUuid = item.correspondence.publicId;
const statusCode = item.status?.statusCode;
return (
@@ -54,7 +54,7 @@ export function RevisionHistory({ revisions }: RevisionHistoryProps) {
const isCurrent = rev.isCurrent;
return (
<div key={rev.uuid ?? rev.revisionNumber} className="flex gap-3 pl-7 relative">
<div key={rev.publicId ?? rev.revisionNumber} className="flex gap-3 pl-7 relative">
<div
className={`absolute left-1.5 top-1 w-3 h-3 rounded-full border-2 ${
isCurrent
+1 -1
View File
@@ -60,7 +60,7 @@ export function DrawingCard({ drawing }: { drawing: Drawing }) {
</div>
<div className="flex gap-2 flex-wrap">
<Link href={`/drawings/${drawing.uuid}`}>
<Link href={`/drawings/${drawing.publicId}`}>
<Button variant="outline" size="sm">
<Eye className="mr-2 h-4 w-4" />
View
+3 -3
View File
@@ -68,16 +68,16 @@ export const columns: ColumnDef<Drawing>[] = [
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<Link href={`/drawings/${drawing.uuid}`}>View Details</Link>
<Link href={`/drawings/${drawing.publicId}`}>View Details</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link href={`/drawings/${drawing.uuid}?edit=true`}>
<Link href={`/drawings/${drawing.publicId}?edit=true`}>
<Pencil className="mr-2 h-4 w-4" />
Edit Detail
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link href={`/drawings/${drawing.uuid}?upload=true`}>
<Link href={`/drawings/${drawing.publicId}?upload=true`}>
<Upload className="mr-2 h-4 w-4" />
Upload Revision
</Link>
@@ -26,7 +26,7 @@ export function NotificationsDropdown() {
const handleNotificationClick = (notification: Notification) => {
if (!notification.isRead) {
markAsRead.mutate(notification.uuid);
markAsRead.mutate(notification.publicId);
}
if (notification.link) {
router.push(notification.link);
@@ -115,7 +115,7 @@ export function TemplateTester({ open, onOpenChange, template }: TemplateTesterP
</SelectTrigger>
<SelectContent>
{(organizations as Organization[])?.map((org) => (
<SelectItem key={org.uuid} value={org.uuid}>
<SelectItem key={org.publicId} value={org.publicId}>
{org.organizationCode} - {org.organizationName}
</SelectItem>
))}
@@ -135,7 +135,7 @@ export function TemplateTester({ open, onOpenChange, template }: TemplateTesterP
</SelectTrigger>
<SelectContent>
{(organizations as Organization[])?.map((org) => (
<SelectItem key={org.uuid} value={org.uuid}>
<SelectItem key={org.publicId} value={org.publicId}>
{org.organizationCode} - {org.organizationName}
</SelectItem>
))}
+3 -3
View File
@@ -62,7 +62,7 @@ export function RFADetail({ data }: RFADetailProps) {
processMutation.mutate(
{
uuid: data.uuid,
uuid: data.publicId,
data: {
action: apiAction,
comments: comments,
@@ -79,7 +79,7 @@ export function RFADetail({ data }: RFADetailProps) {
const handleSubmit = () => {
submitMutation.mutate(
{ uuid: data.uuid, templateId },
{ uuid: data.publicId, templateId },
{
onSuccess: () => {
setActionState(null);
@@ -109,7 +109,7 @@ export function RFADetail({ data }: RFADetailProps) {
<div className="flex gap-2">
{currentRevision?.statusCode?.statusCode === 'DFT' && (
<>
<Link href={`/rfas/${data.uuid}/edit`}>
<Link href={`/rfas/${data.publicId}/edit`}>
<Button variant="outline">
<Edit className="mr-2 h-4 w-4" />
Edit
+2 -2
View File
@@ -92,7 +92,7 @@ export function RFAList({ data }: RFAListProps) {
return (
<div className="flex gap-2">
<Link href={`/rfas/${row.original.uuid}`}>
<Link href={`/rfas/${row.original.publicId}`}>
<Button variant="ghost" size="icon" title="View Details">
<Eye className="h-4 w-4" />
</Button>
@@ -100,7 +100,7 @@ export function RFAList({ data }: RFAListProps) {
<Button variant="ghost" size="icon" title="View File" onClick={handleViewFile}>
<FileText className="h-4 w-4" />
</Button>
<Link href={`/rfas/${row.original.uuid}/edit`}>
<Link href={`/rfas/${row.original.publicId}/edit`}>
<Button variant="ghost" size="icon" title="Edit">
<Edit className="h-4 w-4" />
</Button>
+3 -3
View File
@@ -36,8 +36,8 @@ const STATUS_LABEL: Record<string, string> = {
};
function getLink(result: SearchResult): string {
if (result.type === 'drawing') return `/drawings/${result.uuid}`;
return `/${result.type}s/${result.uuid}`;
if (result.type === 'drawing') return `/drawings/${result.publicId}`;
return `/${result.type}s/${result.publicId}`;
}
export function SearchResults({ results, query, loading }: SearchResultsProps) {
@@ -67,7 +67,7 @@ export function SearchResults({ results, query, loading }: SearchResultsProps) {
return (
<Card
key={`${result.type}-${result.uuid ?? index}`}
key={`${result.type}-${result.publicId ?? index}`}
className="px-5 py-4 hover:shadow-md transition-shadow group"
>
<Link href={getLink(result)}>
@@ -65,7 +65,7 @@ export function TransmittalList({ data }: TransmittalListProps) {
cell: ({ row }) => {
const item = row.original;
return (
<Link href={`/transmittals/${item.uuid}`}>
<Link href={`/transmittals/${item.publicId}`}>
<Button variant="ghost" size="icon" title="View Details">
<Eye className="h-4 w-4" />
</Button>
+5 -5
View File
@@ -47,7 +47,7 @@ export function useDrawings(type: DrawingType, params: DrawingSearchParams) {
if (response && response.data) {
const mappedData = response.data.map((d: ContractDrawing) => ({
...d,
uuid: d.uuid || (d as unknown as { id: string }).id,
publicId: d.publicId || (d as unknown as { id: string }).id,
drawingNumber: d.contractDrawingNo,
type: 'CONTRACT',
}));
@@ -60,11 +60,11 @@ export function useDrawings(type: DrawingType, params: DrawingSearchParams) {
if (response && response.data) {
const mappedData = response.data.map((d: ShopDrawing) => ({
...d,
uuid: d.uuid || (d as unknown as { id: string }).id,
publicId: d.publicId || (d as unknown as { id: string }).id,
type: 'SHOP',
title: d.currentRevision?.title || 'Untitled',
revision: d.currentRevision?.revisionNumber,
currentRevisionUuid: d.currentRevision?.uuid,
currentRevisionPublicId: d.currentRevision?.publicId,
legacyDrawingNumber: d.currentRevision?.legacyDrawingNumber,
}));
// Re-wrap to preserve meta
@@ -76,11 +76,11 @@ export function useDrawings(type: DrawingType, params: DrawingSearchParams) {
if (response && response.data) {
const mappedData = response.data.map((d: AsBuiltDrawing) => ({
...d,
uuid: d.uuid || (d as unknown as { id: string }).id,
publicId: d.publicId || (d as unknown as { id: string }).id,
type: 'AS_BUILT',
title: d.currentRevision?.title || 'Untitled',
revision: d.currentRevision?.revisionNumber,
currentRevisionUuid: d.currentRevision?.uuid,
currentRevisionPublicId: d.currentRevision?.publicId,
}));
// Re-wrap to preserve meta
response = { ...response, data: mappedData };
+3 -3
View File
@@ -3,7 +3,7 @@ import { NotificationResponse } from '@/types/notification';
// Mock Data
let mockNotifications = [
{
uuid: '019575a0-0001-7000-8000-000000000001',
publicId: '019575a0-0001-7000-8000-000000000001',
notificationId: 1,
title: 'RFA Approved',
message: 'RFA-001 has been approved by the Project Manager.',
@@ -13,7 +13,7 @@ let mockNotifications = [
link: '/rfas/1',
},
{
uuid: '019575a0-0002-7000-8000-000000000002',
publicId: '019575a0-0002-7000-8000-000000000002',
notificationId: 2,
title: 'New Correspondence',
message: 'You have received a new correspondence from Contractor A.',
@@ -23,7 +23,7 @@ let mockNotifications = [
link: '/correspondences/3',
},
{
uuid: '019575a0-0003-7000-8000-000000000003',
publicId: '019575a0-0003-7000-8000-000000000003',
notificationId: 3,
title: 'Drawing Revision Required',
message: 'Drawing S-201 requires revision based on recent comments.',
+1 -1
View File
@@ -21,7 +21,7 @@ export interface NumberingTemplate {
id: number | string;
projectCode: string;
projectName: string;
uuid?: string;
publicId?: string; // ADR-019: exposed as 'id' in API responses
};
formatTemplate: string;
disciplineId: number;
+1 -1
View File
@@ -30,7 +30,7 @@ const extractArrayData = <T>(value: unknown): T[] => {
const transformUser = (user: RawUser): User => {
return {
...(user as unknown as User),
uuid: (user.uuid as string) ?? '',
publicId: (user.publicId as string) ?? '',
userId: (user.user_id ?? user.userId) as number | undefined,
roles: (user.assignments?.map((a) => a.role) ?? []) as User['roles'],
};