diff --git a/backend/src/modules/master/dto/create-tag.dto.ts b/backend/src/modules/master/dto/create-tag.dto.ts index 9e3879f..13028c7 100644 --- a/backend/src/modules/master/dto/create-tag.dto.ts +++ b/backend/src/modules/master/dto/create-tag.dto.ts @@ -5,7 +5,7 @@ export class CreateTagDto { @ApiProperty({ example: 'URGENT', description: 'ชื่อ Tag' }) @IsString() @IsNotEmpty() - tag_name!: string; // เพิ่ม ! + tagName!: string; @ApiProperty({ example: 'คำอธิบาย', description: 'คำอธิบาย' }) @IsString() @@ -19,7 +19,7 @@ export class CreateTagDto { }) @IsString() @IsOptional() - color_code?: string; + colorCode?: string; @ApiProperty({ example: 1, @@ -27,5 +27,5 @@ export class CreateTagDto { required: false, }) @IsOptional() - project_id?: number | string; + projectId?: number | string; } diff --git a/backend/src/modules/master/dto/search-tag.dto.ts b/backend/src/modules/master/dto/search-tag.dto.ts index 1561669..ca6ede6 100644 --- a/backend/src/modules/master/dto/search-tag.dto.ts +++ b/backend/src/modules/master/dto/search-tag.dto.ts @@ -2,16 +2,17 @@ import { IsString, IsOptional, IsInt, Min } from 'class-validator'; import { Type } from 'class-transformer'; -import { ApiPropertyOptional } from '@nestjs/swagger'; +import { ApiPropertyOptional, ApiProperty } from '@nestjs/swagger'; export class SearchTagDto { - @ApiPropertyOptional({ - description: 'ID โครงการ (ใช้กรอง Tag ของแต่ละโปรเจกต์)', + @ApiProperty({ + example: 1, + description: + 'Project ID or UUID (ใช้กรอง Tag ของแต่ละโปรเจกต์) - ADR-019: Accept UUID', + required: false, }) @IsOptional() - @Type(() => Number) - @IsInt() - project_id?: number; + projectId?: number | string; @ApiPropertyOptional({ description: 'คำค้นหา (ชื่อ Tag หรือ คำอธิบาย)' }) @IsOptional() diff --git a/backend/src/modules/master/master.service.ts b/backend/src/modules/master/master.service.ts index d5b0c38..3c0837f 100644 --- a/backend/src/modules/master/master.service.ts +++ b/backend/src/modules/master/master.service.ts @@ -303,25 +303,24 @@ export class MasterService { .createQueryBuilder('tag') .leftJoinAndSelect('tag.project', 'project'); - if (query?.project_id) { - // In Tags, we use project_id (INT) directly or resolve if UUID passed via query + if (query?.projectId) { const internalId = await this.uuidResolver.resolveProjectId( - query.project_id + query.projectId ); - qb.andWhere('tag.project_id = :projectId', { + qb.andWhere('tag.projectId = :projectId', { projectId: internalId, }); } if (query?.search) { qb.andWhere( - '(tag.tag_name LIKE :search OR tag.description LIKE :search)', + '(tag.tagName LIKE :search OR tag.description LIKE :search)', { search: `%${query.search}%`, } ); } - qb.orderBy('tag.tag_name', 'ASC'); + qb.orderBy('tag.tagName', 'ASC'); if (query?.page && query?.limit) { const page = query.page; const limit = query.limit; @@ -342,11 +341,13 @@ export class MasterService { } async createTag(dto: CreateTagDto, userId: number) { - const internalProjectId = dto.project_id - ? await this.uuidResolver.resolveProjectId(dto.project_id) + const internalProjectId = dto.projectId + ? await this.uuidResolver.resolveProjectId(dto.projectId) : null; const tag = this.tagRepo.create({ - ...dto, + tagName: dto.tagName, + colorCode: dto.colorCode, + description: dto.description, projectId: internalProjectId, createdBy: userId, }); @@ -355,10 +356,18 @@ export class MasterService { async updateTag(id: number, dto: UpdateTagDto) { const tag = await this.findOneTag(id); - if (dto.project_id) { - dto.project_id = await this.uuidResolver.resolveProjectId(dto.project_id); + let internalProjectId = dto.projectId; + if (dto.projectId) { + internalProjectId = await this.uuidResolver.resolveProjectId( + dto.projectId + ); } - Object.assign(tag, dto); + Object.assign(tag, { + tagName: dto.tagName, + colorCode: dto.colorCode, + description: dto.description, + projectId: internalProjectId, + }); return this.tagRepo.save(tag); } diff --git a/frontend/app/(admin)/admin/doc-control/reference/tags/page.tsx b/frontend/app/(admin)/admin/doc-control/reference/tags/page.tsx index f971cc5..3d4f34c 100644 --- a/frontend/app/(admin)/admin/doc-control/reference/tags/page.tsx +++ b/frontend/app/(admin)/admin/doc-control/reference/tags/page.tsx @@ -24,7 +24,7 @@ export default function TagsPage() { const columns: ColumnDef[] = [ { - accessorKey: 'project_id', + accessorKey: 'projectId', header: 'Project', cell: ({ row }) => { const item = row.original as Tag & { project?: { id?: number | string; publicId?: string; projectName?: string; projectCode?: string } }; @@ -34,7 +34,7 @@ export default function TagsPage() { }, }, { - accessorKey: 'tag_name', + accessorKey: 'tagName', header: 'Tag Name', cell: ({ row }) => { const color = String(row.original.colorCode || 'default'); @@ -58,9 +58,9 @@ export default function TagsPage() { const formatPayload = (data: Record) => { const payload = { ...data }; - // ADR-019: project_id is now a UUID string or '__none__' for global - if (!payload.project_id || payload.project_id === '__none__') { - payload.project_id = null; + // ADR-019: projectId is now a UUID string or '__none__' for global + if (!payload.projectId || payload.projectId === '__none__') { + payload.projectId = null; } return payload; }; @@ -73,12 +73,12 @@ export default function TagsPage() { queryKey={['tags']} fetchFn={async () => { const items = await masterDataService.getTags(); - // ADR-019: Map project_id INT → project UUID for edit mode select matching + // ADR-019: Map projectId INT → project UUID for edit mode select matching return items.map((item) => { - const rec = item as Tag & { project?: { id?: number | string; publicId?: string }; project_id?: number | string }; + const rec = item as Tag & { project?: { id?: number | string; publicId?: string }; projectId?: number | string }; return { ...item, - project_id: rec.project?.publicId || rec.project?.id || (rec.project_id ? String(rec.project_id) : null), + projectId: rec.project?.publicId || rec.project?.id || (rec.projectId ? String(rec.projectId) : null), } as Tag; }); }} @@ -90,7 +90,7 @@ export default function TagsPage() { columns={columns} fields={[ { - name: 'project_id', + name: 'projectId', label: 'Project Scope', type: 'select', options: projectOptions, diff --git a/frontend/components/correspondences/form.tsx b/frontend/components/correspondences/form.tsx index fdb37ac..5eaf65d 100644 --- a/frontend/components/correspondences/form.tsx +++ b/frontend/components/correspondences/form.tsx @@ -439,81 +439,6 @@ export function CorrespondenceForm({ initialData, uuid }: { initialData?: Initia - {/* Subject */} -
- - - {errors.subject &&

{errors.subject.message}

} -
- - {/* Body */} -
- -