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
@@ -1,12 +1,36 @@
import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
import {
Entity,
Column,
PrimaryGeneratedColumn,
OneToMany,
BeforeInsert,
} from 'typeorm';
import { v7 as uuidv7 } from 'uuid';
import { Exclude } from 'class-transformer';
import { BaseEntity } from '../../../common/entities/base.entity';
import { Contract } from '../../contract/entities/contract.entity';
@Entity('projects')
export class Project extends BaseEntity {
@PrimaryGeneratedColumn()
@Exclude()
id!: number;
@Column({
type: 'uuid',
unique: true,
nullable: false,
comment: 'UUID Public Identifier (ADR-019)',
})
uuid!: string;
@BeforeInsert()
generateUuid(): void {
if (!this.uuid) {
this.uuid = uuidv7();
}
}
@Column({ name: 'project_code', unique: true, length: 50 })
projectCode!: string;
@@ -8,7 +8,6 @@ import {
Delete,
Query,
UseGuards,
ParseIntPipe,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
@@ -19,6 +18,7 @@ import { SearchProjectDto } from './dto/search-project.dto';
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
import { RbacGuard } from '../../common/guards/rbac.guard';
import { ParseUuidPipe } from '../../common/pipes/parse-uuid.pipe';
import { RequirePermission } from '../../common/decorators/require-permission.decorator';
@ApiTags('Projects')
@@ -49,34 +49,34 @@ export class ProjectController {
return this.projectService.findAllOrganizations();
}
@Get(':id/contracts')
@Get(':uuid/contracts')
@ApiOperation({ summary: 'List All Contracts in Project' })
@RequirePermission('project.view')
findContracts(@Param('id', ParseIntPipe) id: number) {
return this.projectService.findContracts(id);
findContracts(@Param('uuid', ParseUuidPipe) uuid: string) {
return this.projectService.findContracts(uuid);
}
@Get(':id')
@Get(':uuid')
@ApiOperation({ summary: 'Get Project Details' })
@RequirePermission('project.view')
findOne(@Param('id', ParseIntPipe) id: number) {
return this.projectService.findOne(id);
findOne(@Param('uuid', ParseUuidPipe) uuid: string) {
return this.projectService.findOneByUuid(uuid);
}
@Patch(':id')
@Patch(':uuid')
@ApiOperation({ summary: 'Update Project' })
@RequirePermission('project.edit')
update(
@Param('id', ParseIntPipe) id: number,
@Param('uuid', ParseUuidPipe) uuid: string,
@Body() updateDto: UpdateProjectDto
) {
return this.projectService.update(id, updateDto);
return this.projectService.update(uuid, updateDto);
}
@Delete(':id')
@Delete(':uuid')
@ApiOperation({ summary: 'Delete Project (Soft Delete)' })
@RequirePermission('project.delete')
remove(@Param('id', ParseIntPipe) id: number) {
return this.projectService.remove(id);
remove(@Param('uuid', ParseUuidPipe) uuid: string) {
return this.projectService.remove(uuid);
}
}
+19 -14
View File
@@ -91,8 +91,21 @@ export class ProjectService {
return project;
}
async update(id: number, updateDto: UpdateProjectDto) {
const project = await this.findOne(id);
async findOneByUuid(uuid: string) {
const project = await this.projectRepository.findOne({
where: { uuid },
relations: ['contracts'],
});
if (!project) {
throw new NotFoundException(`Project UUID ${uuid} not found`);
}
return project;
}
async update(uuid: string, updateDto: UpdateProjectDto) {
const project = await this.findOneByUuid(uuid);
// Merge ข้อมูลใหม่ใส่ข้อมูลเดิม
this.projectRepository.merge(project, updateDto);
@@ -100,22 +113,14 @@ export class ProjectService {
return this.projectRepository.save(project);
}
async remove(id: number) {
const project = await this.findOne(id);
async remove(uuid: string) {
const project = await this.findOneByUuid(uuid);
// ใช้ Soft Delete
return this.projectRepository.softRemove(project);
}
async findContracts(projectId: number) {
const project = await this.projectRepository.findOne({
where: { id: projectId },
relations: ['contracts'],
});
if (!project) {
throw new NotFoundException(`Project ID ${projectId} not found`);
}
async findContracts(uuid: string) {
const project = await this.findOneByUuid(uuid);
return project.contracts;
}