@platform-modules/civil-aviation-authority 2.3.225 → 2.3.227

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/data-source.js +12 -0
  2. package/dist/index.d.ts +7 -0
  3. package/dist/index.js +7 -0
  4. package/dist/models/NotificationModel.d.ts +4 -0
  5. package/dist/models/NotificationModel.js +8 -0
  6. package/dist/models/SecurityAwarenessRequestModel.d.ts +4 -0
  7. package/dist/models/SecurityAwarenessRequestModel.js +8 -0
  8. package/dist/models/VipHallApprovalModel.d.ts +22 -0
  9. package/dist/models/VipHallApprovalModel.js +84 -0
  10. package/dist/models/VipHallAttachmentModel.d.ts +11 -0
  11. package/dist/models/VipHallAttachmentModel.js +52 -0
  12. package/dist/models/VipHallChatModel.d.ts +18 -0
  13. package/dist/models/VipHallChatModel.js +65 -0
  14. package/dist/models/VipHallHistoryModel.d.ts +12 -0
  15. package/dist/models/VipHallHistoryModel.js +52 -0
  16. package/dist/models/VipHallRequestModel.d.ts +43 -0
  17. package/dist/models/VipHallRequestModel.js +151 -0
  18. package/dist/models/VipHallWorkflowModel.d.ts +17 -0
  19. package/dist/models/VipHallWorkflowModel.js +67 -0
  20. package/dist/sla/sla-table-sync.service.d.ts +23 -0
  21. package/dist/sla/sla-table-sync.service.js +59 -0
  22. package/package.json +1 -1
  23. package/src/data-source.ts +12 -0
  24. package/src/index.ts +8 -1
  25. package/src/models/NotificationModel.ts +8 -0
  26. package/src/models/SecurityAwarenessRequestModel.ts +8 -0
  27. package/src/models/VipHallApprovalModel.ts +56 -0
  28. package/src/models/VipHallAttachmentModel.ts +29 -0
  29. package/src/models/VipHallChatModel.ts +42 -0
  30. package/src/models/VipHallHistoryModel.ts +30 -0
  31. package/src/models/VipHallRequestModel.ts +114 -0
  32. package/src/models/VipHallWorkflowModel.ts +43 -0
  33. package/src/sla/sla-table-sync.service.ts +87 -0
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.VipHallWorkFlow = exports.VipHallWorkFlowStatus = void 0;
13
+ const typeorm_1 = require("typeorm");
14
+ const BaseModel_1 = require("./BaseModel");
15
+ var VipHallWorkFlowStatus;
16
+ (function (VipHallWorkFlowStatus) {
17
+ VipHallWorkFlowStatus["COMPLETED"] = "Completed";
18
+ VipHallWorkFlowStatus["NOT_YET_STARTED"] = "Not Yet Started";
19
+ VipHallWorkFlowStatus["PENDING"] = "Pending";
20
+ })(VipHallWorkFlowStatus || (exports.VipHallWorkFlowStatus = VipHallWorkFlowStatus = {}));
21
+ let VipHallWorkFlow = class VipHallWorkFlow extends BaseModel_1.BaseModel {
22
+ };
23
+ exports.VipHallWorkFlow = VipHallWorkFlow;
24
+ __decorate([
25
+ (0, typeorm_1.Column)({ type: "integer", nullable: false }),
26
+ __metadata("design:type", Number)
27
+ ], VipHallWorkFlow.prototype, "request_id", void 0);
28
+ __decorate([
29
+ (0, typeorm_1.Column)({ type: "integer", nullable: true }),
30
+ __metadata("design:type", Object)
31
+ ], VipHallWorkFlow.prototype, "service_id", void 0);
32
+ __decorate([
33
+ (0, typeorm_1.Column)({ type: "integer", nullable: true }),
34
+ __metadata("design:type", Object)
35
+ ], VipHallWorkFlow.prototype, "sub_service_id", void 0);
36
+ __decorate([
37
+ (0, typeorm_1.Column)({ type: "varchar", length: 500, nullable: false }),
38
+ __metadata("design:type", String)
39
+ ], VipHallWorkFlow.prototype, "content", void 0);
40
+ __decorate([
41
+ (0, typeorm_1.Column)({
42
+ type: "enum",
43
+ enum: VipHallWorkFlowStatus,
44
+ default: VipHallWorkFlowStatus.NOT_YET_STARTED,
45
+ nullable: false,
46
+ }),
47
+ __metadata("design:type", String)
48
+ ], VipHallWorkFlow.prototype, "status", void 0);
49
+ __decorate([
50
+ (0, typeorm_1.Column)({ type: "integer", nullable: true }),
51
+ __metadata("design:type", Object)
52
+ ], VipHallWorkFlow.prototype, "user_id", void 0);
53
+ __decorate([
54
+ (0, typeorm_1.Column)({ type: "integer", nullable: true }),
55
+ __metadata("design:type", Object)
56
+ ], VipHallWorkFlow.prototype, "role_id", void 0);
57
+ __decorate([
58
+ (0, typeorm_1.Column)({ type: "integer", nullable: true }),
59
+ __metadata("design:type", Object)
60
+ ], VipHallWorkFlow.prototype, "department_id", void 0);
61
+ __decorate([
62
+ (0, typeorm_1.Column)({ type: "integer", nullable: true }),
63
+ __metadata("design:type", Object)
64
+ ], VipHallWorkFlow.prototype, "section_id", void 0);
65
+ exports.VipHallWorkFlow = VipHallWorkFlow = __decorate([
66
+ (0, typeorm_1.Entity)({ name: "vip_hall_workflows" })
67
+ ], VipHallWorkFlow);
@@ -0,0 +1,23 @@
1
+ import { EntityManager } from "typeorm";
2
+ import { SlaRequestStatus } from "../models/SlaRequestModel";
3
+ export type PatchSlaApprovalTableInput = Partial<{
4
+ approval_status: string;
5
+ approver_user_id: number | null;
6
+ approver_role_id: number | null;
7
+ department_id: number | null;
8
+ section_id: number | null;
9
+ level: number;
10
+ }>;
11
+ export type PatchSlaRequestTableInput = Partial<{
12
+ status: SlaRequestStatus | string;
13
+ workflow_execution_id: string | null;
14
+ }>;
15
+ /**
16
+ * TypeORM patches for `sla_approval` and `sla_requests` by the keys used at insert time
17
+ * (`source_approval_id` and native `request_id`). Safe to call from any service that shares the DB;
18
+ * failures are swallowed so missing SLA rows never block business transactions.
19
+ */
20
+ export declare class SlaTableSyncService {
21
+ static patchSlaApprovalBySourceApprovalId(manager: EntityManager, sourceApprovalId: number, patch: PatchSlaApprovalTableInput, updatedBy?: number | null): Promise<void>;
22
+ static patchSlaRequestByNativeRequestId(manager: EntityManager, nativeRequestId: number, patch: PatchSlaRequestTableInput, updatedBy?: number | null): Promise<void>;
23
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SlaTableSyncService = void 0;
4
+ const ServiceSlaApprovalModel_1 = require("../models/ServiceSlaApprovalModel");
5
+ const SlaRequestModel_1 = require("../models/SlaRequestModel");
6
+ function stripUndefined(obj) {
7
+ const out = {};
8
+ for (const key of Object.keys(obj)) {
9
+ const v = obj[key];
10
+ if (v !== undefined) {
11
+ out[key] = v;
12
+ }
13
+ }
14
+ return out;
15
+ }
16
+ /**
17
+ * TypeORM patches for `sla_approval` and `sla_requests` by the keys used at insert time
18
+ * (`source_approval_id` and native `request_id`). Safe to call from any service that shares the DB;
19
+ * failures are swallowed so missing SLA rows never block business transactions.
20
+ */
21
+ class SlaTableSyncService {
22
+ static async patchSlaApprovalBySourceApprovalId(manager, sourceApprovalId, patch, updatedBy) {
23
+ if (!Number.isFinite(sourceApprovalId)) {
24
+ return;
25
+ }
26
+ try {
27
+ const setPayload = {
28
+ ...stripUndefined(patch),
29
+ updated_at: new Date()
30
+ };
31
+ if (updatedBy != null) {
32
+ setPayload.updated_by = updatedBy;
33
+ }
34
+ await manager.getRepository(ServiceSlaApprovalModel_1.ServiceSlaApproval).update({ source_approval_id: sourceApprovalId, is_deleted: false }, setPayload);
35
+ }
36
+ catch {
37
+ // non-fatal
38
+ }
39
+ }
40
+ static async patchSlaRequestByNativeRequestId(manager, nativeRequestId, patch, updatedBy) {
41
+ if (!Number.isFinite(nativeRequestId) || nativeRequestId < 1) {
42
+ return;
43
+ }
44
+ try {
45
+ const setPayload = {
46
+ ...stripUndefined(patch),
47
+ updated_at: new Date()
48
+ };
49
+ if (updatedBy != null) {
50
+ setPayload.updated_by = updatedBy;
51
+ }
52
+ await manager.getRepository(SlaRequestModel_1.SlaRequest).update({ request_id: nativeRequestId, is_deleted: false }, setPayload);
53
+ }
54
+ catch {
55
+ // non-fatal
56
+ }
57
+ }
58
+ }
59
+ exports.SlaTableSyncService = SlaTableSyncService;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platform-modules/civil-aviation-authority",
3
- "version": "2.3.225",
3
+ "version": "2.3.227",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
@@ -144,6 +144,12 @@ import { MultiPurposeHallWorkFlow } from './models/MultiPurposeHallWorkflowModel
144
144
  import { MultiPurposeHallRequestChat } from './models/MultiPurposeHallChatModel';
145
145
  import { MultiPurposeHallRequestAttachment } from './models/MultiPurposeHallAttachmentModel';
146
146
  import { MultiPurposeHallHistory } from './models/MultiPurposeHallHistoryModel';
147
+ import { VipHallRequests } from './models/VipHallRequestModel';
148
+ import { VipHallApprovalDetails } from './models/VipHallApprovalModel';
149
+ import { VipHallWorkFlow } from './models/VipHallWorkflowModel';
150
+ import { VipHallRequestChat } from './models/VipHallChatModel';
151
+ import { VipHallRequestAttachment } from './models/VipHallAttachmentModel';
152
+ import { VipHallHistory } from './models/VipHallHistoryModel';
147
153
  import { FoodRequests } from './models/FoodRequestModel';
148
154
  import { FoodApprovalDetails } from './models/FoodApprovalModel';
149
155
  import { FoodWorkFlow } from './models/FoodWorkflowModel';
@@ -366,6 +372,12 @@ export const AppDataSource = new DataSource({
366
372
  MultiPurposeHallRequestChat,
367
373
  MultiPurposeHallRequestAttachment,
368
374
  MultiPurposeHallHistory,
375
+ VipHallRequests,
376
+ VipHallApprovalDetails,
377
+ VipHallWorkFlow,
378
+ VipHallRequestChat,
379
+ VipHallRequestAttachment,
380
+ VipHallHistory,
369
381
  FoodRequests,
370
382
  FoodApprovalDetails,
371
383
  FoodWorkFlow,
package/src/index.ts CHANGED
@@ -124,6 +124,12 @@ export * from './models/MultiPurposeHallWorkflowModel';
124
124
  export * from './models/MultiPurposeHallChatModel';
125
125
  export * from './models/MultiPurposeHallAttachmentModel';
126
126
  export * from './models/MultiPurposeHallHistoryModel';
127
+ export * from './models/VipHallRequestModel';
128
+ export * from './models/VipHallApprovalModel';
129
+ export * from './models/VipHallWorkflowModel';
130
+ export * from './models/VipHallChatModel';
131
+ export * from './models/VipHallAttachmentModel';
132
+ export * from './models/VipHallHistoryModel';
127
133
  export * from './models/FoodRequestModel';
128
134
  export * from './models/FoodApprovalModel';
129
135
  export * from './models/FoodWorkflowModel';
@@ -474,4 +480,5 @@ export * from './models/ContractServiceRequestModel';
474
480
 
475
481
  export * from './models/SlaConfigModel';
476
482
  export * from './models/SlaRequestModel';
477
- export * from './models/ServiceSlaApprovalModel';
483
+ export * from './models/ServiceSlaApprovalModel';
484
+ export * from './sla/sla-table-sync.service';
@@ -51,6 +51,14 @@ export class Notification extends BaseModel {
51
51
  @Column({ type: 'varchar', length: 500, nullable: true })
52
52
  route_path: string;
53
53
 
54
+ /** Mirrors SLA reminder metadata also stored in `content` for cron-created rows (optional DB migration). */
55
+ @Column({ type: 'boolean', default: false })
56
+ is_sla: boolean;
57
+
58
+ /** Remaining SLA reminder taps allowed (starts at 3 for SLA cron notifications). Optional column — see `content.sla_count`. */
59
+ @Column({ type: 'integer', nullable: true })
60
+ sla_count: number | null;
61
+
54
62
  constructor(
55
63
  type: NotificationType,
56
64
  user_id: number,
@@ -23,6 +23,14 @@ export class SecurityAwarenessRequest extends BaseModel {
23
23
  @Column({ type: 'int', nullable: true })
24
24
  req_user_section_id: number | null;
25
25
 
26
+ /** Target department from create payload (approval routing / reporting). */
27
+ @Column({ type: 'int', nullable: true })
28
+ department_id: number | null;
29
+
30
+ /** Target section from create payload; may reference a section or be omitted when "All Sections". */
31
+ @Column({ type: 'int', nullable: true })
32
+ section_id: number | null;
33
+
26
34
  @Column({ nullable: true })
27
35
  service_id: number;
28
36
 
@@ -0,0 +1,56 @@
1
+ import { Column, Entity } from "typeorm";
2
+ import { BaseModel } from "./BaseModel";
3
+
4
+ export enum VipHallApprovalStatus {
5
+ PENDING = "Pending",
6
+ IN_PROGRESS = "In Progress",
7
+ APPROVED = "Approved",
8
+ REJECTED = "Rejected",
9
+ }
10
+
11
+ @Entity({ name: "vip_hall_approvals" })
12
+ export class VipHallApprovalDetails extends BaseModel {
13
+ @Column({ type: "integer", nullable: false })
14
+ request_id: number;
15
+
16
+ @Column({ type: "integer", nullable: true })
17
+ service_id: number | null;
18
+
19
+ @Column({ type: "integer", nullable: true })
20
+ sub_service_id: number | null;
21
+
22
+ @Column({ type: "integer", nullable: false })
23
+ level: number;
24
+
25
+ @Column({ type: "integer", nullable: true })
26
+ approver_role_id: number | null;
27
+
28
+ @Column({ type: "integer", nullable: true })
29
+ department_id: number | null;
30
+
31
+ @Column({ type: "integer", nullable: true })
32
+ section_id: number | null;
33
+
34
+ @Column({ type: "integer", nullable: true })
35
+ approver_user_id: number | null;
36
+
37
+ @Column({ type: "integer", nullable: true })
38
+ delegate_user_id: number | null;
39
+
40
+ @Column({ type: "integer", nullable: true })
41
+ approved_by: number | null;
42
+
43
+ @Column({ type: "varchar", length: 500, nullable: true, default: "" })
44
+ comment: string;
45
+
46
+ @Column({
47
+ type: "enum",
48
+ enum: VipHallApprovalStatus,
49
+ default: VipHallApprovalStatus.PENDING,
50
+ nullable: false,
51
+ })
52
+ approval_status: VipHallApprovalStatus;
53
+
54
+ @Column({ type: "boolean", default: true, nullable: false })
55
+ is_allowed: boolean;
56
+ }
@@ -0,0 +1,29 @@
1
+ import { Column, Entity } from "typeorm";
2
+ import { BaseModel } from "./BaseModel";
3
+
4
+ @Entity({ name: "vip_hall_attachments" })
5
+ export class VipHallRequestAttachment extends BaseModel {
6
+ @Column({ type: "integer", nullable: false })
7
+ request_id: number;
8
+
9
+ @Column({ type: "integer", nullable: true })
10
+ service_id: number | null;
11
+
12
+ @Column({ type: "integer", nullable: true })
13
+ sub_service_id: number | null;
14
+
15
+ @Column({ type: "varchar", length: 500, nullable: false })
16
+ file_url: string;
17
+
18
+ @Column({ type: "varchar", length: 255, nullable: true })
19
+ file_name: string;
20
+
21
+ @Column({ type: "varchar", length: 100, nullable: true })
22
+ file_type: string;
23
+
24
+ @Column({ type: "bigint", nullable: true })
25
+ file_size: number | null;
26
+
27
+ @Column({ type: "integer", nullable: true })
28
+ chat_id: number | null;
29
+ }
@@ -0,0 +1,42 @@
1
+ import { Column, Entity } from "typeorm";
2
+ import { BaseModel } from "./BaseModel";
3
+
4
+ export enum VipHallMessageType {
5
+ TEXT = "text",
6
+ IMAGE = "image",
7
+ VIDEO = "video",
8
+ FILE = "file",
9
+ LINK = "link",
10
+ }
11
+
12
+ @Entity({ name: "vip_hall_chats" })
13
+ export class VipHallRequestChat extends BaseModel {
14
+ @Column({ type: "integer", nullable: false })
15
+ request_id: number;
16
+
17
+ @Column({ type: "integer", nullable: true })
18
+ service_id: number | null;
19
+
20
+ @Column({ type: "integer", nullable: true })
21
+ sub_service_id: number | null;
22
+
23
+ @Column({ type: "integer", nullable: false })
24
+ user_id: number;
25
+
26
+ @Column({ type: "integer", nullable: true })
27
+ role_id: number | null;
28
+
29
+ @Column({ type: "text", nullable: false })
30
+ message: string;
31
+
32
+ @Column({
33
+ type: "enum",
34
+ enum: VipHallMessageType,
35
+ default: VipHallMessageType.TEXT,
36
+ nullable: false,
37
+ })
38
+ messageType: VipHallMessageType;
39
+
40
+ @Column({ type: "text", nullable: true })
41
+ status: string | null;
42
+ }
@@ -0,0 +1,30 @@
1
+ import { Column, Entity } from "typeorm";
2
+ import { BaseModel } from "./BaseModel";
3
+
4
+ @Entity({ name: "vip_hall_histories" })
5
+ export class VipHallHistory extends BaseModel {
6
+ /** Source `vip_hall_requests.id` when history was created on final approval. */
7
+ @Column({ type: "int", nullable: true })
8
+ request_id: number | null;
9
+
10
+ @Column({ type: "int", nullable: true })
11
+ hall_id: number | null;
12
+
13
+ @Column({ type: "int", nullable: true })
14
+ location_id: number | null;
15
+
16
+ @Column({ type: "int", nullable: true })
17
+ department_id: number | null;
18
+
19
+ @Column({ type: "date", nullable: true })
20
+ booked_start_date: string | null;
21
+
22
+ @Column({ type: "date", nullable: true })
23
+ booked_end_date: string | null;
24
+
25
+ @Column({ type: "varchar", length: 50, nullable: true })
26
+ from_time: string | null;
27
+
28
+ @Column({ type: "varchar", length: 50, nullable: true })
29
+ to_time: string | null;
30
+ }
@@ -0,0 +1,114 @@
1
+ import { Column, Entity } from "typeorm";
2
+ import { BaseModel } from "./BaseModel";
3
+
4
+ export enum VipHallRequestStatus {
5
+ PENDING = "Pending",
6
+ IN_PROGRESS = "In Progress",
7
+ APPROVED = "Approved",
8
+ REJECTED = "Rejected",
9
+ CANCELLED = "Cancelled",
10
+ }
11
+
12
+ export enum VipHallInternalExternal {
13
+ INTERNAL = "Internal",
14
+ EXTERNAL = "External",
15
+ }
16
+
17
+ export enum VipHallMealType {
18
+ BREAKFAST = "Breakfast",
19
+ LUNCH = "Lunch",
20
+ DINNER = "Dinner",
21
+ }
22
+
23
+ @Entity({ name: "vip_hall_requests" })
24
+ export class VipHallRequests extends BaseModel {
25
+ @Column({ type: "integer", nullable: true })
26
+ req_user_department_id: number | null;
27
+
28
+ @Column({ type: "integer", nullable: true })
29
+ req_user_section_id: number | null;
30
+
31
+ @Column({ type: "integer", nullable: true })
32
+ service_id: number | null;
33
+
34
+ @Column({ type: "integer", nullable: true })
35
+ sub_service_id: number | null;
36
+
37
+ @Column({ type: "integer", nullable: true })
38
+ hall_id: number | null;
39
+
40
+ @Column({ type: "integer", nullable: true })
41
+ location_id: number | null;
42
+
43
+ @Column({ type: "integer", nullable: true })
44
+ department_id: number | null;
45
+
46
+ @Column({ type: "integer", nullable: false })
47
+ user_id: number;
48
+
49
+ @Column({
50
+ type: "enum",
51
+ enum: VipHallInternalExternal,
52
+ enumName: "vip_hall_event_type_en",
53
+ nullable: false,
54
+ })
55
+ event_type: VipHallInternalExternal;
56
+
57
+ @Column({
58
+ type: "enum",
59
+ enum: VipHallInternalExternal,
60
+ enumName: "vip_hall_request_type_en",
61
+ nullable: false,
62
+ })
63
+ request_type: VipHallInternalExternal;
64
+
65
+ @Column({ type: "date", nullable: false })
66
+ event_date: string;
67
+
68
+ @Column({ type: "time", nullable: false })
69
+ event_start_time: string;
70
+
71
+ @Column({ type: "time", nullable: false })
72
+ event_end_time: string;
73
+
74
+ /** Purpose of the meeting (mandatory in API validation). */
75
+ @Column({ type: "text", nullable: false })
76
+ meeting_purpose: string;
77
+
78
+ @Column({ type: "boolean", default: false, nullable: false })
79
+ meal_required: boolean;
80
+
81
+ @Column({
82
+ type: "enum",
83
+ enum: VipHallMealType,
84
+ enumName: "vip_hall_meal_type_en",
85
+ nullable: true,
86
+ })
87
+ meal_type: VipHallMealType | null;
88
+
89
+ @Column({ type: "boolean", default: false, nullable: false })
90
+ network_support_required: boolean;
91
+
92
+ @Column({ type: "boolean", default: false, nullable: false })
93
+ media_coverage_required: boolean;
94
+
95
+ @Column({ type: "boolean", default: false, nullable: false })
96
+ project_maintenance_support_required: boolean;
97
+
98
+ @Column({ type: "integer", nullable: true })
99
+ number_of_guests: number | null;
100
+
101
+ @Column({ type: "text", nullable: true })
102
+ special_requirements: string | null;
103
+
104
+ @Column({
105
+ type: "enum",
106
+ enum: VipHallRequestStatus,
107
+ default: VipHallRequestStatus.PENDING,
108
+ nullable: false,
109
+ })
110
+ status: VipHallRequestStatus;
111
+
112
+ @Column({ type: "varchar", nullable: true })
113
+ workflow_execution_id: string | null;
114
+ }
@@ -0,0 +1,43 @@
1
+ import { Column, Entity } from "typeorm";
2
+ import { BaseModel } from "./BaseModel";
3
+
4
+ export enum VipHallWorkFlowStatus {
5
+ COMPLETED = "Completed",
6
+ NOT_YET_STARTED = "Not Yet Started",
7
+ PENDING = "Pending",
8
+ }
9
+
10
+ @Entity({ name: "vip_hall_workflows" })
11
+ export class VipHallWorkFlow extends BaseModel {
12
+ @Column({ type: "integer", nullable: false })
13
+ request_id: number;
14
+
15
+ @Column({ type: "integer", nullable: true })
16
+ service_id: number | null;
17
+
18
+ @Column({ type: "integer", nullable: true })
19
+ sub_service_id: number | null;
20
+
21
+ @Column({ type: "varchar", length: 500, nullable: false })
22
+ content: string;
23
+
24
+ @Column({
25
+ type: "enum",
26
+ enum: VipHallWorkFlowStatus,
27
+ default: VipHallWorkFlowStatus.NOT_YET_STARTED,
28
+ nullable: false,
29
+ })
30
+ status: VipHallWorkFlowStatus;
31
+
32
+ @Column({ type: "integer", nullable: true })
33
+ user_id: number | null;
34
+
35
+ @Column({ type: "integer", nullable: true })
36
+ role_id: number | null;
37
+
38
+ @Column({ type: "integer", nullable: true })
39
+ department_id: number | null;
40
+
41
+ @Column({ type: "integer", nullable: true })
42
+ section_id: number | null;
43
+ }
@@ -0,0 +1,87 @@
1
+ import { EntityManager } from "typeorm";
2
+ import { ServiceSlaApproval } from "../models/ServiceSlaApprovalModel";
3
+ import { SlaRequest, SlaRequestStatus } from "../models/SlaRequestModel";
4
+
5
+ export type PatchSlaApprovalTableInput = Partial<{
6
+ approval_status: string;
7
+ approver_user_id: number | null;
8
+ approver_role_id: number | null;
9
+ department_id: number | null;
10
+ section_id: number | null;
11
+ level: number;
12
+ }>;
13
+
14
+ export type PatchSlaRequestTableInput = Partial<{
15
+ status: SlaRequestStatus | string;
16
+ workflow_execution_id: string | null;
17
+ }>;
18
+
19
+ function stripUndefined<T extends Record<string, unknown>>(obj: T): Partial<T> {
20
+ const out: Partial<T> = {};
21
+ for (const key of Object.keys(obj)) {
22
+ const v = obj[key];
23
+ if (v !== undefined) {
24
+ (out as Record<string, unknown>)[key] = v;
25
+ }
26
+ }
27
+ return out;
28
+ }
29
+
30
+ /**
31
+ * TypeORM patches for `sla_approval` and `sla_requests` by the keys used at insert time
32
+ * (`source_approval_id` and native `request_id`). Safe to call from any service that shares the DB;
33
+ * failures are swallowed so missing SLA rows never block business transactions.
34
+ */
35
+ export class SlaTableSyncService {
36
+ static async patchSlaApprovalBySourceApprovalId(
37
+ manager: EntityManager,
38
+ sourceApprovalId: number,
39
+ patch: PatchSlaApprovalTableInput,
40
+ updatedBy?: number | null
41
+ ): Promise<void> {
42
+ if (!Number.isFinite(sourceApprovalId)) {
43
+ return;
44
+ }
45
+ try {
46
+ const setPayload: Record<string, unknown> = {
47
+ ...stripUndefined(patch as Record<string, unknown>),
48
+ updated_at: new Date()
49
+ };
50
+ if (updatedBy != null) {
51
+ setPayload.updated_by = updatedBy;
52
+ }
53
+ await manager.getRepository(ServiceSlaApproval).update(
54
+ { source_approval_id: sourceApprovalId, is_deleted: false },
55
+ setPayload as any
56
+ );
57
+ } catch {
58
+ // non-fatal
59
+ }
60
+ }
61
+
62
+ static async patchSlaRequestByNativeRequestId(
63
+ manager: EntityManager,
64
+ nativeRequestId: number,
65
+ patch: PatchSlaRequestTableInput,
66
+ updatedBy?: number | null
67
+ ): Promise<void> {
68
+ if (!Number.isFinite(nativeRequestId) || nativeRequestId < 1) {
69
+ return;
70
+ }
71
+ try {
72
+ const setPayload: Record<string, unknown> = {
73
+ ...stripUndefined(patch as Record<string, unknown>),
74
+ updated_at: new Date()
75
+ };
76
+ if (updatedBy != null) {
77
+ setPayload.updated_by = updatedBy;
78
+ }
79
+ await manager.getRepository(SlaRequest).update(
80
+ { request_id: nativeRequestId, is_deleted: false },
81
+ setPayload as any
82
+ );
83
+ } catch {
84
+ // non-fatal
85
+ }
86
+ }
87
+ }