@heyhru/business-dms-approval 0.7.1 → 0.8.0

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.
@@ -1,9 +1,20 @@
1
- export declare function listApprovals(filters?: {
1
+ interface ApprovalFilters {
2
2
  status?: string;
3
3
  submittedBy?: string;
4
- }): Promise<Record<string, unknown>[]>;
4
+ limit?: number;
5
+ offset?: number;
6
+ }
7
+ export declare function countApprovals(filters?: ApprovalFilters): Promise<number>;
8
+ export declare function listApprovals(filters?: ApprovalFilters): Promise<Record<string, unknown>[]>;
5
9
  export declare function getApprovalById(id: string): Promise<Record<string, unknown> | undefined>;
6
- export declare function insertApproval(dataSourceId: string, dbName: string | null, sqlText: string, submittedBy: string): Promise<Record<string, unknown> | undefined>;
10
+ interface InsertApprovalParams {
11
+ dataSourceId: string;
12
+ dbName: string | null;
13
+ sqlText: string;
14
+ submittedBy: string;
15
+ sqlType?: string;
16
+ }
17
+ export declare function insertApproval({ dataSourceId, dbName, sqlText, submittedBy, sqlType }: InsertApprovalParams): Promise<Record<string, unknown> | undefined>;
7
18
  export declare function updateReview(id: string, status: string, reviewedBy: string, rejectReason: string | null): Promise<Record<string, unknown> | undefined>;
