@platform-modules/civil-aviation-authority 2.3.304 → 2.3.305

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.
@@ -4,5 +4,6 @@ export declare class Departments extends BaseModel {
4
4
  department_arabic_name: string | null;
5
5
  department_code: string;
6
6
  department_description: string;
7
+ DG_department_id: number | null;
7
8
  constructor(department_name: string, department_code: string, department_description: string);
8
9
  }
@@ -37,6 +37,10 @@ __decorate([
37
37
  (0, typeorm_1.Column)({ nullable: false }),
38
38
  __metadata("design:type", String)
39
39
  ], Departments.prototype, "department_description", void 0);
40
+ __decorate([
41
+ (0, typeorm_1.Column)({ type: 'integer', nullable: true, name: 'DG_department_id' }),
42
+ __metadata("design:type", Object)
43
+ ], Departments.prototype, "DG_department_id", void 0);
40
44
  exports.Departments = Departments = __decorate([
41
45
  (0, typeorm_1.Entity)({ name: 'departments' }),
42
46
  __metadata("design:paramtypes", [String, String, String])
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platform-modules/civil-aviation-authority",
3
- "version": "2.3.304",
3
+ "version": "2.3.305",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Applies SLA report views + stored procedures to PostgreSQL (idempotent CREATE OR REPLACE).
3
3
  *
4
- * Env (shared_models/.env or Reports_Service/.env):
4
+ * Env from shared_models/.env only:
5
5
  * DB_HOST / TYPEORM_HOST
6
6
  * DB_PORT / TYPEORM_PORT
7
7
  * DB_USER / TYPEORM_USERNAME
@@ -20,31 +20,25 @@ const { Client } = require('pg');
20
20
  function loadEnvFiles() {
21
21
  const dotenv = require('dotenv');
22
22
  const packageRoot = path.resolve(__dirname, '..');
23
- const cwdEnv = path.join(process.cwd(), '.env');
24
23
  const packageEnv = path.join(packageRoot, '.env');
25
- const reportsEnv = path.resolve(packageRoot, '..', 'Reports_Service', '.env');
26
24
 
27
- if (fs.existsSync(cwdEnv)) {
28
- dotenv.config({ path: cwdEnv });
29
- }
30
- if (fs.existsSync(packageEnv)) {
31
- dotenv.config({ path: packageEnv, override: true });
32
- }
33
- if (fs.existsSync(reportsEnv)) {
34
- dotenv.config({ path: reportsEnv, override: true });
25
+ if (!fs.existsSync(packageEnv)) {
26
+ throw new Error(`Missing env file: ${packageEnv}`);
35
27
  }
28
+
29
+ dotenv.config({ path: packageEnv, override: true });
36
30
  }
37
31
 
38
32
  function getDbConfig() {
39
- const host = (process.env.TYPEORM_HOST || process.env.DB_HOST || '').trim();
40
- const port = parseInt(process.env.TYPEORM_PORT || process.env.DB_PORT || '5432', 10);
41
- const user = (process.env.TYPEORM_USERNAME || process.env.DB_USER || '').trim();
42
- const password = process.env.TYPEORM_PASSWORD || process.env.DB_PASS || '';
43
- const database = (process.env.TYPEORM_DATABASE || process.env.DB_NAME || '').trim();
33
+ const host = (process.env.DB_HOST || process.env.TYPEORM_HOST || '').trim();
34
+ const port = parseInt(process.env.DB_PORT || process.env.TYPEORM_PORT || '5432', 10);
35
+ const user = (process.env.DB_USER || process.env.TYPEORM_USERNAME || '').trim();
36
+ const password = process.env.DB_PASS || process.env.TYPEORM_PASSWORD || '';
37
+ const database = (process.env.DB_NAME || process.env.TYPEORM_DATABASE || '').trim();
44
38
 
45
39
  if (!host || !user || !database) {
46
40
  throw new Error(
47
- 'Missing DB config. Set TYPEORM_* in Reports_Service/.env or DB_* in shared_models/.env'
41
+ 'Missing DB config. Set DB_HOST, DB_USER, DB_NAME (and DB_PASS) in shared_models/.env'
48
42
  );
49
43
  }
50
44
 
package/sql/README.md CHANGED
@@ -10,7 +10,7 @@ Applied in order by `npm run sync:sla-sql` (see `sla-reports-sync.manifest.json`
10
10
  | `sla_reports_approvals_workbook.sql` | Approvals Excel workbook (Requests + Approvals per sub-service) |
11
11
  | `sla_reports_admin_procedures.sql` | Admin SLA report functions (requires procedures file) |
12
12
 
13
- From **shared_models** (uses `shared_models/.env`, or `Reports_Service/.env` when present in monorepo):
13
+ From **shared_models** (reads DB config from `shared_models/.env` only `DB_HOST`, `DB_USER`, `DB_PASS`, `DB_NAME`):
14
14
 
15
15
  ```bash
16
16
  cd shared_models && npm run sync:sla-sql
@@ -1,18 +1,25 @@
1
1
  -- Migrate sla_requests.status from PostgreSQL enum to varchar(64) in-place (preserves data).
2
- -- Drops SLA views only when converting from enum (safe for sync:sla-sql manifest runs).
2
+ -- Drops SLA views when a type change is required (recreated by later sync:sla-sql files).
3
3
  -- Idempotent when status is already varchar(64).
4
4
 
5
5
  DO $$
6
6
  DECLARE
7
7
  status_udt text;
8
+ status_len integer;
8
9
  BEGIN
9
- SELECT c.udt_name
10
- INTO status_udt
10
+ SELECT c.udt_name, c.character_maximum_length
11
+ INTO status_udt, status_len
11
12
  FROM information_schema.columns c
12
13
  WHERE c.table_schema = 'public'
13
14
  AND c.table_name = 'sla_requests'
14
15
  AND c.column_name = 'status';
15
16
 
17
+ IF status_udt IS NULL THEN
18
+ RAISE NOTICE 'sla_requests.status not found — skip type migration';
19
+ RETURN;
20
+ END IF;
21
+
22
+ -- Enum -> varchar(64)
16
23
  IF status_udt = 'sla_requests_status_enum' THEN
17
24
  DROP VIEW IF EXISTS vw_sla_approvals CASCADE;
18
25
  DROP VIEW IF EXISTS vw_sla_my_requests CASCADE;
@@ -21,9 +28,16 @@ BEGIN
21
28
  ALTER COLUMN status TYPE varchar(64) USING status::text;
22
29
 
23
30
  DROP TYPE IF EXISTS sla_requests_status_enum;
24
- ELSIF status_udt = 'varchar' THEN
31
+
32
+ -- Already varchar but not length 64 (views block ALTER TYPE)
33
+ ELSIF status_udt = 'varchar' AND status_len IS DISTINCT FROM 64 THEN
34
+ DROP VIEW IF EXISTS vw_sla_approvals CASCADE;
35
+ DROP VIEW IF EXISTS vw_sla_my_requests CASCADE;
36
+
25
37
  ALTER TABLE sla_requests
26
38
  ALTER COLUMN status TYPE varchar(64);
39
+
40
+ -- Already varchar(64) — nothing to do
27
41
  END IF;
28
42
  END $$;
29
43
 
@@ -139,3 +139,7 @@ ALTER TABLE followup_report_items
139
139
  ADD COLUMN IF NOT EXISTS file_name VARCHAR(255),
140
140
  ADD COLUMN IF NOT EXISTS file_type VARCHAR(100),
141
141
  ADD COLUMN IF NOT EXISTS file_size BIGINT;
142
+
143
+ -- 10. Departments: optional parent DG department reference (self FK to departments.id)
144
+ ALTER TABLE departments
145
+ ADD COLUMN IF NOT EXISTS "DG_department_id" INTEGER NULL;
@@ -22,6 +22,8 @@ $$;
22
22
  -- ADMIN — my requests Excel (optional p_target_user_id)
23
23
  -- Per sub-service Requests + Approvals sheets (same as user my-requests download)
24
24
  -- ---------------------------------------------------------------------------
25
+ DROP FUNCTION IF EXISTS sp_sla_admin_my_requests_excel_export(INT, INT[], INT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT);
26
+
25
27
  CREATE OR REPLACE FUNCTION sp_sla_admin_my_requests_excel_export(
26
28
  p_target_user_id INT DEFAULT NULL,
27
29
  p_service_ids INT[] DEFAULT NULL,
@@ -31,7 +33,8 @@ CREATE OR REPLACE FUNCTION sp_sla_admin_my_requests_excel_export(
31
33
  p_to_date DATE DEFAULT NULL,
32
34
  p_search_text TEXT DEFAULT NULL,
33
35
  p_sort_by TEXT DEFAULT 'created_at',
34
- p_sort_order TEXT DEFAULT 'DESC'
36
+ p_sort_order TEXT DEFAULT 'DESC',
37
+ p_extra_filter_sql TEXT DEFAULT 'TRUE'
35
38
  )
36
39
  RETURNS TABLE (
37
40
  sheet_order INT,
@@ -63,7 +66,11 @@ DECLARE
63
66
  v_sheet_order INT := 0;
64
67
  v_user_filter TEXT;
65
68
  BEGIN
66
- v_user_filter := CASE WHEN p_target_user_id IS NULL THEN 'TRUE' ELSE format('v.user_id = %s', p_target_user_id) END;
69
+ v_user_filter := format(
70
+ '(%s) AND (%s)',
71
+ CASE WHEN p_target_user_id IS NULL THEN 'TRUE' ELSE format('v.user_id = %s', p_target_user_id) END,
72
+ COALESCE(NULLIF(trim(p_extra_filter_sql), ''), 'TRUE')
73
+ );
67
74
 
68
75
  v_sort_col := CASE lower(trim(p_sort_by))
69
76
  WHEN 'updated_at' THEN 'v.created_at'
@@ -199,6 +206,10 @@ DROP FUNCTION IF EXISTS sp_sla_approvals_excel_export_internal(
199
206
  TEXT, BOOLEAN, INT, INT[], INT[], TEXT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT
200
207
  );
201
208
 
209
+ DROP FUNCTION IF EXISTS sp_sla_approvals_excel_export(
210
+ INT, INT[], INT[], TEXT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT
211
+ );
212
+
202
213
  CREATE OR REPLACE FUNCTION sp_sla_approvals_excel_export(
203
214
  p_approver_user_id INT,
204
215
  p_service_ids INT[] DEFAULT NULL,
@@ -209,7 +220,8 @@ CREATE OR REPLACE FUNCTION sp_sla_approvals_excel_export(
209
220
  p_to_date DATE DEFAULT NULL,
210
221
  p_search_text TEXT DEFAULT NULL,
211
222
  p_sort_by TEXT DEFAULT 'created_at',
212
- p_sort_order TEXT DEFAULT 'DESC'
223
+ p_sort_order TEXT DEFAULT 'DESC',
224
+ p_extra_filter_sql TEXT DEFAULT 'TRUE'
213
225
  )
214
226
  RETURNS TABLE (
215
227
  sheet_order INT, sub_service_id INT, sub_service_name TEXT, sheet_name TEXT, headers JSONB, rows JSONB
@@ -219,7 +231,11 @@ STABLE
219
231
  AS $$
220
232
  DECLARE
221
233
  v_exists TEXT := sla_approval_queue_exists_sql(p_approver_user_id);
222
- v_own TEXT := format('sr.user_id != %s', p_approver_user_id);
234
+ v_own TEXT := format(
235
+ '(%s) AND (%s)',
236
+ format('sr.user_id != %s', p_approver_user_id),
237
+ COALESCE(NULLIF(trim(p_extra_filter_sql), ''), 'TRUE')
238
+ );
223
239
  BEGIN
224
240
  RETURN QUERY
225
241
  SELECT * FROM sp_sla_approvals_workbook_excel_export(
@@ -243,6 +259,10 @@ $$;
243
259
  -- Per sub-service Requests + Approvals; optional approver_user_id (NULL = all queues)
244
260
  -- Does not exclude own requests (unlike user approvals download)
245
261
  -- ---------------------------------------------------------------------------
262
+ DROP FUNCTION IF EXISTS sp_sla_admin_approvals_excel_export(
263
+ INT, INT[], INT[], TEXT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT
264
+ );
265
+
246
266
  CREATE OR REPLACE FUNCTION sp_sla_admin_approvals_excel_export(
247
267
  p_target_approver_user_id INT DEFAULT NULL,
248
268
  p_service_ids INT[] DEFAULT NULL,
@@ -253,7 +273,8 @@ CREATE OR REPLACE FUNCTION sp_sla_admin_approvals_excel_export(
253
273
  p_to_date DATE DEFAULT NULL,
254
274
  p_search_text TEXT DEFAULT NULL,
255
275
  p_sort_by TEXT DEFAULT 'created_at',
256
- p_sort_order TEXT DEFAULT 'DESC'
276
+ p_sort_order TEXT DEFAULT 'DESC',
277
+ p_extra_filter_sql TEXT DEFAULT 'TRUE'
257
278
  )
258
279
  RETURNS TABLE (
259
280
  sheet_order INT, sub_service_id INT, sub_service_name TEXT, sheet_name TEXT, headers JSONB, rows JSONB
@@ -263,7 +284,7 @@ STABLE
263
284
  AS $$
264
285
  DECLARE
265
286
  v_exists TEXT := sla_approval_queue_exists_sql_optional(p_target_approver_user_id);
266
- v_own TEXT := 'TRUE';
287
+ v_own TEXT := COALESCE(NULLIF(trim(p_extra_filter_sql), ''), 'TRUE');
267
288
  BEGIN
268
289
  RETURN QUERY
269
290
  SELECT * FROM sp_sla_approvals_workbook_excel_export(
@@ -700,6 +700,8 @@ $$;
700
700
  -- MY REQUESTS — Excel workbook payload (one result row per sub-service sheet)
701
701
  -- Uses vw_sla_my_requests; flattening and dynamic columns are built in the database.
702
702
  -- ---------------------------------------------------------------------------
703
+ DROP FUNCTION IF EXISTS sp_sla_my_requests_excel_export(INT, INT[], INT[], TEXT[], DATE, DATE, TEXT, TEXT, TEXT);
704
+
703
705
  CREATE OR REPLACE FUNCTION sp_sla_my_requests_excel_export(
704
706
  p_user_id INT,
705
707
  p_service_ids INT[] DEFAULT NULL,
@@ -709,7 +711,8 @@ CREATE OR REPLACE FUNCTION sp_sla_my_requests_excel_export(
709
711
  p_to_date DATE DEFAULT NULL,
710
712
  p_search_text TEXT DEFAULT NULL,
711
713
  p_sort_by TEXT DEFAULT 'created_at',
712
- p_sort_order TEXT DEFAULT 'DESC'
714
+ p_sort_order TEXT DEFAULT 'DESC',
715
+ p_extra_filter_sql TEXT DEFAULT 'TRUE'
713
716
  )
714
717
  RETURNS TABLE (
715
718
  sheet_order INT,
@@ -739,7 +742,10 @@ DECLARE
739
742
  v_all_rows JSONB;
740
743
  v_k TEXT;
741
744
  v_sheet_order INT := 0;
745
+ v_extra TEXT;
742
746
  BEGIN
747
+ v_extra := COALESCE(NULLIF(trim(p_extra_filter_sql), ''), 'TRUE');
748
+
743
749
  v_sort_col := CASE lower(trim(p_sort_by))
744
750
  WHEN 'updated_at' THEN 'v.created_at'
745
751
  WHEN 'id' THEN 'v.sla_request_id'
@@ -758,6 +764,7 @@ BEGIN
758
764
  INNER JOIN sla_requests sr ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
759
765
  LEFT JOIN caa_sub_services subsvc ON subsvc.id = sr.sub_service_id
760
766
  WHERE v.user_id = %1$s
767
+ AND (%2$s)
761
768
  AND v.status = ANY($1)
762
769
  AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
763
770
  AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
@@ -765,24 +772,28 @@ BEGIN
765
772
  AND ($5 IS NULL OR v.created_at::date <= $5)
766
773
  AND ($6 IS NULL OR trim($6) = '' OR CAST(v.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
767
774
  ORDER BY sub_service_name ASC
768
- $q$, p_user_id)
775
+ $q$, p_user_id, v_extra)
769
776
  USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text
770
777
  LOOP
771
778
  v_sheet_order := v_sheet_order + 1;
772
779
 
773
- SELECT COALESCE(array_agg(DISTINCT keys.k ORDER BY keys.k), ARRAY[]::TEXT[])
780
+ EXECUTE format($q$
781
+ SELECT COALESCE(array_agg(DISTINCT keys.k ORDER BY keys.k), ARRAY[]::TEXT[])
782
+ FROM vw_sla_my_requests v
783
+ INNER JOIN sla_requests sr ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
784
+ CROSS JOIN LATERAL jsonb_object_keys(COALESCE(v.request_fields, '{}'::jsonb)) AS keys(k)
785
+ WHERE v.user_id = %1$s
786
+ AND (%2$s)
787
+ AND v.status = ANY($1)
788
+ AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
789
+ AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
790
+ AND ($4 IS NULL OR v.created_at::date >= $4)
791
+ AND ($5 IS NULL OR v.created_at::date <= $5)
792
+ AND ($6 IS NULL OR trim($6) = '' OR CAST(v.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
793
+ AND COALESCE(sr.sub_service_id, 0) = %3$s
794
+ $q$, p_user_id, v_extra, v_sub.sub_service_id_num)
774
795
  INTO v_dyn_keys
775
- FROM vw_sla_my_requests v
776
- INNER JOIN sla_requests sr ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
777
- CROSS JOIN LATERAL jsonb_object_keys(COALESCE(v.request_fields, '{}'::jsonb)) AS keys(k)
778
- WHERE v.user_id = p_user_id
779
- AND v.status = ANY(p_statuses)
780
- AND (p_service_ids IS NULL OR cardinality(p_service_ids) = 0 OR sr.service_id = ANY(p_service_ids))
781
- AND (p_sub_service_ids IS NULL OR cardinality(p_sub_service_ids) = 0 OR sr.sub_service_id = ANY(p_sub_service_ids))
782
- AND (p_from_date IS NULL OR v.created_at::date >= p_from_date)
783
- AND (p_to_date IS NULL OR v.created_at::date <= p_to_date)
784
- AND (p_search_text IS NULL OR trim(p_search_text) = '' OR CAST(v.request_id AS TEXT) ILIKE '%' || trim(p_search_text) || '%')
785
- AND COALESCE(sr.sub_service_id, 0) = v_sub.sub_service_id_num;
796
+ USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text;
786
797
 
787
798
  v_dyn_labels := ARRAY[]::TEXT[];
788
799
  IF v_dyn_keys IS NOT NULL THEN
@@ -815,15 +826,16 @@ BEGIN
815
826
  INNER JOIN sla_requests sr ON sr.id = v.sla_request_id AND COALESCE(sr.is_deleted, false) = false
816
827
  LEFT JOIN users u ON u.id = v.user_id AND COALESCE(u.is_deleted, false) = false
817
828
  WHERE v.user_id = %1$s
829
+ AND (%2$s)
818
830
  AND v.status = ANY($1)
819
831
  AND ($2 IS NULL OR cardinality($2) = 0 OR sr.service_id = ANY($2))
820
832
  AND ($3 IS NULL OR cardinality($3) = 0 OR sr.sub_service_id = ANY($3))
821
833
  AND ($4 IS NULL OR v.created_at::date >= $4)
822
834
  AND ($5 IS NULL OR v.created_at::date <= $5)
823
835
  AND ($6 IS NULL OR trim($6) = '' OR CAST(v.request_id AS TEXT) ILIKE '%%' || trim($6) || '%%')
824
- AND COALESCE(sr.sub_service_id, 0) = %2$s
825
- ORDER BY %3$s %4$s, v.sla_request_id ASC
826
- $q$, p_user_id, v_sub.sub_service_id_num, v_sort_col, v_sort_dir)
836
+ AND COALESCE(sr.sub_service_id, 0) = %3$s
837
+ ORDER BY %4$s %5$s, v.sla_request_id ASC
838
+ $q$, p_user_id, v_extra, v_sub.sub_service_id_num, v_sort_col, v_sort_dir)
827
839
  USING p_statuses, p_service_ids, p_sub_service_ids, p_from_date, p_to_date, p_search_text
828
840
  LOOP
829
841
  v_cells := ARRAY[
@@ -859,7 +871,7 @@ BEGIN
859
871
  RETURN QUERY
860
872
  SELECT *
861
873
  FROM sla_my_requests_approvals_excel_sheet(
862
- format('v.user_id = %s', p_user_id),
874
+ format('v.user_id = %s AND (%s)', p_user_id, v_extra),
863
875
  p_statuses,
864
876
  p_service_ids,
865
877
  p_sub_service_ids,
@@ -16,6 +16,9 @@ export class Departments extends BaseModel {
16
16
  @Column({ nullable: false })
17
17
  department_description: string;
18
18
 
19
+ @Column({ type: 'integer', nullable: true, name: 'DG_department_id' })
20
+ DG_department_id: number | null;
21
+
19
22
  constructor(
20
23
  department_name: string,
21
24
  department_code: string,