251128:1700 Backend to T3.1.1

This commit is contained in:
admin
2025-11-28 17:12:05 +07:00
parent b22d00877e
commit f7a43600a3
50 changed files with 4891 additions and 2849 deletions
@@ -0,0 +1,57 @@
// File: src/modules/correspondence/dto/create-routing-template.dto.ts
import {
IsString,
IsNotEmpty,
IsOptional,
IsInt,
IsArray,
ValidateNested,
IsEnum,
IsBoolean,
} from 'class-validator';
import { Type } from 'class-transformer';
export class CreateRoutingTemplateStepDto {
@IsInt()
@IsNotEmpty()
sequence!: number;
@IsInt()
@IsNotEmpty()
toOrganizationId!: number;
@IsInt()
@IsOptional()
roleId?: number;
@IsString()
@IsOptional()
stepPurpose?: string = 'FOR_REVIEW';
@IsInt()
@IsOptional()
expectedDays?: number;
}
export class CreateRoutingTemplateDto {
@IsString()
@IsNotEmpty()
templateName!: string;
@IsString()
@IsOptional()
description?: string;
@IsInt()
@IsOptional()
projectId?: number;
@IsBoolean()
@IsOptional()
isActive?: boolean;
@IsArray()
@ValidateNested({ each: true })
@Type(() => CreateRoutingTemplateStepDto)
steps!: CreateRoutingTemplateStepDto[];
}
@@ -1,3 +1,4 @@
// File: src/modules/correspondence/entities/correspondence-revision.entity.ts
import {
Entity,
Column,
@@ -5,12 +6,16 @@ import {
ManyToOne,
JoinColumn,
CreateDateColumn,
Index,
} from 'typeorm';
import { Correspondence } from './correspondence.entity.js';
import { CorrespondenceStatus } from './correspondence-status.entity.js';
import { User } from '../../user/entities/user.entity.js';
@Entity('correspondence_revisions')
// ✅ เพิ่ม Index สำหรับ Virtual Columns เพื่อให้ Search เร็วขึ้น
@Index('idx_corr_rev_v_project', ['vRefProjectId'])
@Index('idx_corr_rev_v_type', ['vRefType'])
export class CorrespondenceRevision {
@PrimaryGeneratedColumn()
id!: number;
@@ -39,6 +44,27 @@ export class CorrespondenceRevision {
@Column({ type: 'json', nullable: true })
details?: any; // เก็บข้อมูลแบบ Dynamic ตาม Type
// ✅ [New] Virtual Column: ดึง Project ID จาก JSON details
@Column({
name: 'v_ref_project_id',
type: 'int',
generatedType: 'VIRTUAL',
asExpression: "JSON_UNQUOTE(JSON_EXTRACT(details, '$.projectId'))",
nullable: true,
})
vRefProjectId?: number;
// ✅ [New] Virtual Column: ดึง Document SubType จาก JSON details
@Column({
name: 'v_doc_subtype',
type: 'varchar',
length: 50,
generatedType: 'VIRTUAL',
asExpression: "JSON_UNQUOTE(JSON_EXTRACT(details, '$.subType'))",
nullable: true,
})
vRefType?: string;
// Dates
@Column({ name: 'document_date', type: 'date', nullable: true })
documentDate?: Date;
@@ -1,3 +1,4 @@
// File: src/modules/correspondence/entities/correspondence-routing.entity.ts
import {
Entity,
Column,
@@ -9,7 +10,7 @@ import {
import { CorrespondenceRevision } from './correspondence-revision.entity.js';
import { Organization } from '../../project/entities/organization.entity.js';
import { User } from '../../user/entities/user.entity.js';
import { RoutingTemplate } from './routing-template.entity.js'; // <--- ✅ เพิ่ม Import นี้ครับ
import { RoutingTemplate } from './routing-template.entity.js';
@Entity('correspondence_routings')
export class CorrespondenceRouting {
@@ -49,6 +50,10 @@ export class CorrespondenceRouting {
@Column({ name: 'processed_at', type: 'datetime', nullable: true })
processedAt?: Date;
// ✅ [New] เพิ่ม State Context เพื่อเก็บ Snapshot ข้อมูล Workflow ณ จุดนั้น
@Column({ name: 'state_context', type: 'json', nullable: true })
stateContext?: any;
@CreateDateColumn({ name: 'created_at' })
createdAt!: Date;
@@ -57,7 +62,7 @@ export class CorrespondenceRouting {
@JoinColumn({ name: 'correspondence_id' })
correspondenceRevision?: CorrespondenceRevision;
@ManyToOne(() => RoutingTemplate) // ตอนนี้ TypeScript จะรู้จัก RoutingTemplate แล้ว
@ManyToOne(() => RoutingTemplate)
@JoinColumn({ name: 'template_id' })
template?: RoutingTemplate;
@@ -1,12 +1,14 @@
// File: src/modules/correspondence/entities/routing-template-step.entity.ts
import {
Entity,
Column,
PrimaryGeneratedColumn,
Column,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { RoutingTemplate } from './routing-template.entity.js';
import { Organization } from '../../project/entities/organization.entity.js';
import { Role } from '../../user/entities/role.entity.js';
@Entity('correspondence_routing_template_steps')
export class RoutingTemplateStep {
@@ -22,17 +24,27 @@ export class RoutingTemplateStep {
@Column({ name: 'to_organization_id' })
toOrganizationId!: number;
@Column({ name: 'role_id', nullable: true })
roleId?: number;
@Column({ name: 'step_purpose', default: 'FOR_REVIEW' })
stepPurpose!: string; // FOR_APPROVAL, FOR_REVIEW
stepPurpose!: string;
@Column({ name: 'expected_days', nullable: true })
expectedDays?: number;
@ManyToOne(() => RoutingTemplate, (t) => t.steps, { onDelete: 'CASCADE' })
// Relations
@ManyToOne(() => RoutingTemplate, (template) => template.steps, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'template_id' })
template?: RoutingTemplate;
@ManyToOne(() => Organization)
@JoinColumn({ name: 'to_organization_id' })
toOrganization?: Organization;
@ManyToOne(() => Role)
@JoinColumn({ name: 'role_id' })
role?: Role;
}