260316:1117 20260316:1100 Refactor UUID
Build and Deploy / deploy (push) Successful in 9m24s

This commit is contained in:
admin
2026-03-16 11:17:15 +07:00
parent b93cd91325
commit c5c3ed9016
92 changed files with 1726 additions and 620 deletions
@@ -104,7 +104,7 @@ export function OrganizationDialog({
if (organization) {
updateOrg.mutate(
{ id: organization.id, data: submitData },
{ uuid: organization.uuid, data: submitData },
{ onSuccess: () => onOpenChange(false) }
);
} else {
+6 -3
View File
@@ -151,7 +151,7 @@ export function UserDialog({ open, onOpenChange, user }: UserDialogProps) {
if (user) {
updateUser.mutate(
{ id: user.userId, data: payload },
{ uuid: user.uuid, data: payload },
{ onSuccess: () => onOpenChange(false) }
);
} else {
@@ -230,10 +230,13 @@ export function UserDialog({ open, onOpenChange, user }: UserDialogProps) {
<SelectValue placeholder="Select Organization" />
</SelectTrigger>
<SelectContent>
{/* TODO: ADR-019 — Backend DTO needs to accept UUID for primaryOrganization.
Currently using org.id which is excluded from API responses.
Temporary: org.id may still exist in some query responses. */}
{organizations?.map((org: any) => (
<SelectItem
key={org.id}
value={org.id.toString()}
key={org.uuid ?? org.id}
value={(org.id ?? 0).toString()}
>
{org.organizationCode} - {org.organizationName}
</SelectItem>
@@ -113,7 +113,7 @@ export function CirculationList({ data }: CirculationListProps) {
const item = row.original;
return (
<div className="flex gap-1">
<Link href={`/circulation/${item.id}`}>
<Link href={`/circulation/${item.uuid}`}>
<Button variant="ghost" size="icon" title="View Details">
<Eye className="h-4 w-4" />
</Button>
@@ -39,7 +39,7 @@ export function CorrespondenceDetail({ data }: CorrespondenceDetailProps) {
const handleSubmit = () => {
if (confirm("Are you sure you want to submit this correspondence?")) {
submitMutation.mutate({
id: data.id,
uuid: data.uuid,
data: {}
});
}
@@ -50,7 +50,7 @@ export function CorrespondenceDetail({ data }: CorrespondenceDetailProps) {
const action = actionState === "approve" ? "APPROVE" : "REJECT";
processMutation.mutate({
id: data.id,
uuid: data.uuid,
data: {
action,
comments
@@ -83,7 +83,7 @@ export function CorrespondenceDetail({ data }: CorrespondenceDetailProps) {
<div className="flex gap-2">
{/* EDIT BUTTON LOGIC: Show if DRAFT */}
{status === "DRAFT" && (
<Link href={`/correspondences/${data.id}/edit`}>
<Link href={`/correspondences/${data.uuid}/edit`}>
<Button variant="outline">
<Edit className="mr-2 h-4 w-4" />
Edit
+5 -5
View File
@@ -42,7 +42,7 @@ const correspondenceSchema = z.object({
type FormData = z.infer<typeof correspondenceSchema>;
export function CorrespondenceForm({ initialData, id }: { initialData?: any, id?: number }) {
export function CorrespondenceForm({ initialData, uuid }: { initialData?: any, uuid?: string }) {
const router = useRouter();
const createMutation = useCreateCorrespondence();
const updateMutation = useUpdateCorrespondence();
@@ -107,10 +107,10 @@ export function CorrespondenceForm({ initialData, id }: { initialData?: any, id?
},
};
if (id && initialData) {
if (uuid && initialData) {
// UPDATE Mode
updateMutation.mutate({ id, data: payload }, {
onSuccess: () => router.push(`/correspondences/${id}`)
updateMutation.mutate({ uuid, data: payload }, {
onSuccess: () => router.push(`/correspondences/${uuid}`)
});
} else {
// CREATE Mode
@@ -420,7 +420,7 @@ export function CorrespondenceForm({ initialData, id }: { initialData?: any, id?
</Button>
<Button type="submit" disabled={isPending}>
{isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
{id ? "Update Correspondence" : "Create Correspondence"}
{uuid ? "Update Correspondence" : "Create Correspondence"}
</Button>
</div>
</form>
+5 -5
View File
@@ -59,15 +59,15 @@ export function CorrespondenceList({ data }: CorrespondenceListProps) {
id: "actions",
cell: ({ row }) => {
const item = row.original;
// Edit/View link goes to the DOCUMENT detail (correspondence.id)
// Ideally we might pass ?revId=item.id to view specific revision, but detail page defaults to latest.
// 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.
// For editing, we edit the document.
const docId = item.correspondence.id;
const docUuid = item.correspondence.uuid;
const statusCode = item.status?.statusCode;
return (
<div className="flex gap-2">
<Link href={`/correspondences/${docId}`}>
<Link href={`/correspondences/${docUuid}`}>
<Button variant="ghost" size="icon" title="View Details">
<Eye className="h-4 w-4" />
</Button>
@@ -89,7 +89,7 @@ export function CorrespondenceList({ data }: CorrespondenceListProps) {
<FileText className="h-4 w-4" />
</Button>
{statusCode === "DRAFT" && (
<Link href={`/correspondences/${docId}/edit`}>
<Link href={`/correspondences/${docUuid}/edit`}>
<Button variant="ghost" size="icon" title="Edit">
<Edit className="h-4 w-4" />
</Button>
+1 -1
View File
@@ -58,7 +58,7 @@ export function DrawingCard({ drawing }: { drawing: Drawing }) {
</div>
<div className="flex gap-2 flex-wrap">
<Link href={`/drawings/${drawing.drawingId}`}>
<Link href={`/drawings/${drawing.uuid}`}>
<Button variant="outline" size="sm">
<Eye className="mr-2 h-4 w-4" />
View
+5 -5
View File
@@ -16,7 +16,8 @@ import { useSearchSuggestions } from "@/hooks/use-search";
/** Search suggestion item returned from the API */
interface SearchSuggestion {
id: string | number;
uuid: string;
id?: string | number; // Excluded from API responses (ADR-019)
type: string;
title: string;
documentNumber?: string;
@@ -97,12 +98,11 @@ export function GlobalSearch() {
<CommandGroup heading="Suggestions">
{(suggestions as SearchSuggestion[]).map((item) => (
<CommandItem
key={`${item.type}-${item.id}`}
key={`${item.type}-${item.uuid}`}
onSelect={() => {
setQuery(item.title);
// Assumption: item has type and id.
// If type is missing, we might need a map or check usage in backend response
router.push(`/${item.type}s/${item.id}`);
// ADR-019: Use UUID for public routes
router.push(`/${item.type}s/${item.uuid}`);
setOpen(false);
}}
>
@@ -26,7 +26,7 @@ export function NotificationsDropdown() {
const handleNotificationClick = (notification: Notification) => {
if (!notification.isRead) {
markAsRead.mutate(notification.notificationId);
markAsRead.mutate(notification.uuid);
}
if (notification.link) {
router.push(notification.link);
@@ -117,7 +117,7 @@ export function TemplateTester({ open, onOpenChange, template }: TemplateTesterP
</SelectTrigger>
<SelectContent>
{(organizations as Organization[])?.map((org) => (
<SelectItem key={org.id} value={org.id.toString()}>
<SelectItem key={org.uuid} value={(org.id ?? org.uuid).toString()}>
{org.organizationCode} - {org.organizationName}
</SelectItem>
))}
@@ -137,7 +137,7 @@ export function TemplateTester({ open, onOpenChange, template }: TemplateTesterP
</SelectTrigger>
<SelectContent>
{(organizations as Organization[])?.map((org) => (
<SelectItem key={org.id} value={org.id.toString()}>
<SelectItem key={org.uuid} value={(org.id ?? org.uuid).toString()}>
{org.organizationCode} - {org.organizationName}
</SelectItem>
))}
+2 -2
View File
@@ -44,7 +44,7 @@ export function SearchResults({ results, query, loading }: SearchResultsProps) {
};
const getLink = (result: SearchResult) => {
return `/${result.type}s/${result.id}`; // Assuming routes are plural (correspondences, rfas, drawings)
return `/${result.type}s/${result.uuid}`; // ADR-019: Use UUID for public routes
};
return (
@@ -54,7 +54,7 @@ export function SearchResults({ results, query, loading }: SearchResultsProps) {
return (
<Card
key={`${result.type}-${result.id}-${index}`}
key={`${result.type}-${result.uuid}-${index}`}
className="p-6 hover:shadow-md transition-shadow group"
>
<Link href={getLink(result)}>