260326:1347 Fixing Refactor ADR-019 Naming convention uuid #01
CI / CD Pipeline / build (push) Failing after 17m29s
CI / CD Pipeline / deploy (push) Has been skipped

This commit is contained in:
admin
2026-03-26 13:47:07 +07:00
parent 978d66e49e
commit 1aff83214f
34 changed files with 217 additions and 222 deletions
@@ -14,45 +14,45 @@ class TestEntity extends UuidBaseEntity {
describe('UuidBaseEntity', () => {
// ==========================================================
// generateUuid() — @BeforeInsert hook
// generatePublicId() — @BeforeInsert hook
// ==========================================================
describe('generateUuid()', () => {
it('should generate a UUIDv7 when uuid is not set', () => {
describe('generatePublicId()', () => {
it('should generate a UUIDv7 when publicId is not set', () => {
const entity = new TestEntity();
expect(entity.uuid).toBeUndefined();
expect(entity.publicId).toBeUndefined();
entity.generateUuid();
entity.generatePublicId();
expect(entity.uuid).toBe('01912345-6789-7abc-8def-0123456789ab');
expect(entity.publicId).toBe('01912345-6789-7abc-8def-0123456789ab');
});
it('should not overwrite an existing uuid', () => {
it('should not overwrite an existing publicId', () => {
const entity = new TestEntity();
entity.uuid = 'existing-uuid-value-should-be-kept';
entity.publicId = 'existing-publicId-value-should-be-kept';
entity.generateUuid();
entity.generatePublicId();
expect(entity.uuid).toBe('existing-uuid-value-should-be-kept');
expect(entity.publicId).toBe('existing-publicId-value-should-be-kept');
});
it('should not overwrite a pre-set UUIDv1 from DB default', () => {
const entity = new TestEntity();
entity.uuid = '550e8400-e29b-11d4-a716-446655440000';
entity.publicId = '550e8400-e29b-11d4-a716-446655440000';
entity.generateUuid();
entity.generatePublicId();
expect(entity.uuid).toBe('550e8400-e29b-11d4-a716-446655440000');
expect(entity.publicId).toBe('550e8400-e29b-11d4-a716-446655440000');
});
it('should generate uuid when uuid is empty string', () => {
it('should generate publicId when publicId is empty string', () => {
const entity = new TestEntity();
entity.uuid = '';
entity.publicId = '';
entity.generateUuid();
entity.generatePublicId();
// Empty string is falsy, so generateUuid should assign a new value
expect(entity.uuid).toBe('01912345-6789-7abc-8def-0123456789ab');
// Empty string is falsy, so generatePublicId should assign a new value
expect(entity.publicId).toBe('01912345-6789-7abc-8def-0123456789ab');
});
});
@@ -66,12 +66,12 @@ describe('UuidBaseEntity', () => {
expect(entity).toBeInstanceOf(UuidBaseEntity);
});
it('should have uuid property accessible from subclass', () => {
it('should have publicId property accessible from subclass', () => {
const entity = new TestEntity();
entity.uuid = 'test-uuid';
entity.publicId = 'test-publicId';
entity.id = 42;
expect(entity.uuid).toBe('test-uuid');
expect(entity.publicId).toBe('test-publicId');
expect(entity.id).toBe(42);
});
});
@@ -2,27 +2,29 @@ import { Column, BeforeInsert } from 'typeorm';
import { v7 as uuidv7 } from 'uuid';
/**
* Abstract base entity providing a UUID public identifier column.
* Uses MariaDB native UUID type (stored as BINARY(16) internally,
* auto-converts to string format — no transformer needed).
* Abstract base entity providing a UUID public identifier.
*
* App generates UUIDv7 via @BeforeInsert(); DB DEFAULT UUID() is fallback.
* Naming Convention (ADR-019 v1.8.1):
* - TypeScript Property: `publicId` — semantic name indicating this is the public-facing identifier
* - Database Column: `uuid` — MariaDB native UUID type (stored as BINARY(16))
*
* @see ADR-019 Hybrid Identifier Strategy
* This avoids confusion between the property name and the DB data type,
* while clearly indicating this is the ID exposed via API (not internal INT PK).
*/
export abstract class UuidBaseEntity {
@Column({
type: 'uuid',
name: 'uuid', // DB column name (MariaDB native UUID type)
unique: true,
nullable: false,
comment: 'UUID Public Identifier (ADR-019)',
})
uuid!: string;
publicId!: string; // TypeScript property name — semantic, avoids type confusion
@BeforeInsert()
generateUuid(): void {
if (!this.uuid) {
this.uuid = uuidv7();
generatePublicId(): void {
if (!this.publicId) {
this.publicId = uuidv7();
}
}
}
@@ -95,7 +95,7 @@ export class CirculationService {
}
async findAll(searchDto: SearchCirculationDto, user: User) {
const { status, correspondenceUuid, page = 1, limit = 20 } = searchDto;
const { status, correspondencePublicId, page = 1, limit = 20 } = searchDto;
const query = this.circulationRepo
.createQueryBuilder('c')
.leftJoinAndSelect('c.creator', 'creator')
@@ -103,9 +103,9 @@ export class CirculationService {
.leftJoinAndSelect('routings.assignee', 'assignee')
.leftJoinAndSelect('c.correspondence', 'correspondence');
if (correspondenceUuid) {
query.where('correspondence.uuid = :corrUuid', {
corrUuid: correspondenceUuid,
if (correspondencePublicId) {
query.where('correspondence.publicId = :corrPublicId', {
corrPublicId: correspondencePublicId,
});
} else {
query.where('c.organizationId = :orgId', {
@@ -136,14 +136,14 @@ export class CirculationService {
return circulation;
}
async findOneByUuid(uuid: string) {
async findOneByUuid(publicId: string) {
const circulation = await this.circulationRepo.findOne({
where: { uuid },
where: { publicId },
relations: ['routings', 'routings.assignee', 'correspondence', 'creator'],
order: { routings: { stepNumber: 'ASC' } },
});
if (!circulation)
throw new NotFoundException(`Circulation UUID ${uuid} not found`);
throw new NotFoundException(`Circulation publicId ${publicId} not found`);
return circulation;
}
@@ -8,7 +8,7 @@ export class SearchCirculationDto {
@IsOptional()
@IsUUID('all')
correspondenceUuid?: string; // กรองตาม correspondence UUID (ADR-019)
correspondencePublicId?: string; // กรองตาม correspondence publicId (ADR-019)
@IsOptional()
@IsString()
@@ -100,18 +100,20 @@ export class ContractService {
return contract;
}
async findOneByUuid(uuid: string) {
async findOneByPublicId(publicId: string) {
const contract = await this.contractRepo.findOne({
where: { uuid },
where: { publicId },
relations: ['project'],
});
if (!contract)
throw new NotFoundException(`Contract UUID ${uuid} not found`);
throw new NotFoundException(
`Contract with publicId ${publicId} not found`
);
return contract;
}
async update(uuid: string, dto: UpdateContractDto) {
const contract = await this.findOneByUuid(uuid);
async update(publicId: string, dto: UpdateContractDto) {
const contract = await this.findOneByPublicId(publicId);
if (dto.projectId) {
dto.projectId = await this.uuidResolver.resolveProjectId(dto.projectId);
}
@@ -119,8 +121,8 @@ export class ContractService {
return this.contractRepo.save(contract);
}
async remove(uuid: string) {
const contract = await this.findOneByUuid(uuid);
async remove(publicId: string) {
const contract = await this.findOneByPublicId(publicId);
return this.contractRepo.remove(contract);
}
}
@@ -4,34 +4,18 @@ import {
PrimaryGeneratedColumn,
ManyToOne,
JoinColumn,
BeforeInsert,
} from 'typeorm';
import { v7 as uuidv7 } from 'uuid';
import { Exclude, Expose } from 'class-transformer';
import { BaseEntity } from '../../../common/entities/base.entity';
import { Exclude } from 'class-transformer';
import { UuidBaseEntity } from '../../../common/entities/uuid-base.entity';
import { Project } from '../../project/entities/project.entity';
@Entity('contracts')
export class Contract extends BaseEntity {
export class Contract extends UuidBaseEntity {
@PrimaryGeneratedColumn()
@Exclude()
id!: number;
@Expose({ name: 'id' })
@Column({
type: 'uuid',
unique: true,
nullable: false,
comment: 'UUID Public Identifier (ADR-019)',
})
uuid!: string;
@BeforeInsert()
generateUuid(): void {
if (!this.uuid) {
this.uuid = uuidv7();
}
}
// publicId inherited from UuidBaseEntity (DB column: uuid)
@Column({ name: 'project_id' })
projectId!: number;
@@ -112,7 +112,7 @@ export class CorrespondenceWorkflowService {
type: 'EMAIL',
entityType: 'correspondence',
entityId: revision.correspondenceId,
link: `/correspondences/${corrForNotify.uuid}`,
link: `/correspondences/${corrForNotify.publicId}`,
});
}
}
@@ -344,7 +344,7 @@ export class CorrespondenceService {
// Fire-and-forget search indexing (non-blocking, void intentional)
void this.searchService.indexDocument({
id: savedCorr.id,
uuid: savedCorr.uuid,
publicId: savedCorr.publicId,
type: 'correspondence',
docNumber: docNumber.number,
title: createDto.subject,
@@ -459,9 +459,9 @@ export class CorrespondenceService {
return correspondence;
}
async findOneByUuid(uuid: string) {
async findOneByUuid(publicId: string) {
const correspondence = await this.correspondenceRepo.findOne({
where: { uuid },
where: { publicId },
relations: [
'revisions',
'revisions.status',
@@ -474,16 +474,18 @@ export class CorrespondenceService {
});
if (!correspondence) {
throw new NotFoundException(`Correspondence with UUID ${uuid} not found`);
throw new NotFoundException(
`Correspondence with UUID ${publicId} not found`
);
}
return correspondence;
}
async addReference(id: number, dto: AddReferenceDto) {
const source = await this.correspondenceRepo.findOne({ where: { id } });
// ADR-019: Resolve target UUID → internal INT id
// ADR-019: Resolve target publicId → internal INT id
const target = await this.correspondenceRepo.findOne({
where: { uuid: dto.targetUuid },
where: { publicId: dto.targetUuid },
});
if (!source || !target) {
@@ -814,7 +816,7 @@ export class CorrespondenceService {
// Re-index updated document in Elasticsearch (fire-and-forget)
void this.searchService.indexDocument({
id: updated.id,
uuid: updated.uuid,
publicId: updated.publicId,
type: 'correspondence',
docNumber: updated.correspondenceNumber,
title: updateDto.subject ?? updated.revisions?.[0]?.subject,
@@ -896,8 +898,8 @@ export class CorrespondenceService {
* Business Rule Implementation: EC-CORR-001 - Cancel Correspondence with Downstream Circulation
* Cancel correspondence and handle related circulations
*/
async cancel(uuid: string, reason: string, user: User) {
const correspondence = await this.findOneByUuid(uuid);
async cancel(publicId: string, reason: string, user: User) {
const correspondence = await this.findOneByUuid(publicId);
// Check if user has permission to cancel (Org Admin or Superadmin only)
const permissions = await this.userService.getUserPermissions(user.user_id);
@@ -983,7 +985,7 @@ export class CorrespondenceService {
// Re-index cancelled status in Elasticsearch (fire-and-forget)
void this.searchService.indexDocument({
id: correspondence.id,
uuid: correspondence.uuid,
publicId: correspondence.publicId,
type: 'correspondence',
docNumber: correspondence.correspondenceNumber,
title: currentRevision.subject,
@@ -1005,7 +1007,7 @@ export class CorrespondenceService {
type: 'EMAIL',
entityType: 'correspondence',
entityId: correspondence.id,
link: `/correspondences/${correspondence.uuid}`,
link: `/correspondences/${correspondence.publicId}`,
});
}
})
@@ -1031,19 +1033,19 @@ export class CorrespondenceService {
}
async bulkCancel(
uuids: string[],
publicIds: string[],
reason: string,
user: User
): Promise<{ succeeded: string[]; failed: string[] }> {
const succeeded: string[] = [];
const failed: string[] = [];
for (const uuid of uuids) {
for (const publicId of publicIds) {
try {
await this.cancel(uuid, reason, user);
succeeded.push(uuid);
await this.cancel(publicId, reason, user);
succeeded.push(publicId);
} catch {
failed.push(uuid);
failed.push(publicId);
}
}
@@ -63,7 +63,7 @@ export class DueDateReminderService {
type: 'EMAIL',
entityType: 'correspondence',
entityId: corr.id,
link: `/correspondences/${corr.uuid}`,
link: `/correspondences/${corr.publicId}`,
});
} catch (err) {
this.logger.warn(
@@ -89,10 +89,12 @@ export class OrganizationService {
return org;
}
async findOneByUuid(uuid: string) {
const org = await this.orgRepo.findOne({ where: { uuid } });
async findOneByUuid(publicId: string) {
const org = await this.orgRepo.findOne({ where: { publicId } });
if (!org)
throw new NotFoundException(`Organization UUID ${uuid} not found`);
throw new NotFoundException(
`Organization publicId ${publicId} not found`
);
return org;
}
@@ -1,36 +1,15 @@
import {
Entity,
Column,
PrimaryGeneratedColumn,
OneToMany,
BeforeInsert,
} from 'typeorm';
import { v7 as uuidv7 } from 'uuid';
import { Exclude, Expose } from 'class-transformer';
import { BaseEntity } from '../../../common/entities/base.entity';
import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
import { Exclude } from 'class-transformer';
import { UuidBaseEntity } from '../../../common/entities/uuid-base.entity';
import { Contract } from '../../contract/entities/contract.entity';
@Entity('projects')
export class Project extends BaseEntity {
export class Project extends UuidBaseEntity {
@PrimaryGeneratedColumn()
@Exclude()
id!: number;
@Expose({ name: 'id' })
@Column({
type: 'uuid',
unique: true,
nullable: false,
comment: 'UUID Public Identifier (ADR-019)',
})
uuid!: string;
@BeforeInsert()
generateUuid(): void {
if (!this.uuid) {
this.uuid = uuidv7();
}
}
// publicId inherited from UuidBaseEntity (DB column: uuid)
@Column({ name: 'project_code', unique: true, length: 50 })
projectCode!: string;
+11 -9
View File
@@ -91,21 +91,23 @@ export class ProjectService {
return project;
}
async findOneByUuid(uuid: string) {
async findOneByUuid(publicId: string) {
const project = await this.projectRepository.findOne({
where: { uuid },
where: { publicId },
relations: ['contracts'],
});
if (!project) {
throw new NotFoundException(`Project UUID ${uuid} not found`);
throw new NotFoundException(
`Project with publicId ${publicId} not found`
);
}
return project;
}
async update(uuid: string, updateDto: UpdateProjectDto) {
const project = await this.findOneByUuid(uuid);
async update(publicId: string, updateDto: UpdateProjectDto) {
const project = await this.findOneByUuid(publicId);
// Merge ข้อมูลใหม่ใส่ข้อมูลเดิม
this.projectRepository.merge(project, updateDto);
@@ -113,14 +115,14 @@ export class ProjectService {
return this.projectRepository.save(project);
}
async remove(uuid: string) {
const project = await this.findOneByUuid(uuid);
async remove(publicId: string) {
const project = await this.findOneByUuid(publicId);
// ใช้ Soft Delete
return this.projectRepository.softRemove(project);
}
async findContracts(uuid: string) {
const project = await this.findOneByUuid(uuid);
async findContracts(publicId: string) {
const project = await this.findOneByUuid(publicId);
return project.contracts;
}
+5 -5
View File
@@ -63,7 +63,7 @@ export class RfaController {
@ApiOperation({ summary: 'Submit RFA to Workflow' })
@ApiParam({
name: 'uuid',
description: 'RFA UUID (from correspondences.uuid)',
description: 'RFA publicId (from correspondences.publicId)',
})
@ApiBody({ type: SubmitRfaDto })
@ApiResponse({ status: 200, description: 'RFA submitted successfully' })
@@ -83,7 +83,7 @@ export class RfaController {
@ApiOperation({ summary: 'Process Workflow Action (Approve/Reject)' })
@ApiParam({
name: 'uuid',
description: 'RFA UUID (from correspondences.uuid)',
description: 'RFA publicId (from correspondences.publicId)',
})
@ApiBody({ type: WorkflowActionDto })
@ApiResponse({
@@ -120,7 +120,7 @@ export class RfaController {
@ApiOperation({ summary: 'Get RFA details with revisions and items' })
@ApiParam({
name: 'uuid',
description: 'RFA UUID (from correspondences.uuid)',
description: 'RFA publicId (from correspondences.publicId)',
})
@ApiResponse({ status: 200, description: 'RFA details' })
@RequirePermission('document.view')
@@ -130,7 +130,7 @@ export class RfaController {
@Put(':uuid')
@ApiOperation({ summary: 'Update Draft RFA fields (EC-RFA-002: DFT only)' })
@ApiParam({ name: 'uuid', description: 'RFA UUID' })
@ApiParam({ name: 'uuid', description: 'RFA publicId' })
@ApiBody({ type: UpdateRfaDto })
@ApiResponse({ status: 200, description: 'RFA updated successfully' })
@RequirePermission('rfa.create')
@@ -146,7 +146,7 @@ export class RfaController {
@Delete(':uuid')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'Cancel Draft RFA (sets status to CC)' })
@ApiParam({ name: 'uuid', description: 'RFA UUID' })
@ApiParam({ name: 'uuid', description: 'RFA publicId' })
@ApiResponse({ status: 200, description: 'RFA cancelled successfully' })
@RequirePermission('rfa.create')
@Audit('rfa.cancel', 'rfa')
+17 -17
View File
@@ -44,7 +44,7 @@ type CorrRevWithRfa = CorrespondenceRevision & { rfaRevision?: RfaRevision };
/** RFA entity + a flat `revisions` convenience array for the frontend */
export interface RfaMapped extends Rfa {
uuid?: string; // ADR-019: top-level UUID from correspondence
publicId?: string; // ADR-019: top-level publicId from correspondence
revisions: CorrRevWithRfa[];
}
@@ -429,7 +429,7 @@ export class RfaService {
this.searchService
.indexDocument({
id: savedCorr.id,
uuid: savedCorr.uuid, // ADR-019: index UUID for search
publicId: savedCorr.publicId, // ADR-019: index publicId for search
type: 'rfa',
docNumber: docNumber.number,
title: createDto.subject,
@@ -536,7 +536,7 @@ export class RfaService {
(rfa.correspondence?.revisions as CorrRevWithRfa[] | undefined) ?? [];
return {
...rfa,
uuid: rfa.correspondence?.uuid, // ADR-019: expose UUID at top level
publicId: rfa.correspondence?.publicId, // ADR-019: expose publicId at top level
revisions: revisions.map((cr) => ({
...cr,
...(cr.rfaRevision ?? {}),
@@ -557,27 +557,27 @@ export class RfaService {
}
/**
* ADR-019: Find RFA by the parent Correspondence UUID (public identifier).
* Resolves correspondence.uuid internal rfa.id
* ADR-019: Find RFA by the parent Correspondence publicId (public identifier).
* Resolves correspondence.publicId internal rfa.id
*/
async findOneByUuid(uuid: string) {
async findOneByUuid(publicId: string) {
const correspondence = await this.correspondenceRepo.findOne({
where: { uuid },
where: { publicId },
select: ['id'],
});
if (!correspondence) {
throw new NotFoundException(`RFA with UUID ${uuid} not found`);
throw new NotFoundException(`RFA with publicId ${publicId} not found`);
}
return this.findOne(correspondence.id);
}
async findOneByUuidRaw(uuid: string) {
async findOneByUuidRaw(publicId: string) {
const correspondence = await this.correspondenceRepo.findOne({
where: { uuid },
where: { publicId },
select: ['id'],
});
if (!correspondence) {
throw new NotFoundException(`RFA with UUID ${uuid} not found`);
throw new NotFoundException(`RFA with publicId ${publicId} not found`);
}
return this.findOne(correspondence.id, true);
}
@@ -618,7 +618,7 @@ export class RfaService {
(rfa.correspondence?.revisions as CorrRevWithRfa[] | undefined) ?? [];
const mappedRfa: RfaMapped = {
...rfa,
uuid: rfa.correspondence?.uuid, // ADR-019: expose UUID at top level
publicId: rfa.correspondence?.publicId, // ADR-019: expose publicId at top level
revisions: revisions.map((cr) => ({
...cr,
...(cr.rfaRevision ?? {}),
@@ -846,8 +846,8 @@ export class RfaService {
* Update a Draft RFA's revision fields (subject, body, remarks, description, dueDate).
* EC-RFA-002: Only allowed when current revision is in DFT status.
*/
async update(uuid: string, dto: UpdateRfaDto, _user: User) {
const rfa = await this.findOneByUuidRaw(uuid);
async update(publicId: string, dto: UpdateRfaDto, _user: User) {
const rfa = await this.findOneByUuidRaw(publicId);
const corrRevisions =
(rfa.correspondence?.revisions as CorrRevWithRfa[] | undefined) ?? [];
const currentCorrRev = corrRevisions.find((r) => r.isCurrent);
@@ -880,15 +880,15 @@ export class RfaService {
await this.rfaRevisionRepo.save(currentRfaRev);
}
return this.findOneByUuid(uuid);
return this.findOneByUuid(publicId);
}
/**
* Cancel (soft-delete) a Draft RFA by setting its status to CC.
* EC-RFA-002: Only allowed when current revision is in DFT status.
*/
async cancel(uuid: string, user: User) {
const rfa = await this.findOneByUuidRaw(uuid);
async cancel(publicId: string, user: User) {
const rfa = await this.findOneByUuidRaw(publicId);
const corrRevisions =
(rfa.correspondence?.revisions as CorrRevWithRfa[] | undefined) ?? [];
const currentCorrRev = corrRevisions.find((r) => r.isCurrent);
+8 -2
View File
@@ -73,12 +73,18 @@ export class SearchService implements OnModuleInit {
* Index (Create/Update)
*/
async indexDocument(
doc: Record<string, unknown> & { type: string; id?: number; uuid?: string }
doc: Record<string, unknown> & {
type: string;
id?: number;
publicId?: string;
}
) {
try {
return await this.esService.index({
index: this.indexName,
id: doc.uuid ? `${doc.type}_${doc.uuid}` : `${doc.type}_${doc.id}`, // ADR-019: prefer UUID key
id: doc.publicId
? `${doc.type}_${doc.publicId}`
: `${doc.type}_${doc.id}`, // ADR-019: prefer publicId key
document: doc, // ✅ Library รุ่นใหม่ใช้ 'document' แทน 'body' ในบางเวอร์ชัน
});
} catch (error) {
@@ -61,8 +61,8 @@ export class TransmittalController {
@Get(':uuid')
@ApiOperation({ summary: 'Get Transmittal details' })
@ApiParam({
name: 'uuid',
description: 'Transmittal UUID (from correspondences.uuid)',
name: 'publicId',
description: 'Transmittal publicId (from correspondences.publicId)',
})
@RequirePermission('document.view')
findOne(@Param('uuid', ParseUuidPipe) uuid: string) {
@@ -159,16 +159,18 @@ export class TransmittalService {
}
/**
* ADR-019: Find Transmittal by parent Correspondence UUID (public identifier).
* Resolves correspondence.uuid internal correspondenceId (INT)
* ADR-019: Find Transmittal by parent Correspondence publicId (public identifier).
* Resolves correspondence.publicId internal correspondenceId (INT)
*/
async findOneByUuid(uuid: string): Promise<Transmittal> {
async findOneByUuid(publicId: string): Promise<Transmittal> {
const correspondence = await this.dataSource.manager.findOne(
Correspondence,
{ where: { uuid }, select: ['id'] }
{ where: { publicId }, select: ['id'] }
);
if (!correspondence) {
throw new NotFoundException(`Transmittal with UUID ${uuid} not found`);
throw new NotFoundException(
`Transmittal with publicId ${publicId} not found`
);
}
return this.findOne(correspondence.id);
}
@@ -218,10 +220,10 @@ export class TransmittalService {
.take(limit)
.getManyAndCount();
// ADR-019: Map correspondence.uuid to top level for frontend convenience
// ADR-019: Map correspondence.publicId to top level for frontend convenience
const mappedItems = items.map((t) => ({
...t,
uuid: t.correspondence?.uuid,
publicId: t.correspondence?.publicId,
}));
return {
+4 -4
View File
@@ -86,7 +86,7 @@ export class UserService {
.leftJoinAndSelect('assignments.role', 'role')
.select([
'user.user_id',
'user.uuid',
'user.publicId',
'user.username',
'user.email',
'user.firstName',
@@ -156,9 +156,9 @@ export class UserService {
return user;
}
async findOneByUuid(uuid: string): Promise<User> {
async findOneByUuid(publicId: string): Promise<User> {
const user = await this.usersRepository.findOne({
where: { uuid },
where: { publicId },
relations: [
'preference',
'assignments',
@@ -168,7 +168,7 @@ export class UserService {
});
if (!user) {
throw new NotFoundException(`User with UUID ${uuid} not found`);
throw new NotFoundException(`User with publicId ${publicId} not found`);
}
return user;