@loomcore/api 0.1.106 → 0.1.110
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/LICENSE +201 -201
- package/README.md +77 -77
- package/dist/__tests__/postgres-test-migrations/postgres-test-schema.js +266 -266
- package/dist/__tests__/postgres.test-database.js +8 -8
- package/dist/controllers/organizations.controller.d.ts +6 -2
- package/dist/controllers/organizations.controller.js +2 -2
- package/dist/databases/migrations/migration-runner.js +21 -21
- package/dist/databases/postgres/commands/postgres-batch-update.command.js +7 -7
- package/dist/databases/postgres/commands/postgres-create-many.command.js +4 -4
- package/dist/databases/postgres/commands/postgres-create.command.js +4 -4
- package/dist/databases/postgres/commands/postgres-full-update-by-id.command.js +13 -13
- package/dist/databases/postgres/commands/postgres-partial-update-by-id.command.js +7 -7
- package/dist/databases/postgres/commands/postgres-update.command.js +7 -7
- package/dist/databases/postgres/migrations/postgres-initial-schema.js +224 -224
- package/dist/databases/postgres/postgres.database.js +17 -17
- package/dist/databases/postgres/utils/build-select-clause.js +26 -9
- package/dist/databases/postgres/utils/does-table-exist.util.js +4 -4
- package/package.json +92 -92
|
@@ -13,22 +13,22 @@ export const getPostgresInitialSchema = (dbConfig) => {
|
|
|
13
13
|
migrations.push({
|
|
14
14
|
name: '00000000000001_schema-organizations',
|
|
15
15
|
up: async ({ context: pool }) => {
|
|
16
|
-
await pool.query(`
|
|
17
|
-
CREATE TABLE IF NOT EXISTS "organizations" (
|
|
18
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
19
|
-
"name" VARCHAR(255) NOT NULL UNIQUE,
|
|
20
|
-
"code" VARCHAR(255) NOT NULL UNIQUE,
|
|
21
|
-
"description" TEXT,
|
|
22
|
-
"status" INTEGER NOT NULL,
|
|
23
|
-
"is_meta_org" BOOLEAN NOT NULL,
|
|
24
|
-
"auth_token" TEXT,
|
|
25
|
-
"_created" TIMESTAMPTZ NOT NULL,
|
|
26
|
-
"_createdBy" INTEGER NOT NULL,
|
|
27
|
-
"_updated" TIMESTAMPTZ NOT NULL,
|
|
28
|
-
"_updatedBy" INTEGER NOT NULL,
|
|
29
|
-
"_deleted" TIMESTAMPTZ,
|
|
30
|
-
"_deletedBy" INTEGER
|
|
31
|
-
)
|
|
16
|
+
await pool.query(`
|
|
17
|
+
CREATE TABLE IF NOT EXISTS "organizations" (
|
|
18
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
19
|
+
"name" VARCHAR(255) NOT NULL UNIQUE,
|
|
20
|
+
"code" VARCHAR(255) NOT NULL UNIQUE,
|
|
21
|
+
"description" TEXT,
|
|
22
|
+
"status" INTEGER NOT NULL,
|
|
23
|
+
"is_meta_org" BOOLEAN NOT NULL,
|
|
24
|
+
"auth_token" TEXT,
|
|
25
|
+
"_created" TIMESTAMPTZ NOT NULL,
|
|
26
|
+
"_createdBy" INTEGER NOT NULL,
|
|
27
|
+
"_updated" TIMESTAMPTZ NOT NULL,
|
|
28
|
+
"_updatedBy" INTEGER NOT NULL,
|
|
29
|
+
"_deleted" TIMESTAMPTZ,
|
|
30
|
+
"_deletedBy" INTEGER
|
|
31
|
+
)
|
|
32
32
|
`);
|
|
33
33
|
},
|
|
34
34
|
down: async ({ context: pool }) => {
|
|
@@ -41,26 +41,26 @@ export const getPostgresInitialSchema = (dbConfig) => {
|
|
|
41
41
|
name: '00000000000002_schema-persons',
|
|
42
42
|
up: async ({ context: pool }) => {
|
|
43
43
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
44
|
-
await pool.query(`
|
|
45
|
-
CREATE TABLE IF NOT EXISTS "persons" (
|
|
46
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
47
|
-
${orgColumnDef}
|
|
48
|
-
"external_id" VARCHAR(255) UNIQUE,
|
|
49
|
-
"first_name" VARCHAR(255) NOT NULL,
|
|
50
|
-
"middle_name" VARCHAR(255),
|
|
51
|
-
"last_name" VARCHAR(255) NOT NULL,
|
|
52
|
-
"date_of_birth" DATE,
|
|
53
|
-
"is_agent" BOOLEAN NOT NULL DEFAULT FALSE,
|
|
54
|
-
"is_client" BOOLEAN NOT NULL DEFAULT FALSE,
|
|
55
|
-
"is_employee" BOOLEAN NOT NULL DEFAULT FALSE,
|
|
56
|
-
"extended_types" INTEGER,
|
|
57
|
-
"_created" TIMESTAMPTZ NOT NULL,
|
|
58
|
-
"_createdBy" INTEGER NOT NULL,
|
|
59
|
-
"_updated" TIMESTAMPTZ NOT NULL,
|
|
60
|
-
"_updatedBy" INTEGER NOT NULL,
|
|
61
|
-
"_deleted" TIMESTAMPTZ,
|
|
62
|
-
"_deletedBy" INTEGER
|
|
63
|
-
)
|
|
44
|
+
await pool.query(`
|
|
45
|
+
CREATE TABLE IF NOT EXISTS "persons" (
|
|
46
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
47
|
+
${orgColumnDef}
|
|
48
|
+
"external_id" VARCHAR(255) UNIQUE,
|
|
49
|
+
"first_name" VARCHAR(255) NOT NULL,
|
|
50
|
+
"middle_name" VARCHAR(255),
|
|
51
|
+
"last_name" VARCHAR(255) NOT NULL,
|
|
52
|
+
"date_of_birth" DATE,
|
|
53
|
+
"is_agent" BOOLEAN NOT NULL DEFAULT FALSE,
|
|
54
|
+
"is_client" BOOLEAN NOT NULL DEFAULT FALSE,
|
|
55
|
+
"is_employee" BOOLEAN NOT NULL DEFAULT FALSE,
|
|
56
|
+
"extended_types" INTEGER,
|
|
57
|
+
"_created" TIMESTAMPTZ NOT NULL,
|
|
58
|
+
"_createdBy" INTEGER NOT NULL,
|
|
59
|
+
"_updated" TIMESTAMPTZ NOT NULL,
|
|
60
|
+
"_updatedBy" INTEGER NOT NULL,
|
|
61
|
+
"_deleted" TIMESTAMPTZ,
|
|
62
|
+
"_deletedBy" INTEGER
|
|
63
|
+
)
|
|
64
64
|
`);
|
|
65
65
|
},
|
|
66
66
|
down: async ({ context: pool }) => {
|
|
@@ -75,27 +75,27 @@ export const getPostgresInitialSchema = (dbConfig) => {
|
|
|
75
75
|
let uniqueConstraint = isMultiTenant
|
|
76
76
|
? 'CONSTRAINT "uk_users_email" UNIQUE ("_orgId", "email")'
|
|
77
77
|
: 'CONSTRAINT "uk_users_email" UNIQUE ("email")';
|
|
78
|
-
uniqueConstraint += `,
|
|
78
|
+
uniqueConstraint += `,
|
|
79
79
|
CONSTRAINT "fk_users_person_id" FOREIGN KEY("person_id") REFERENCES "persons"("_id") ON DELETE CASCADE`;
|
|
80
|
-
await pool.query(`
|
|
81
|
-
CREATE TABLE IF NOT EXISTS "users" (
|
|
82
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
83
|
-
${orgColumnDef}
|
|
84
|
-
"external_id" VARCHAR(255) UNIQUE,
|
|
85
|
-
"email" VARCHAR(255) NOT NULL,
|
|
86
|
-
"display_name" VARCHAR(255),
|
|
87
|
-
"password" VARCHAR(255) NOT NULL,
|
|
88
|
-
"person_id" INTEGER UNIQUE,
|
|
89
|
-
"_lastLoggedIn" TIMESTAMPTZ,
|
|
90
|
-
"_lastPasswordChange" TIMESTAMPTZ,
|
|
91
|
-
"_created" TIMESTAMPTZ NOT NULL,
|
|
92
|
-
"_createdBy" INTEGER NOT NULL,
|
|
93
|
-
"_updated" TIMESTAMPTZ NOT NULL,
|
|
94
|
-
"_updatedBy" INTEGER NOT NULL,
|
|
95
|
-
"_deleted" TIMESTAMPTZ,
|
|
96
|
-
"_deletedBy" INTEGER,
|
|
97
|
-
${uniqueConstraint}
|
|
98
|
-
)
|
|
80
|
+
await pool.query(`
|
|
81
|
+
CREATE TABLE IF NOT EXISTS "users" (
|
|
82
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
83
|
+
${orgColumnDef}
|
|
84
|
+
"external_id" VARCHAR(255) UNIQUE,
|
|
85
|
+
"email" VARCHAR(255) NOT NULL,
|
|
86
|
+
"display_name" VARCHAR(255),
|
|
87
|
+
"password" VARCHAR(255) NOT NULL,
|
|
88
|
+
"person_id" INTEGER UNIQUE,
|
|
89
|
+
"_lastLoggedIn" TIMESTAMPTZ,
|
|
90
|
+
"_lastPasswordChange" TIMESTAMPTZ,
|
|
91
|
+
"_created" TIMESTAMPTZ NOT NULL,
|
|
92
|
+
"_createdBy" INTEGER NOT NULL,
|
|
93
|
+
"_updated" TIMESTAMPTZ NOT NULL,
|
|
94
|
+
"_updatedBy" INTEGER NOT NULL,
|
|
95
|
+
"_deleted" TIMESTAMPTZ,
|
|
96
|
+
"_deletedBy" INTEGER,
|
|
97
|
+
${uniqueConstraint}
|
|
98
|
+
)
|
|
99
99
|
`);
|
|
100
100
|
},
|
|
101
101
|
down: async ({ context: pool }) => {
|
|
@@ -107,18 +107,18 @@ export const getPostgresInitialSchema = (dbConfig) => {
|
|
|
107
107
|
name: '00000000000004_schema-refresh-tokens',
|
|
108
108
|
up: async ({ context: pool }) => {
|
|
109
109
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
110
|
-
await pool.query(`
|
|
111
|
-
CREATE TABLE IF NOT EXISTS "refresh_tokens" (
|
|
112
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
113
|
-
${orgColumnDef}
|
|
114
|
-
"token" VARCHAR(255) NOT NULL,
|
|
115
|
-
"device_id" VARCHAR(255) NOT NULL,
|
|
116
|
-
"user_id" INTEGER NOT NULL,
|
|
117
|
-
"expires_on" BIGINT NOT NULL,
|
|
118
|
-
"created" TIMESTAMPTZ NOT NULL,
|
|
119
|
-
"created_by" INTEGER NOT NULL,
|
|
120
|
-
CONSTRAINT "fk_refresh_tokens_user" FOREIGN KEY ("user_id") REFERENCES "users"("_id") ON DELETE CASCADE
|
|
121
|
-
)
|
|
110
|
+
await pool.query(`
|
|
111
|
+
CREATE TABLE IF NOT EXISTS "refresh_tokens" (
|
|
112
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
113
|
+
${orgColumnDef}
|
|
114
|
+
"token" VARCHAR(255) NOT NULL,
|
|
115
|
+
"device_id" VARCHAR(255) NOT NULL,
|
|
116
|
+
"user_id" INTEGER NOT NULL,
|
|
117
|
+
"expires_on" BIGINT NOT NULL,
|
|
118
|
+
"created" TIMESTAMPTZ NOT NULL,
|
|
119
|
+
"created_by" INTEGER NOT NULL,
|
|
120
|
+
CONSTRAINT "fk_refresh_tokens_user" FOREIGN KEY ("user_id") REFERENCES "users"("_id") ON DELETE CASCADE
|
|
121
|
+
)
|
|
122
122
|
`);
|
|
123
123
|
},
|
|
124
124
|
down: async ({ context: pool }) => {
|
|
@@ -133,21 +133,21 @@ export const getPostgresInitialSchema = (dbConfig) => {
|
|
|
133
133
|
const uniqueConstraint = isMultiTenant
|
|
134
134
|
? 'CONSTRAINT "uk_passwordResetTokens_email" UNIQUE ("_orgId", "email")'
|
|
135
135
|
: 'CONSTRAINT "uk_passwordResetTokens_email" UNIQUE ("email")';
|
|
136
|
-
await pool.query(`
|
|
137
|
-
CREATE TABLE IF NOT EXISTS "password_reset_tokens" (
|
|
138
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
139
|
-
${orgColumnDef}
|
|
140
|
-
"email" VARCHAR(255) NOT NULL,
|
|
141
|
-
"token" VARCHAR(255) NOT NULL,
|
|
142
|
-
"expires_on" BIGINT NOT NULL,
|
|
143
|
-
"_created" TIMESTAMPTZ NOT NULL,
|
|
144
|
-
"_createdBy" INTEGER NOT NULL,
|
|
145
|
-
"_updated" TIMESTAMPTZ NOT NULL,
|
|
146
|
-
"_updatedBy" INTEGER NOT NULL,
|
|
147
|
-
"_deleted" TIMESTAMPTZ,
|
|
148
|
-
"_deletedBy" INTEGER,
|
|
149
|
-
${uniqueConstraint}
|
|
150
|
-
)
|
|
136
|
+
await pool.query(`
|
|
137
|
+
CREATE TABLE IF NOT EXISTS "password_reset_tokens" (
|
|
138
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
139
|
+
${orgColumnDef}
|
|
140
|
+
"email" VARCHAR(255) NOT NULL,
|
|
141
|
+
"token" VARCHAR(255) NOT NULL,
|
|
142
|
+
"expires_on" BIGINT NOT NULL,
|
|
143
|
+
"_created" TIMESTAMPTZ NOT NULL,
|
|
144
|
+
"_createdBy" INTEGER NOT NULL,
|
|
145
|
+
"_updated" TIMESTAMPTZ NOT NULL,
|
|
146
|
+
"_updatedBy" INTEGER NOT NULL,
|
|
147
|
+
"_deleted" TIMESTAMPTZ,
|
|
148
|
+
"_deletedBy" INTEGER,
|
|
149
|
+
${uniqueConstraint}
|
|
150
|
+
)
|
|
151
151
|
`);
|
|
152
152
|
},
|
|
153
153
|
down: async ({ context: pool }) => {
|
|
@@ -162,14 +162,14 @@ export const getPostgresInitialSchema = (dbConfig) => {
|
|
|
162
162
|
const uniqueConstraint = isMultiTenant
|
|
163
163
|
? 'CONSTRAINT "uk_roles_name" UNIQUE ("_orgId", "name")'
|
|
164
164
|
: 'CONSTRAINT "uk_roles_name" UNIQUE ("name")';
|
|
165
|
-
await pool.query(`
|
|
166
|
-
CREATE TABLE IF NOT EXISTS "roles" (
|
|
167
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
168
|
-
${orgColumnDef}
|
|
169
|
-
"name" VARCHAR(255) NOT NULL,
|
|
170
|
-
"description" TEXT,
|
|
171
|
-
${uniqueConstraint}
|
|
172
|
-
)
|
|
165
|
+
await pool.query(`
|
|
166
|
+
CREATE TABLE IF NOT EXISTS "roles" (
|
|
167
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
168
|
+
${orgColumnDef}
|
|
169
|
+
"name" VARCHAR(255) NOT NULL,
|
|
170
|
+
"description" TEXT,
|
|
171
|
+
${uniqueConstraint}
|
|
172
|
+
)
|
|
173
173
|
`);
|
|
174
174
|
},
|
|
175
175
|
down: async ({ context: pool }) => {
|
|
@@ -184,22 +184,22 @@ export const getPostgresInitialSchema = (dbConfig) => {
|
|
|
184
184
|
const uniqueConstraint = isMultiTenant
|
|
185
185
|
? 'CONSTRAINT "uk_user_roles" UNIQUE ("_orgId", "user_id", "role_id")'
|
|
186
186
|
: 'CONSTRAINT "uk_user_roles" UNIQUE ("user_id", "role_id")';
|
|
187
|
-
await pool.query(`
|
|
188
|
-
CREATE TABLE IF NOT EXISTS "user_roles" (
|
|
189
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
190
|
-
${orgColumnDef}
|
|
191
|
-
"user_id" INTEGER NOT NULL,
|
|
192
|
-
"role_id" INTEGER NOT NULL,
|
|
193
|
-
"_created" TIMESTAMPTZ NOT NULL,
|
|
194
|
-
"_createdBy" INTEGER NOT NULL,
|
|
195
|
-
"_updated" TIMESTAMPTZ NOT NULL,
|
|
196
|
-
"_updatedBy" INTEGER NOT NULL,
|
|
197
|
-
"_deleted" TIMESTAMPTZ,
|
|
198
|
-
"_deletedBy" INTEGER,
|
|
199
|
-
CONSTRAINT "fk_user_roles_user" FOREIGN KEY ("user_id") REFERENCES "users"("_id") ON DELETE CASCADE,
|
|
200
|
-
CONSTRAINT "fk_user_roles_role" FOREIGN KEY ("role_id") REFERENCES "roles"("_id") ON DELETE CASCADE,
|
|
201
|
-
${uniqueConstraint}
|
|
202
|
-
)
|
|
187
|
+
await pool.query(`
|
|
188
|
+
CREATE TABLE IF NOT EXISTS "user_roles" (
|
|
189
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
190
|
+
${orgColumnDef}
|
|
191
|
+
"user_id" INTEGER NOT NULL,
|
|
192
|
+
"role_id" INTEGER NOT NULL,
|
|
193
|
+
"_created" TIMESTAMPTZ NOT NULL,
|
|
194
|
+
"_createdBy" INTEGER NOT NULL,
|
|
195
|
+
"_updated" TIMESTAMPTZ NOT NULL,
|
|
196
|
+
"_updatedBy" INTEGER NOT NULL,
|
|
197
|
+
"_deleted" TIMESTAMPTZ,
|
|
198
|
+
"_deletedBy" INTEGER,
|
|
199
|
+
CONSTRAINT "fk_user_roles_user" FOREIGN KEY ("user_id") REFERENCES "users"("_id") ON DELETE CASCADE,
|
|
200
|
+
CONSTRAINT "fk_user_roles_role" FOREIGN KEY ("role_id") REFERENCES "roles"("_id") ON DELETE CASCADE,
|
|
201
|
+
${uniqueConstraint}
|
|
202
|
+
)
|
|
203
203
|
`);
|
|
204
204
|
},
|
|
205
205
|
down: async ({ context: pool }) => {
|
|
@@ -214,14 +214,14 @@ export const getPostgresInitialSchema = (dbConfig) => {
|
|
|
214
214
|
const uniqueConstraint = isMultiTenant
|
|
215
215
|
? 'CONSTRAINT "uk_features" UNIQUE ("_orgId", "name")'
|
|
216
216
|
: 'CONSTRAINT "uk_features" UNIQUE ("name")';
|
|
217
|
-
await pool.query(`
|
|
218
|
-
CREATE TABLE IF NOT EXISTS "features" (
|
|
219
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
220
|
-
${orgColumnDef}
|
|
221
|
-
"name" VARCHAR(255) NOT NULL,
|
|
222
|
-
"description" TEXT,
|
|
223
|
-
${uniqueConstraint}
|
|
224
|
-
)
|
|
217
|
+
await pool.query(`
|
|
218
|
+
CREATE TABLE IF NOT EXISTS "features" (
|
|
219
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
220
|
+
${orgColumnDef}
|
|
221
|
+
"name" VARCHAR(255) NOT NULL,
|
|
222
|
+
"description" TEXT,
|
|
223
|
+
${uniqueConstraint}
|
|
224
|
+
)
|
|
225
225
|
`);
|
|
226
226
|
},
|
|
227
227
|
down: async ({ context: pool }) => {
|
|
@@ -236,25 +236,25 @@ export const getPostgresInitialSchema = (dbConfig) => {
|
|
|
236
236
|
const uniqueConstraint = isMultiTenant
|
|
237
237
|
? 'CONSTRAINT "uk_authorizations" UNIQUE ("_orgId", "role_id", "feature_id")'
|
|
238
238
|
: 'CONSTRAINT "uk_authorizations" UNIQUE ("role_id", "feature_id")';
|
|
239
|
-
await pool.query(`
|
|
240
|
-
CREATE TABLE IF NOT EXISTS "authorizations" (
|
|
241
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
242
|
-
${orgColumnDef}
|
|
243
|
-
"role_id" INTEGER NOT NULL,
|
|
244
|
-
"feature_id" INTEGER NOT NULL,
|
|
245
|
-
"start_date" TIMESTAMPTZ,
|
|
246
|
-
"end_date" TIMESTAMPTZ,
|
|
247
|
-
"config" JSONB,
|
|
248
|
-
"_created" TIMESTAMPTZ NOT NULL,
|
|
249
|
-
"_createdBy" INTEGER NOT NULL,
|
|
250
|
-
"_updated" TIMESTAMPTZ NOT NULL,
|
|
251
|
-
"_updatedBy" INTEGER NOT NULL,
|
|
252
|
-
"_deleted" TIMESTAMPTZ,
|
|
253
|
-
"_deletedBy" INTEGER,
|
|
254
|
-
CONSTRAINT "fk_authorizations_role" FOREIGN KEY ("role_id") REFERENCES "roles"("_id") ON DELETE CASCADE,
|
|
255
|
-
CONSTRAINT "fk_authorizations_feature" FOREIGN KEY ("feature_id") REFERENCES "features"("_id") ON DELETE CASCADE,
|
|
256
|
-
${uniqueConstraint}
|
|
257
|
-
)
|
|
239
|
+
await pool.query(`
|
|
240
|
+
CREATE TABLE IF NOT EXISTS "authorizations" (
|
|
241
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
242
|
+
${orgColumnDef}
|
|
243
|
+
"role_id" INTEGER NOT NULL,
|
|
244
|
+
"feature_id" INTEGER NOT NULL,
|
|
245
|
+
"start_date" TIMESTAMPTZ,
|
|
246
|
+
"end_date" TIMESTAMPTZ,
|
|
247
|
+
"config" JSONB,
|
|
248
|
+
"_created" TIMESTAMPTZ NOT NULL,
|
|
249
|
+
"_createdBy" INTEGER NOT NULL,
|
|
250
|
+
"_updated" TIMESTAMPTZ NOT NULL,
|
|
251
|
+
"_updatedBy" INTEGER NOT NULL,
|
|
252
|
+
"_deleted" TIMESTAMPTZ,
|
|
253
|
+
"_deletedBy" INTEGER,
|
|
254
|
+
CONSTRAINT "fk_authorizations_role" FOREIGN KEY ("role_id") REFERENCES "roles"("_id") ON DELETE CASCADE,
|
|
255
|
+
CONSTRAINT "fk_authorizations_feature" FOREIGN KEY ("feature_id") REFERENCES "features"("_id") ON DELETE CASCADE,
|
|
256
|
+
${uniqueConstraint}
|
|
257
|
+
)
|
|
258
258
|
`);
|
|
259
259
|
},
|
|
260
260
|
down: async ({ context: pool }) => {
|
|
@@ -265,10 +265,10 @@ export const getPostgresInitialSchema = (dbConfig) => {
|
|
|
265
265
|
migrations.push({
|
|
266
266
|
name: '00000000000010_data-meta-org',
|
|
267
267
|
up: async ({ context: pool }) => {
|
|
268
|
-
const result = await pool.query(`
|
|
269
|
-
INSERT INTO "organizations" ("name", "code", "status", "is_meta_org", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
270
|
-
VALUES ($1, $2, 1, true, NOW(), 0, NOW(), 0)
|
|
271
|
-
RETURNING "_id", "name", "code", "status", "is_meta_org", "_created", "_createdBy", "_updated", "_updatedBy"
|
|
268
|
+
const result = await pool.query(`
|
|
269
|
+
INSERT INTO "organizations" ("name", "code", "status", "is_meta_org", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
270
|
+
VALUES ($1, $2, 1, true, NOW(), 0, NOW(), 0)
|
|
271
|
+
RETURNING "_id", "name", "code", "status", "is_meta_org", "_created", "_createdBy", "_updated", "_updatedBy"
|
|
272
272
|
`, [dbConfig.multiTenant?.metaOrgName, dbConfig.multiTenant?.metaOrgCode]);
|
|
273
273
|
if (result.rowCount === 0) {
|
|
274
274
|
throw new Error('Failed to create meta organization');
|
|
@@ -299,19 +299,19 @@ export const getPostgresInitialSchema = (dbConfig) => {
|
|
|
299
299
|
const client = await pool.connect();
|
|
300
300
|
try {
|
|
301
301
|
const personResult = isMultiTenant && orgId
|
|
302
|
-
? await client.query(`INSERT INTO "persons" ("_orgId", "first_name", "last_name", "is_agent", "is_client", "is_employee", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
303
|
-
VALUES ($1, 'Admin', 'User', false, false, false, NOW(), 0, NOW(), 0)
|
|
302
|
+
? await client.query(`INSERT INTO "persons" ("_orgId", "first_name", "last_name", "is_agent", "is_client", "is_employee", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
303
|
+
VALUES ($1, 'Admin', 'User', false, false, false, NOW(), 0, NOW(), 0)
|
|
304
304
|
RETURNING "_id"`, [orgId])
|
|
305
|
-
: await client.query(`INSERT INTO "persons" ("first_name", "last_name", "is_agent", "is_client", "is_employee", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
306
|
-
VALUES ('Admin', 'User', false, false, false, NOW(), 0, NOW(), 0)
|
|
305
|
+
: await client.query(`INSERT INTO "persons" ("first_name", "last_name", "is_agent", "is_client", "is_employee", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
306
|
+
VALUES ('Admin', 'User', false, false, false, NOW(), 0, NOW(), 0)
|
|
307
307
|
RETURNING "_id"`);
|
|
308
308
|
const personId = personResult.rows[0]._id;
|
|
309
309
|
if (isMultiTenant && orgId) {
|
|
310
|
-
await client.query(`INSERT INTO "users" ("_orgId", "email", "display_name", "password", "person_id", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
310
|
+
await client.query(`INSERT INTO "users" ("_orgId", "email", "display_name", "password", "person_id", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
311
311
|
VALUES ($1, $2, 'Admin User', $3, $4, NOW(), 0, NOW(), 0)`, [orgId, email, hashedPassword, personId]);
|
|
312
312
|
}
|
|
313
313
|
else {
|
|
314
|
-
await client.query(`INSERT INTO "users" ("email", "display_name", "password", "person_id", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
314
|
+
await client.query(`INSERT INTO "users" ("email", "display_name", "password", "person_id", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
315
315
|
VALUES ($1, 'Admin User', $2, $3, NOW(), 0, NOW(), 0)`, [email, hashedPassword, personId]);
|
|
316
316
|
}
|
|
317
317
|
}
|
|
@@ -348,61 +348,61 @@ export const getPostgresInitialSchema = (dbConfig) => {
|
|
|
348
348
|
await client.query('BEGIN');
|
|
349
349
|
try {
|
|
350
350
|
const roleResult = isMultiTenant
|
|
351
|
-
? await client.query(`
|
|
352
|
-
INSERT INTO "roles" ("_orgId", "name")
|
|
353
|
-
VALUES ($1, 'admin')
|
|
354
|
-
RETURNING "_id"
|
|
351
|
+
? await client.query(`
|
|
352
|
+
INSERT INTO "roles" ("_orgId", "name")
|
|
353
|
+
VALUES ($1, 'admin')
|
|
354
|
+
RETURNING "_id"
|
|
355
355
|
`, [metaOrg._id])
|
|
356
|
-
: await client.query(`
|
|
357
|
-
INSERT INTO "roles" ("name")
|
|
358
|
-
VALUES ('admin')
|
|
359
|
-
RETURNING "_id"
|
|
356
|
+
: await client.query(`
|
|
357
|
+
INSERT INTO "roles" ("name")
|
|
358
|
+
VALUES ('admin')
|
|
359
|
+
RETURNING "_id"
|
|
360
360
|
`);
|
|
361
361
|
if (roleResult.rowCount === 0) {
|
|
362
362
|
throw new Error('Failed to create admin role');
|
|
363
363
|
}
|
|
364
364
|
const roleId = roleResult.rows[0]._id;
|
|
365
365
|
const userRoleResult = isMultiTenant
|
|
366
|
-
? await client.query(`
|
|
367
|
-
INSERT INTO "user_roles" ("_orgId", "user_id", "role_id", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
368
|
-
VALUES ($1, $2, $3, NOW(), 0, NOW(), 0)
|
|
366
|
+
? await client.query(`
|
|
367
|
+
INSERT INTO "user_roles" ("_orgId", "user_id", "role_id", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
368
|
+
VALUES ($1, $2, $3, NOW(), 0, NOW(), 0)
|
|
369
369
|
`, [metaOrg._id, adminUserId, roleId])
|
|
370
|
-
: await client.query(`
|
|
371
|
-
INSERT INTO "user_roles" ("user_id", "role_id", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
372
|
-
VALUES ($1, $2, NOW(), 0, NOW(), 0)
|
|
370
|
+
: await client.query(`
|
|
371
|
+
INSERT INTO "user_roles" ("user_id", "role_id", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
372
|
+
VALUES ($1, $2, NOW(), 0, NOW(), 0)
|
|
373
373
|
`, [adminUserId, roleId]);
|
|
374
374
|
if (userRoleResult.rowCount === 0) {
|
|
375
375
|
throw new Error('Failed to create user role');
|
|
376
376
|
}
|
|
377
377
|
const featureResult = isMultiTenant
|
|
378
|
-
? await client.query(`
|
|
379
|
-
INSERT INTO "features" ("_orgId", "name")
|
|
380
|
-
VALUES ($1, 'admin')
|
|
381
|
-
RETURNING "_id"
|
|
378
|
+
? await client.query(`
|
|
379
|
+
INSERT INTO "features" ("_orgId", "name")
|
|
380
|
+
VALUES ($1, 'admin')
|
|
381
|
+
RETURNING "_id"
|
|
382
382
|
`, [metaOrg._id])
|
|
383
|
-
: await client.query(`
|
|
384
|
-
INSERT INTO "features" ("name")
|
|
385
|
-
VALUES ('admin')
|
|
386
|
-
RETURNING "_id"
|
|
383
|
+
: await client.query(`
|
|
384
|
+
INSERT INTO "features" ("name")
|
|
385
|
+
VALUES ('admin')
|
|
386
|
+
RETURNING "_id"
|
|
387
387
|
`);
|
|
388
388
|
if (featureResult.rowCount === 0) {
|
|
389
389
|
throw new Error('Failed to create admin feature');
|
|
390
390
|
}
|
|
391
391
|
const featureId = featureResult.rows[0]._id;
|
|
392
392
|
const authorizationResult = isMultiTenant
|
|
393
|
-
? await client.query(`
|
|
394
|
-
INSERT INTO "authorizations" (
|
|
395
|
-
"_orgId", "role_id", "feature_id",
|
|
396
|
-
"_created", "_createdBy", "_updated", "_updatedBy"
|
|
397
|
-
)
|
|
398
|
-
VALUES ($1, $2, $3, NOW(), 0, NOW(), 0)
|
|
393
|
+
? await client.query(`
|
|
394
|
+
INSERT INTO "authorizations" (
|
|
395
|
+
"_orgId", "role_id", "feature_id",
|
|
396
|
+
"_created", "_createdBy", "_updated", "_updatedBy"
|
|
397
|
+
)
|
|
398
|
+
VALUES ($1, $2, $3, NOW(), 0, NOW(), 0)
|
|
399
399
|
`, [metaOrg._id, roleId, featureId])
|
|
400
|
-
: await client.query(`
|
|
401
|
-
INSERT INTO "authorizations" (
|
|
402
|
-
"role_id", "feature_id",
|
|
403
|
-
"_created", "_createdBy", "_updated", "_updatedBy"
|
|
404
|
-
)
|
|
405
|
-
VALUES ($1, $2, NOW(), 0, NOW(), 0)
|
|
400
|
+
: await client.query(`
|
|
401
|
+
INSERT INTO "authorizations" (
|
|
402
|
+
"role_id", "feature_id",
|
|
403
|
+
"_created", "_createdBy", "_updated", "_updatedBy"
|
|
404
|
+
)
|
|
405
|
+
VALUES ($1, $2, NOW(), 0, NOW(), 0)
|
|
406
406
|
`, [roleId, featureId]);
|
|
407
407
|
if (authorizationResult.rowCount === 0) {
|
|
408
408
|
throw new Error('Failed to create admin authorization');
|
|
@@ -429,61 +429,61 @@ export const getPostgresInitialSchema = (dbConfig) => {
|
|
|
429
429
|
await client.query('BEGIN');
|
|
430
430
|
try {
|
|
431
431
|
if (isMultiTenant) {
|
|
432
|
-
await client.query(`
|
|
433
|
-
DELETE FROM "authorizations"
|
|
434
|
-
WHERE "_orgId" = $1
|
|
435
|
-
AND "feature_id" IN (
|
|
436
|
-
SELECT "_id" FROM "features"
|
|
437
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
438
|
-
)
|
|
439
|
-
AND "role_id" IN (
|
|
440
|
-
SELECT "_id" FROM "roles"
|
|
441
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
442
|
-
)
|
|
432
|
+
await client.query(`
|
|
433
|
+
DELETE FROM "authorizations"
|
|
434
|
+
WHERE "_orgId" = $1
|
|
435
|
+
AND "feature_id" IN (
|
|
436
|
+
SELECT "_id" FROM "features"
|
|
437
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
438
|
+
)
|
|
439
|
+
AND "role_id" IN (
|
|
440
|
+
SELECT "_id" FROM "roles"
|
|
441
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
442
|
+
)
|
|
443
443
|
`, [metaOrg._id]);
|
|
444
|
-
await client.query(`
|
|
445
|
-
DELETE FROM "features"
|
|
446
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
444
|
+
await client.query(`
|
|
445
|
+
DELETE FROM "features"
|
|
446
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
447
447
|
`, [metaOrg._id]);
|
|
448
|
-
await client.query(`
|
|
449
|
-
DELETE FROM "user_roles"
|
|
450
|
-
WHERE "_orgId" = $1
|
|
451
|
-
AND "role_id" IN (
|
|
452
|
-
SELECT "_id" FROM "roles"
|
|
453
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
454
|
-
)
|
|
448
|
+
await client.query(`
|
|
449
|
+
DELETE FROM "user_roles"
|
|
450
|
+
WHERE "_orgId" = $1
|
|
451
|
+
AND "role_id" IN (
|
|
452
|
+
SELECT "_id" FROM "roles"
|
|
453
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
454
|
+
)
|
|
455
455
|
`, [metaOrg._id]);
|
|
456
|
-
await client.query(`
|
|
457
|
-
DELETE FROM "roles"
|
|
458
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
456
|
+
await client.query(`
|
|
457
|
+
DELETE FROM "roles"
|
|
458
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
459
459
|
`, [metaOrg._id]);
|
|
460
460
|
}
|
|
461
461
|
else {
|
|
462
|
-
await client.query(`
|
|
463
|
-
DELETE FROM "authorizations"
|
|
464
|
-
WHERE "feature_id" IN (
|
|
465
|
-
SELECT "_id" FROM "features"
|
|
466
|
-
WHERE "name" = 'admin'
|
|
467
|
-
)
|
|
468
|
-
AND "role_id" IN (
|
|
469
|
-
SELECT "_id" FROM "roles"
|
|
470
|
-
WHERE "name" = 'admin'
|
|
471
|
-
)
|
|
462
|
+
await client.query(`
|
|
463
|
+
DELETE FROM "authorizations"
|
|
464
|
+
WHERE "feature_id" IN (
|
|
465
|
+
SELECT "_id" FROM "features"
|
|
466
|
+
WHERE "name" = 'admin'
|
|
467
|
+
)
|
|
468
|
+
AND "role_id" IN (
|
|
469
|
+
SELECT "_id" FROM "roles"
|
|
470
|
+
WHERE "name" = 'admin'
|
|
471
|
+
)
|
|
472
472
|
`);
|
|
473
|
-
await client.query(`
|
|
474
|
-
DELETE FROM "features"
|
|
475
|
-
WHERE "name" = 'admin'
|
|
473
|
+
await client.query(`
|
|
474
|
+
DELETE FROM "features"
|
|
475
|
+
WHERE "name" = 'admin'
|
|
476
476
|
`);
|
|
477
|
-
await client.query(`
|
|
478
|
-
DELETE FROM "user_roles"
|
|
479
|
-
WHERE "role_id" IN (
|
|
480
|
-
SELECT "_id" FROM "roles"
|
|
481
|
-
WHERE "name" = 'admin'
|
|
482
|
-
)
|
|
477
|
+
await client.query(`
|
|
478
|
+
DELETE FROM "user_roles"
|
|
479
|
+
WHERE "role_id" IN (
|
|
480
|
+
SELECT "_id" FROM "roles"
|
|
481
|
+
WHERE "name" = 'admin'
|
|
482
|
+
)
|
|
483
483
|
`);
|
|
484
|
-
await client.query(`
|
|
485
|
-
DELETE FROM "roles"
|
|
486
|
-
WHERE "name" = 'admin'
|
|
484
|
+
await client.query(`
|
|
485
|
+
DELETE FROM "roles"
|
|
486
|
+
WHERE "name" = 'admin'
|
|
487
487
|
`);
|
|
488
488
|
}
|
|
489
489
|
await client.query('COMMIT');
|
|
@@ -70,23 +70,23 @@ export class PostgresDatabase {
|
|
|
70
70
|
}
|
|
71
71
|
async getUserAuthorizations(userId, orgId) {
|
|
72
72
|
const now = new Date();
|
|
73
|
-
let query = `
|
|
74
|
-
SELECT DISTINCT
|
|
75
|
-
ur."user_id" as "userId",
|
|
76
|
-
r."name" as "role",
|
|
77
|
-
f."name" as "feature",
|
|
78
|
-
a."config",
|
|
79
|
-
a."_id",
|
|
80
|
-
a."_orgId"
|
|
81
|
-
FROM "user_roles" ur
|
|
82
|
-
INNER JOIN "roles" r ON ur."role_id" = r."_id"
|
|
83
|
-
INNER JOIN "authorizations" a ON r."_id" = a."role_id"
|
|
84
|
-
INNER JOIN "features" f ON a."feature_id" = f."_id"
|
|
85
|
-
WHERE ur."user_id" = $1
|
|
86
|
-
AND ur."_deleted" IS NULL
|
|
87
|
-
AND a."_deleted" IS NULL
|
|
88
|
-
AND (a."start_date" IS NULL OR a."start_date" <= $2)
|
|
89
|
-
AND (a."end_date" IS NULL OR a."end_date" >= $2)
|
|
73
|
+
let query = `
|
|
74
|
+
SELECT DISTINCT
|
|
75
|
+
ur."user_id" as "userId",
|
|
76
|
+
r."name" as "role",
|
|
77
|
+
f."name" as "feature",
|
|
78
|
+
a."config",
|
|
79
|
+
a."_id",
|
|
80
|
+
a."_orgId"
|
|
81
|
+
FROM "user_roles" ur
|
|
82
|
+
INNER JOIN "roles" r ON ur."role_id" = r."_id"
|
|
83
|
+
INNER JOIN "authorizations" a ON r."_id" = a."role_id"
|
|
84
|
+
INNER JOIN "features" f ON a."feature_id" = f."_id"
|
|
85
|
+
WHERE ur."user_id" = $1
|
|
86
|
+
AND ur."_deleted" IS NULL
|
|
87
|
+
AND a."_deleted" IS NULL
|
|
88
|
+
AND (a."start_date" IS NULL OR a."start_date" <= $2)
|
|
89
|
+
AND (a."end_date" IS NULL OR a."end_date" >= $2)
|
|
90
90
|
`;
|
|
91
91
|
const values = [userId, now];
|
|
92
92
|
if (orgId) {
|