8
19
  export declare function setExecuting(id: string): Promise<{
9
20
  changes: number;
@@ -11,4 +22,5 @@ export declare function setExecuting(id: string): Promise<{
11
22
  export declare function setExecuteResult(id: string, status: string, result: string): Promise<{
12
23
  changes: number;
13
24
  }>;
25
+ export {};
14
26
  //# sourceMappingURL=approvals.model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"approvals.model.d.ts","sourceRoot":"","sources":["../src/approvals.model.ts"],"names":[],"mappings":"AAGA,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,sCAgBtF;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,gDAEzC;AAED,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,gDAE/G;AAED,wBAAgB,YAAY,CAC1B,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GAAG,IAAI,gDAG5B;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM;;GAEtC;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;GAE1E"}
1
+ {"version":3,"file":"approvals.model.d.ts","sourceRoot":"","sources":["../src/approvals.model.ts"],"names":[],"mappings":"AAGA,UAAU,eAAe;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAgBD,wBAAsB,cAAc,CAAC,OAAO,CAAC,EAAE,eAAe,mBAO7D;AAED,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE,eAAe,sCAS5D;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,gDAEzC;AAED,UAAU,oBAAoB;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,cAAc,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAe,EAAE,EAAE,oBAAoB,gDAEnH;AAED,wBAAgB,YAAY,CAC1B,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GAAG,IAAI,gDAG5B;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM;;GAEtC;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;GAE1E"}
@@ -1 +1 @@
1
- {"version":3,"file":"approvals.service.d.ts","sourceRoot":"","sources":["../src/approvals.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAA0B,MAAM,SAAS,CAAC;AAYzF,UAAU,oBAAqB,SAAQ,cAAc;IACnD,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;CACtB;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,YAAY,kBAQhF;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAKzE;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,YAAY,kBAQlF;AAkBD,wBAAsB,eAAe,CAAC,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,YAAY,kBAUnF;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,YAAY,kBAUlF;AAED,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,IACrC,KAAK,oBAAoB,EAAE,OAAO,YAAY,oBAY7D"}
1
+ {"version":3,"file":"approvals.service.d.ts","sourceRoot":"","sources":["../src/approvals.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAA0B,MAAM,SAAS,CAAC;AAazF,UAAU,oBAAqB,SAAQ,cAAc;IACnD,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;CACtB;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,YAAY,kBAUhF;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAKzE;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,YAAY,kBAWlF;AAkBD,wBAAsB,eAAe,CAAC,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,YAAY,kBAUnF;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,YAAY,kBAUlF;AAED,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,IACrC,KAAK,oBAAoB,EAAE,OAAO,YAAY,oBAY7D"}
@@ -1,5 +1,5 @@
1
1
  export declare const FIND_BY_ID = "\nSELECT *\nFROM approvals\nWHERE id = ?";
2
- export declare const CREATE = "\nINSERT INTO approvals (data_source_id, db_name, sql_text, submitted_by)\nVALUES (?, ?, ?, ?)\nRETURNING *";
2
+ export declare const CREATE = "\nINSERT INTO approvals (data_source_id, db_name, sql_text, submitted_by, sql_type)\nVALUES (?, ?, ?, ?, ?)\nRETURNING *";
3
3
  export declare const UPDATE_REVIEW: () => string;
4
4
  export declare const UPDATE_EXECUTING: () => string;
5
5
  export declare const UPDATE_RESULT: () => string;
@@ -1 +1 @@
1
- {"version":3,"file":"approvals.sql.d.ts","sourceRoot":"","sources":["../src/approvals.sql.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,6CAGV,CAAC;AAEd,eAAO,MAAM,MAAM,gHAGP,CAAC;AAEb,eAAO,MAAM,aAAa,cAId,CAAC;AAEb,eAAO,MAAM,gBAAgB,cAGhB,CAAC;AAEd,eAAO,MAAM,aAAa,cAGb,CAAC"}
1
+ {"version":3,"file":"approvals.sql.d.ts","sourceRoot":"","sources":["../src/approvals.sql.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,6CAGV,CAAC;AAEd,eAAO,MAAM,MAAM,6HAGP,CAAC;AAEb,eAAO,MAAM,aAAa,cAId,CAAC;AAEb,eAAO,MAAM,gBAAgB,cAGhB,CAAC;AAEd,eAAO,MAAM,aAAa,cAGb,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { approvalList, approvalGet, approvalCreate, approvalApprove, approvalReject, approvalExecute, } from "./approvals.service.js";
2
+ export { getApprovalById, setExecuting, setExecuteResult } from "./approvals.model.js";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -25,7 +25,10 @@ __export(index_exports, {
25
25
  approvalExecute: () => approvalExecute,
26
26
  approvalGet: () => approvalGet,
27
27
  approvalList: () => approvalList,
28
- approvalReject: () => approvalReject
28
+ approvalReject: () => approvalReject,
29
+ getApprovalById: () => getApprovalById,
30
+ setExecuteResult: () => setExecuteResult,
31
+ setExecuting: () => setExecuting
29
32
  });
30
33
  module.exports = __toCommonJS(index_exports);
31
34
 
@@ -42,8 +45,8 @@ SELECT *
42
45
  FROM approvals
43
46
  WHERE id = ?`;
44
47
  var CREATE = `
45
- INSERT INTO approvals (data_source_id, db_name, sql_text, submitted_by)
46
- VALUES (?, ?, ?, ?)
48
+ INSERT INTO approvals (data_source_id, db_name, sql_text, submitted_by, sql_type)
49
+ VALUES (?, ?, ?, ?, ?)
47
50
  RETURNING *`;
48
51
  var UPDATE_REVIEW = () => `
49
52
  UPDATE approvals
@@ -60,28 +63,42 @@ SET status = ?, execute_result = ?, updated_at = NOW()
60
63
  WHERE id = ?`;
61
64
 
62
65
  // src/approvals.model.ts
63
- async function listApprovals(filters) {
64
- let query = `SELECT a.*, u.username AS submitter_name
65
- FROM approvals a
66
- LEFT JOIN users u ON u.id = a.submitted_by
67
- WHERE 1=1`;
66
+ function buildWhereParams(filters) {
67
+ const clauses = [];
68
68
  const params = [];
69
69
  if (filters?.status) {
70
- query += " AND a.status = ?";
70
+ clauses.push("a.status = ?");
71
71
  params.push(filters.status);
72
72
  }
73
73
  if (filters?.submittedBy) {
74
- query += " AND a.submitted_by = ?";
74
+ clauses.push("a.submitted_by = ?");
75
75
  params.push(filters.submittedBy);
76
76
  }
77
- query += " ORDER BY a.created_at DESC";
77
+ return { where: clauses.length ? " AND " + clauses.join(" AND ") : "", params };
78
+ }
79
+ async function countApprovals(filters) {
80
+ const { where, params } = buildWhereParams(filters);
81
+ const row = await (0, import_server_plugin_pg.getPgDb)().queryOne(
82
+ `SELECT COUNT(*) AS total FROM approvals a WHERE 1=1` + where,
83
+ params
84
+ );
85
+ return Number(row?.["total"] ?? 0);
86
+ }
87
+ async function listApprovals(filters) {
88
+ let query = `SELECT a.*, u.username AS submitter_name
89
+ FROM approvals a
90
+ LEFT JOIN users u ON u.id = a.submitted_by
91
+ WHERE 1=1`;
92
+ const { where, params } = buildWhereParams(filters);
93
+ query += where + " ORDER BY a.created_at DESC LIMIT ? OFFSET ?";
94
+ params.push(filters?.limit ?? 50, filters?.offset ?? 0);
78
95
  return (0, import_server_plugin_pg.getPgDb)().query(query, params);
79
96
  }
80
97
  function getApprovalById(id) {
81
98
  return (0, import_server_plugin_pg.getPgDb)().queryOne(FIND_BY_ID, [id]);
82
99
  }
83
- function insertApproval(dataSourceId, dbName, sqlText, submittedBy) {
84
- return (0, import_server_plugin_pg.getPgDb)().queryOne(CREATE, [dataSourceId, dbName, sqlText, submittedBy]);
100
+ function insertApproval({ dataSourceId, dbName, sqlText, submittedBy, sqlType = "DML" }) {
101
+ return (0, import_server_plugin_pg.getPgDb)().queryOne(CREATE, [dataSourceId, dbName, sqlText, submittedBy, sqlType]);
85
102
  }
86
103
  function updateReview(id, status, reviewedBy, rejectReason) {
87
104
  return (0, import_server_plugin_pg.getPgDb)().queryOne(UPDATE_REVIEW(), [status, reviewedBy, rejectReason, id]);
@@ -95,13 +112,15 @@ function setExecuteResult(id, status, result) {
95
112
 
96
113
  // src/approvals.service.ts
97
114
  async function approvalList(req, reply) {
98
- const { status, mine } = req.body ?? {};
99
- return reply.send(
100
- await listApprovals({
101
- status,
102
- submittedBy: mine === "true" ? req.user.id : void 0
103
- })
104
- );
115
+ const { status, mine, limit, offset } = req.body ?? {};
116
+ const filters = {
117
+ status,
118
+ submittedBy: mine === "true" ? req.user.id : void 0,
119
+ limit: limit ? Number(limit) : void 0,
120
+ offset: offset ? Number(offset) : void 0
121
+ };
122
+ const [rows, total] = await Promise.all([listApprovals(filters), countApprovals(filters)]);
123
+ return reply.send({ rows, total });
105
124
  }
106
125
  async function approvalGet(req, reply) {
107
126
  const { id } = req.body ?? {};
@@ -110,12 +129,19 @@ async function approvalGet(req, reply) {
110
129
  return reply.send(approval);
111
130
  }
112
131
  async function approvalCreate(req, reply) {
113
- const { dataSourceId, database, sql } = req.body ?? {};
132
+ const { dataSourceId, database, sql, sqlType } = req.body ?? {};
114
133
  if (!dataSourceId || !sql) {
115
134
  return reply.code(400).send({ error: "Data source ID and SQL are required" });
116
135
  }
117
- const approval = await insertApproval(dataSourceId, database ?? null, sql, req.user.id);
118
- req.log.info("Approval submitted (user=%s)", req.user.id);
136
+ const type = sqlType === "EXPORT" ? "EXPORT" : "DML";
137
+ const approval = await insertApproval({
138
+ dataSourceId,
139
+ dbName: database ?? null,
140
+ sqlText: sql,
141
+ submittedBy: req.user.id,
142
+ sqlType: type
143
+ });
144
+ req.log.info("Approval submitted (user=%s, type=%s)", req.user.id, type);
119
145
  return reply.code(201).send(approval);
120
146
  }
121
147
  async function reviewApproval(id, reviewerId, decision, rejectReason) {
@@ -205,5 +231,8 @@ async function doExecuteApproval({ id, userId, ip, encryptionKey }, log) {
205
231
  approvalExecute,
206
232
  approvalGet,
207
233
  approvalList,
208
- approvalReject
234
+ approvalReject,
235
+ getApprovalById,
236
+ setExecuteResult,
237
+ setExecuting
209
238
  });
package/dist/index.mjs CHANGED
@@ -11,8 +11,8 @@ SELECT *
11
11
  FROM approvals
12
12
  WHERE id = ?`;
13
13
  var CREATE = `
14
- INSERT INTO approvals (data_source_id, db_name, sql_text, submitted_by)
15
- VALUES (?, ?, ?, ?)
14
+ INSERT INTO approvals (data_source_id, db_name, sql_text, submitted_by, sql_type)
15
+ VALUES (?, ?, ?, ?, ?)
16
16
  RETURNING *`;
17
17
  var UPDATE_REVIEW = () => `
18
18
  UPDATE approvals
@@ -29,28 +29,42 @@ SET status = ?, execute_result = ?, updated_at = NOW()
29
29
  WHERE id = ?`;
30
30
 
31
31
  // src/approvals.model.ts
32
- async function listApprovals(filters) {
33
- let query = `SELECT a.*, u.username AS submitter_name
34
- FROM approvals a
35
- LEFT JOIN users u ON u.id = a.submitted_by
36
- WHERE 1=1`;
32
+ function buildWhereParams(filters) {
33
+ const clauses = [];
37
34
  const params = [];
38
35
  if (filters?.status) {
39
- query += " AND a.status = ?";
36
+ clauses.push("a.status = ?");
40
37
  params.push(filters.status);
41
38
  }
42
39
  if (filters?.submittedBy) {
43
- query += " AND a.submitted_by = ?";
40
+ clauses.push("a.submitted_by = ?");
44
41
  params.push(filters.submittedBy);
45
42
  }
46
- query += " ORDER BY a.created_at DESC";
43
+ return { where: clauses.length ? " AND " + clauses.join(" AND ") : "", params };
44
+ }
45
+ async function countApprovals(filters) {
46
+ const { where, params } = buildWhereParams(filters);
47
+ const row = await getPgDb().queryOne(
48
+ `SELECT COUNT(*) AS total FROM approvals a WHERE 1=1` + where,
49
+ params
50
+ );
51
+ return Number(row?.["total"] ?? 0);
52
+ }
53
+ async function listApprovals(filters) {
54
+ let query = `SELECT a.*, u.username AS submitter_name
55
+ FROM approvals a
56
+ LEFT JOIN users u ON u.id = a.submitted_by
57
+ WHERE 1=1`;
58
+ const { where, params } = buildWhereParams(filters);
59
+ query += where + " ORDER BY a.created_at DESC LIMIT ? OFFSET ?";
60
+ params.push(filters?.limit ?? 50, filters?.offset ?? 0);
47
61
  return getPgDb().query(query, params);
48
62
  }
49
63
  function getApprovalById(id) {
50
64
  return getPgDb().queryOne(FIND_BY_ID, [id]);
51
65
  }
52
- function insertApproval(dataSourceId, dbName, sqlText, submittedBy) {
53
- return getPgDb().queryOne(CREATE, [dataSourceId, dbName, sqlText, submittedBy]);
66
+ function insertApproval({ dataSourceId, dbName, sqlText, submittedBy, sqlType = "DML" }) {
67
+ return getPgDb().queryOne(CREATE, [dataSourceId, dbName, sqlText, submittedBy, sqlType]);
54
68
  }
55
69
  function updateReview(id, status, reviewedBy, rejectReason) {
56
70
  return getPgDb().queryOne(UPDATE_REVIEW(), [status, reviewedBy, rejectReason, id]);
@@ -64,13 +78,15 @@ function setExecuteResult(id, status, result) {
64
78
 
65
79
  // src/approvals.service.ts
66
80
  async function approvalList(req, reply) {
67
- const { status, mine } = req.body ?? {};
68
- return reply.send(
69
- await listApprovals({
70
- status,
71
- submittedBy: mine === "true" ? req.user.id : void 0
72
- })
73
- );
81
+ const { status, mine, limit, offset } = req.body ?? {};
82
+ const filters = {
83
+ status,
84
+ submittedBy: mine === "true" ? req.user.id : void 0,
85
+ limit: limit ? Number(limit) : void 0,
86
+ offset: offset ? Number(offset) : void 0
87
+ };
88
+ const [rows, total] = await Promise.all([listApprovals(filters), countApprovals(filters)]);
89
+ return reply.send({ rows, total });
74
90
  }
75
91
  async function approvalGet(req, reply) {
76
92
  const { id } = req.body ?? {};
@@ -79,12 +95,19 @@ async function approvalGet(req, reply) {
79
95
  return reply.send(approval);
80
96
  }
81
97
  async function approvalCreate(req, reply) {
82
- const { dataSourceId, database, sql } = req.body ?? {};
98
+ const { dataSourceId, database, sql, sqlType } = req.body ?? {};
83
99
  if (!dataSourceId || !sql) {
84
100
  return reply.code(400).send({ error: "Data source ID and SQL are required" });
85
101
  }
86
- const approval = await insertApproval(dataSourceId, database ?? null, sql, req.user.id);
87
- req.log.info("Approval submitted (user=%s)", req.user.id);
102
+ const type = sqlType === "EXPORT" ? "EXPORT" : "DML";
103
+ const approval = await insertApproval({
104
+ dataSourceId,
105
+ dbName: database ?? null,
106
+ sqlText: sql,
107
+ submittedBy: req.user.id,
108
+ sqlType: type
109
+ });
110
+ req.log.info("Approval submitted (user=%s, type=%s)", req.user.id, type);
88
111
  return reply.code(201).send(approval);
89
112
  }
90
113
  async function reviewApproval(id, reviewerId, decision, rejectReason) {
@@ -173,5 +196,8 @@ export {
173
196
  approvalExecute,
174
197
  approvalGet,
175
198
  approvalList,
176
- approvalReject
199
+ approvalReject,
200
+ getApprovalById,
201
+ setExecuteResult,
202
+ setExecuting
177
203
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.7.1",
6
+ "version": "0.8.0",
7
7
  "description": "DMS approval workflow domain logic: service, model, sql",
8
8
  "main": "./dist/index.js",
9
9
  "module": "./dist/index.mjs",
@@ -26,7 +26,7 @@
26
26
  "clean": "rm -rf dist"
27
27
  },
28
28
  "dependencies": {
29
- "@heyhru/business-dms-audit": "0.6.1",
29
+ "@heyhru/business-dms-audit": "0.6.2",
30
30
  "@heyhru/business-dms-datasource": "0.8.1",
31
31
  "@heyhru/server-plugin-pg": "0.7.0",
32
32
  "fastify": "^5.8.4"
@@ -36,5 +36,5 @@
36
36
  "typescript": "^6.0.2",
37
37
  "vitest": "^4.1.4"
38
38
  },
39
- "gitHead": "6bd2092d7f1dd2bc23d5252e2be4136792ddec4f"
39
+ "gitHead": "63975371f0229a1e097295daabe992835ef4249d"
40
40
  }