@opengis/fastify-table 1.0.39 → 1.0.41
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.
- package/Changelog.md +8 -0
- package/index.js +26 -1
- package/package.json +1 -1
- package/server/migrations/crm.sql +55 -5
- package/widget/controllers/widget.get.js +22 -12
package/Changelog.md
CHANGED
package/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
+
import { readdir, readFile } from 'fs/promises';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
2
4
|
|
|
3
5
|
import fp from 'fastify-plugin';
|
|
4
6
|
import config from './config.js';
|
|
@@ -12,6 +14,8 @@ import widgetPlugin from './widget/index.js';
|
|
|
12
14
|
import crudPlugin from './crud/index.js';
|
|
13
15
|
import policyPlugin from './policy/index.js';
|
|
14
16
|
|
|
17
|
+
import pgClients from './pg/pgClients.js';
|
|
18
|
+
|
|
15
19
|
async function plugin(fastify, opt) {
|
|
16
20
|
// console.log(opt);
|
|
17
21
|
config.pg = opt.pg;
|
|
@@ -27,10 +31,31 @@ async function plugin(fastify, opt) {
|
|
|
27
31
|
fastify.decorate('getFolder', (req, type = 'server') => {
|
|
28
32
|
if (!['server', 'local'].includes(type)) throw new Error('params type is invalid');
|
|
29
33
|
const types = { local: req.root, server: req.mapServerRoot };
|
|
30
|
-
const filepath = path.posix.join(types[type] || '/data/local', req.folder || '');
|
|
34
|
+
const filepath = path.posix.join(types[type] || '/data/local', req.folder || config.folder || '');
|
|
31
35
|
return filepath;
|
|
32
36
|
});
|
|
33
37
|
|
|
38
|
+
fastify.addHook('onListen', async () => {
|
|
39
|
+
const { client } = pgClients;
|
|
40
|
+
if (client?.pk?.['crm.cls']) {
|
|
41
|
+
const clsDir = path.join(process.cwd(), 'server/templates/cls');
|
|
42
|
+
const files = existsSync(clsDir) ? await readdir(clsDir) : [];
|
|
43
|
+
if (files.length) {
|
|
44
|
+
const res = await Promise.all(files.map(async (filename) => {
|
|
45
|
+
const filepath = path.join(clsDir, filename);
|
|
46
|
+
const data = JSON.parse(await readFile(filepath));
|
|
47
|
+
return { name: path.parse(filename).name, data };
|
|
48
|
+
}));
|
|
49
|
+
await client.query('truncate table crm.cls');
|
|
50
|
+
const { rows } = await client.query(`insert into crm.cls(name, type)
|
|
51
|
+
select value->>'name', 'json' from json_array_elements($1) returning cls_id as id, name`, [JSON.stringify(res).replace(/'/g, "''")]);
|
|
52
|
+
rows.forEach((row) => Object.assign(row, { data: res.find((cls) => row.name === cls.name)?.data }));
|
|
53
|
+
const sql = `insert into crm.cls(code, name, parent)
|
|
54
|
+
select json_array_elements(value->'data')->>'id', json_array_elements(value->'data')->>'text', value->>'name' from json_array_elements($1)`;
|
|
55
|
+
await client.query(sql, [JSON.stringify(rows).replace(/'/g, "''")]);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
34
59
|
if (!fastify.funcs) {
|
|
35
60
|
fastify.addHook('onRequest', async (req) => {
|
|
36
61
|
req.funcs = fastify;
|
package/package.json
CHANGED
|
@@ -1,8 +1,37 @@
|
|
|
1
|
+
-- next_id()
|
|
2
|
+
CREATE SEQUENCE crm.cls_clsid_seq
|
|
3
|
+
INCREMENT 1
|
|
4
|
+
MINVALUE 1
|
|
5
|
+
MAXVALUE 9223372036854775807
|
|
6
|
+
START 128142470
|
|
7
|
+
CACHE 1;
|
|
8
|
+
CREATE OR REPLACE FUNCTION crm.next_id()
|
|
9
|
+
RETURNS bigint AS
|
|
10
|
+
$BODY$
|
|
11
|
+
DECLARE
|
|
12
|
+
our_epoch bigint := 1314220021721;
|
|
13
|
+
seq_id bigint;
|
|
14
|
+
now_millis bigint;
|
|
15
|
+
shard_id int := 1;
|
|
16
|
+
result bigint;
|
|
17
|
+
BEGIN
|
|
18
|
+
SELECT nextval('crm.cls_clsid_seq') % 1024 INTO seq_id;
|
|
19
|
+
|
|
20
|
+
SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;
|
|
21
|
+
result := (now_millis - our_epoch) << 23;
|
|
22
|
+
result := result | (shard_id << 10);
|
|
23
|
+
result := result | (seq_id);
|
|
24
|
+
return result;
|
|
25
|
+
END;
|
|
26
|
+
$BODY$
|
|
27
|
+
LANGUAGE plpgsql VOLATILE
|
|
28
|
+
COST 100;
|
|
29
|
+
|
|
1
30
|
-- crm.notifications
|
|
2
31
|
-- DROP TABLE IF EXISTS crm.notifications;
|
|
3
32
|
CREATE TABLE IF NOT EXISTS crm.notifications();
|
|
4
33
|
ALTER TABLE crm.notifications DROP CONSTRAINT IF EXISTS crm_notifications_pkey;
|
|
5
|
-
ALTER TABLE crm.notifications ADD COLUMN IF NOT EXISTS notification_id text NOT NULL DEFAULT
|
|
34
|
+
ALTER TABLE crm.notifications ADD COLUMN IF NOT EXISTS notification_id text NOT NULL DEFAULT crm.next_id();
|
|
6
35
|
|
|
7
36
|
ALTER TABLE crm.notifications ADD COLUMN IF NOT EXISTS notification_user_id text;
|
|
8
37
|
ALTER TABLE crm.notifications ADD COLUMN IF NOT EXISTS notification_type text DEFAULT 'notify'::text;
|
|
@@ -22,7 +51,7 @@ ALTER TABLE crm.notifications ADD CONSTRAINT crm_notifications_pkey PRIMARY KEY
|
|
|
22
51
|
-- DROP TABLE IF EXISTS crm.files;
|
|
23
52
|
CREATE TABLE IF NOT EXISTS crm.files();
|
|
24
53
|
ALTER TABLE crm.files DROP CONSTRAINT IF EXISTS crm_files_pkey;
|
|
25
|
-
ALTER TABLE crm.files ADD COLUMN IF NOT EXISTS file_id text NOT NULL DEFAULT
|
|
54
|
+
ALTER TABLE crm.files ADD COLUMN IF NOT EXISTS file_id text NOT NULL DEFAULT crm.next_id();
|
|
26
55
|
|
|
27
56
|
ALTER TABLE crm.files ADD COLUMN IF NOT EXISTS uploaded_name text;
|
|
28
57
|
ALTER TABLE crm.files ADD COLUMN IF NOT EXISTS entity_id text; -- object_id
|
|
@@ -48,7 +77,7 @@ ALTER TABLE crm.files ADD CONSTRAINT crm_files_pkey PRIMARY KEY (file_id);
|
|
|
48
77
|
-- DROP TABLE IF EXISTS crm.communications;
|
|
49
78
|
CREATE TABLE IF NOT EXISTS crm.communications();
|
|
50
79
|
ALTER TABLE crm.communications DROP CONSTRAINT IF EXISTS crm_communications_pkey;
|
|
51
|
-
ALTER TABLE crm.communications ADD COLUMN IF NOT EXISTS communication_id text NOT NULL DEFAULT
|
|
80
|
+
ALTER TABLE crm.communications ADD COLUMN IF NOT EXISTS communication_id text NOT NULL DEFAULT crm.next_id();
|
|
52
81
|
|
|
53
82
|
ALTER TABLE crm.communications ADD COLUMN IF NOT EXISTS entity_id text; -- object_id
|
|
54
83
|
ALTER TABLE crm.communications ADD COLUMN IF NOT EXISTS entity_type text; -- table_name
|
|
@@ -74,8 +103,8 @@ ALTER TABLE crm.communications ADD CONSTRAINT crm_communications_pkey PRIMARY KE
|
|
|
74
103
|
-- crm.checklists
|
|
75
104
|
-- DROP TABLE IF EXISTS crm.checklists;
|
|
76
105
|
CREATE TABLE IF NOT EXISTS crm.checklists();
|
|
77
|
-
ALTER TABLE crm.checklists DROP CONSTRAINT IF EXISTS
|
|
78
|
-
ALTER TABLE crm.checklists ADD COLUMN IF NOT EXISTS checklist_id text NOT NULL DEFAULT
|
|
106
|
+
ALTER TABLE crm.checklists DROP CONSTRAINT IF EXISTS crm_checklists_pkey;
|
|
107
|
+
ALTER TABLE crm.checklists ADD COLUMN IF NOT EXISTS checklist_id text NOT NULL DEFAULT crm.next_id();
|
|
79
108
|
|
|
80
109
|
ALTER TABLE crm.checklists ADD COLUMN IF NOT EXISTS entity_id text; -- object_id
|
|
81
110
|
ALTER TABLE crm.checklists ADD COLUMN IF NOT EXISTS entity_type text; -- table_name
|
|
@@ -93,3 +122,24 @@ ALTER TABLE crm.checklists ADD COLUMN IF NOT EXISTS cdate timestamp without time
|
|
|
93
122
|
ALTER TABLE crm.checklists ADD COLUMN IF NOT EXISTS editor_id text;
|
|
94
123
|
ALTER TABLE crm.checklists ADD COLUMN IF NOT EXISTS editor_date timestamp without time zone;
|
|
95
124
|
ALTER TABLE crm.checklists ADD CONSTRAINT crm_checklists_pkey PRIMARY KEY (checklist_id);
|
|
125
|
+
|
|
126
|
+
-- crm.cls
|
|
127
|
+
-- DROP TABLE IF EXISTS crm.cls;
|
|
128
|
+
CREATE TABLE IF NOT EXISTS crm.cls();
|
|
129
|
+
ALTER TABLE crm.cls ADD COLUMN IF NOT EXISTS cls_id text NOT NULL DEFAULT crm.next_id();
|
|
130
|
+
|
|
131
|
+
ALTER TABLE crm.cls ADD COLUMN IF NOT EXISTS name text;
|
|
132
|
+
ALTER TABLE crm.cls ADD COLUMN IF NOT EXISTS data text;
|
|
133
|
+
ALTER TABLE crm.cls ADD COLUMN IF NOT EXISTS type text;
|
|
134
|
+
ALTER TABLE crm.cls ADD COLUMN IF NOT EXISTS parent text;
|
|
135
|
+
ALTER TABLE crm.cls ADD COLUMN IF NOT EXISTS code text;
|
|
136
|
+
ALTER TABLE crm.cls ADD COLUMN IF NOT EXISTS color text;
|
|
137
|
+
ALTER TABLE crm.cls ADD COLUMN IF NOT EXISTS icon text;
|
|
138
|
+
|
|
139
|
+
ALTER TABLE crm.cls ADD COLUMN IF NOT EXISTS uid text;
|
|
140
|
+
ALTER TABLE crm.cls ADD COLUMN IF NOT EXISTS files json;
|
|
141
|
+
ALTER TABLE crm.cls ADD COLUMN IF NOT EXISTS cdate timestamp without time zone DEFAULT (now())::timestamp without time zone;
|
|
142
|
+
ALTER TABLE crm.cls ADD COLUMN IF NOT EXISTS editor_id text;
|
|
143
|
+
ALTER TABLE crm.cls ADD COLUMN IF NOT EXISTS editor_date timestamp without time zone;
|
|
144
|
+
ALTER TABLE crm.cls ADD CONSTRAINT crm_cls_pkey PRIMARY KEY (cls_id);
|
|
145
|
+
ALTER TABLE crm.cls ADD CONSTRAINT crm_cls_unique UNIQUE (code, parent);
|
|
@@ -23,25 +23,35 @@ export default async function widgetGet({
|
|
|
23
23
|
if (!objectid) return { error: 'id required', status: 400 };
|
|
24
24
|
|
|
25
25
|
const sqls = {
|
|
26
|
-
comment:
|
|
26
|
+
comment: pg.pk['admin.users']
|
|
27
|
+
? `select communication_id, entity_id, body, subject, c.cdate, c.uid,
|
|
27
28
|
coalesce(user_name,' ')||' '||coalesce(sur_name,'') as username, avatar
|
|
28
|
-
from crm.communications c left join admin.users u on u.uid=c.uid where entity_id=$1 order by cdate desc
|
|
29
|
+
from crm.communications c left join admin.users u on u.uid=c.uid where entity_id=$1 order by cdate desc`
|
|
30
|
+
: 'select communication_id, entity_id, body, subject, cdate, uid from crm.communications where entity_id=$1 order by cdate desc',
|
|
29
31
|
|
|
30
32
|
history: `SELECT table_change_id, entity_id, entity_type, change_key, change_date, json_old, json_new, date_old,
|
|
31
33
|
date_new, number_old, number_new, bool_old, bool_new, text_old,
|
|
32
34
|
text_new, uid, cdate FROM log.table_changes where entity_id=$1 order by cdate desc, change_key limit 100`,
|
|
33
35
|
|
|
34
|
-
checklist:
|
|
35
|
-
|
|
36
|
+
checklist: pg.pk['admin.users']
|
|
37
|
+
? `SELECT checklist_id, entity_id, subject, is_done, done_date, c.uid, c.cdate, coalesce(user_name,' ')||' '||coalesce(sur_name,'') as username,
|
|
38
|
+
avatar FROM crm.checklists c left join admin.users u on u.uid=c.uid where entity_id=$1 order by cdate desc`
|
|
39
|
+
: 'SELECT checklist_id, entity_id, subject, is_done, done_date, uid, cdate FROM crm.checklists where entity_id=$1 order by cdate desc',
|
|
36
40
|
|
|
37
|
-
file:
|
|
41
|
+
file: pg.pk['admin.users']
|
|
42
|
+
? `SELECT file_id, entity_id, entity_type, file_path, uploaded_name, ext, size, c.uid, c.cdate, file_type, c.ismain,
|
|
38
43
|
coalesce(user_name,' ')||' '||coalesce(sur_name,'') as username, isverified,
|
|
39
44
|
avatar, c.uid as author, file_status FROM crm.files c left join admin.users u on u.uid=c.uid
|
|
40
|
-
where entity_id=$1 and file_status<>3 order by cdate desc
|
|
41
|
-
|
|
45
|
+
where entity_id=$1 and file_status<>3 order by cdate desc`
|
|
46
|
+
: `SELECT file_id, entity_id, entity_type, file_path, uploaded_name, ext, size, uid, cdate, file_type, ismain,
|
|
47
|
+
isverified, uid as author, file_status FROM crm.files c where entity_id=$1 and file_status<>3 order by cdate desc`,
|
|
48
|
+
gallery: pg.pk['admin.users']
|
|
49
|
+
? `SELECT file_id, entity_id, entity_type, file_path, uploaded_name, ext, size, c.uid, c.cdate, file_type, c.ismain,
|
|
42
50
|
coalesce(user_name,' ')||' '||coalesce(sur_name,'') as username, isverified,
|
|
43
51
|
avatar, c.uid as author, file_status FROM crm.files c left join admin.users u on u.uid=c.uid
|
|
44
|
-
where entity_id=$1 and file_status<>3 and ext = any($2) order by cdate desc
|
|
52
|
+
where entity_id=$1 and file_status<>3 and ext = any($2) order by cdate desc`
|
|
53
|
+
: `SELECT file_id, entity_id, entity_type, file_path, uploaded_name, ext, size, c.uid, c.cdate, file_type, ismain,
|
|
54
|
+
isverified, uid as author, file_status FROM crm.files c where entity_id=$1 and file_status<>3 and ext = any($2) order by cdate desc`,
|
|
45
55
|
|
|
46
56
|
};
|
|
47
57
|
const sql = sqls[params.type];
|
|
@@ -56,12 +66,12 @@ export default async function widgetGet({
|
|
|
56
66
|
time.push(Date.now());
|
|
57
67
|
|
|
58
68
|
/* Object info */
|
|
59
|
-
const { tableName } = await pg.one('select entity_type as "tableName" from log.table_changes where entity_id=$1 limit 1', [objectid]);
|
|
69
|
+
const { tableName } = pg.pk['log.table_changes'] ? await pg.one('select entity_type as "tableName" from log.table_changes where entity_id=$1 limit 1', [objectid]) : {};
|
|
60
70
|
const { pk } = await getMeta({ table: tableName });
|
|
61
71
|
|
|
62
|
-
const q = `select coalesce(b.user_name,'')||coalesce(' '||b.sur_name,'') as author, a.cdate, a.editor_date from ${tableName} a
|
|
63
|
-
left join admin.users b on a.uid=b.uid where a.${pk}=$1 limit 1
|
|
64
|
-
const data = pk ? await pg.one(q, [objectid]) : {};
|
|
72
|
+
const q = tableName && pg.pk['admin.users'] ? `select coalesce(b.user_name,'')||coalesce(' '||b.sur_name,'') as author, a.cdate, a.editor_date from ${tableName} a
|
|
73
|
+
left join admin.users b on a.uid=b.uid where a.${pk}=$1 limit 1` : undefined;
|
|
74
|
+
const data = pk && q ? await pg.one(q, [objectid]) : {};
|
|
65
75
|
|
|
66
76
|
if (query.debug && user?.user_type === 'admin') {
|
|
67
77
|
return {
|