@loomcore/api 0.1.38 → 0.1.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.
Files changed (42) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +49 -49
  3. package/dist/__tests__/common-test.utils.js +2 -11
  4. package/dist/__tests__/postgres-test-migrations/100-create-test-entities-table.migration.js +22 -22
  5. package/dist/__tests__/postgres-test-migrations/101-create-categories-table.migration.js +12 -12
  6. package/dist/__tests__/postgres-test-migrations/102-create-products-table.migration.js +21 -21
  7. package/dist/__tests__/postgres-test-migrations/103-create-test-items-table.migration.js +20 -20
  8. package/dist/__tests__/postgres.test-database.js +8 -8
  9. package/dist/controllers/api.controller.js +10 -10
  10. package/dist/controllers/auth.controller.js +4 -4
  11. package/dist/controllers/organizations.controller.js +3 -3
  12. package/dist/controllers/users.controller.js +9 -9
  13. package/dist/databases/migrations/migration-runner.d.ts +1 -0
  14. package/dist/databases/migrations/migration-runner.js +6 -0
  15. package/dist/databases/postgres/commands/postgres-batch-update.command.js +7 -7
  16. package/dist/databases/postgres/commands/postgres-create-many.command.js +10 -10
  17. package/dist/databases/postgres/commands/postgres-create.command.js +4 -4
  18. package/dist/databases/postgres/commands/postgres-full-update-by-id.command.js +13 -13
  19. package/dist/databases/postgres/commands/postgres-partial-update-by-id.command.js +7 -7
  20. package/dist/databases/postgres/commands/postgres-update.command.js +7 -7
  21. package/dist/databases/postgres/migrations/001-create-migrations-table.migration.js +12 -12
  22. package/dist/databases/postgres/migrations/002-create-organizations-table.migration.js +24 -24
  23. package/dist/databases/postgres/migrations/003-create-users-table.migration.js +26 -26
  24. package/dist/databases/postgres/migrations/004-create-refresh-tokens-table.migration.js +18 -18
  25. package/dist/databases/postgres/migrations/005-create-meta-org.migration.js +9 -9
  26. package/dist/databases/postgres/migrations/006-create-admin-user.migration.js +3 -3
  27. package/dist/databases/postgres/migrations/007-create-roles-table.migration.js +14 -14
  28. package/dist/databases/postgres/migrations/008-create-user-roles-table.migration.js +24 -24
  29. package/dist/databases/postgres/migrations/009-create-features-table.migration.js +14 -14
  30. package/dist/databases/postgres/migrations/010-create-authorizations-table.migration.js +26 -26
  31. package/dist/databases/postgres/migrations/011-create-admin-authorization.migration.js +44 -44
  32. package/dist/databases/postgres/migrations/database-builder.js +4 -4
  33. package/dist/databases/postgres/postgres.database.js +17 -17
  34. package/dist/databases/postgres/utils/build-select-clause.js +6 -6
  35. package/dist/databases/postgres/utils/does-table-exist.util.js +4 -4
  36. package/dist/middleware/index.d.ts +1 -1
  37. package/dist/middleware/index.js +1 -1
  38. package/dist/middleware/is-authorized.d.ts +3 -0
  39. package/dist/middleware/is-authorized.js +40 -0
  40. package/package.json +88 -88
  41. package/dist/middleware/is-authenticated.d.ts +0 -2
  42. package/dist/middleware/is-authenticated.js +0 -27
@@ -12,27 +12,27 @@ export class CreateOrganizationsTableMigration {
12
12
  await this.client.query('BEGIN');
13
13
  const tableExists = await doesTableExist(this.client, 'organizations');
14
14
  if (!tableExists) {
15
- await this.client.query(`
16
- CREATE TABLE "organizations" (
17
- "_id" VARCHAR(255) PRIMARY KEY,
18
- "name" VARCHAR(255) NOT NULL UNIQUE,
19
- "code" VARCHAR(255) NOT NULL UNIQUE,
20
- "description" TEXT,
21
- "status" INTEGER NOT NULL,
22
- "isMetaOrg" BOOLEAN NOT NULL,
23
- "authToken" TEXT,
24
- "_created" TIMESTAMP NOT NULL,
25
- "_createdBy" VARCHAR(255) NOT NULL,
26
- "_updated" TIMESTAMP NOT NULL,
27
- "_updatedBy" VARCHAR(255) NOT NULL,
28
- "_deleted" TIMESTAMP,
29
- "_deletedBy" VARCHAR(255)
30
- )
15
+ await this.client.query(`
16
+ CREATE TABLE "organizations" (
17
+ "_id" VARCHAR(255) PRIMARY KEY,
18
+ "name" VARCHAR(255) NOT NULL UNIQUE,
19
+ "code" VARCHAR(255) NOT NULL UNIQUE,
20
+ "description" TEXT,
21
+ "status" INTEGER NOT NULL,
22
+ "isMetaOrg" BOOLEAN NOT NULL,
23
+ "authToken" TEXT,
24
+ "_created" TIMESTAMP NOT NULL,
25
+ "_createdBy" VARCHAR(255) NOT NULL,
26
+ "_updated" TIMESTAMP NOT NULL,
27
+ "_updatedBy" VARCHAR(255) NOT NULL,
28
+ "_deleted" TIMESTAMP,
29
+ "_deletedBy" VARCHAR(255)
30
+ )
31
31
  `);
32
32
  }
33
- const result = await this.client.query(`
34
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
35
- VALUES ('${_id}', ${this.index}, TRUE, FALSE);
33
+ const result = await this.client.query(`
34
+ INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
35
+ VALUES ('${_id}', ${this.index}, TRUE, FALSE);
36
36
  `);
37
37
  if (result.rowCount === 0) {
38
38
  await this.client.query('ROLLBACK');
@@ -51,17 +51,17 @@ export class CreateOrganizationsTableMigration {
51
51
  await this.client.query('BEGIN');
52
52
  const tableExists = await doesTableExist(this.client, 'organizations');
53
53
  if (tableExists) {
54
- await this.client.query(`
55
- DROP TABLE "organizations";
54
+ await this.client.query(`
55
+ DROP TABLE "organizations";
56
56
  `);
57
57
  }
58
- const updateResult = await this.client.query(`
59
- UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
58
+ const updateResult = await this.client.query(`
59
+ UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
60
60
  `);
61
61
  if (updateResult.rowCount === 0) {
62
62
  await this.client.query('ROLLBACK');
63
63
  return {
64
- success: false, error: new Error(`Error updating migration record for index ${this.index}: Migration record not found.
64
+ success: false, error: new Error(`Error updating migration record for index ${this.index}: Migration record not found.
65
65
  Migration index: ${this.index}`)
66
66
  };
67
67
  }
@@ -16,30 +16,30 @@ export class CreateUsersTableMigration {
16
16
  const fkConstraint = config.app.isMultiTenant
17
17
  ? ',\n CONSTRAINT "fk_users_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE'
18
18
  : '';
19
- await this.client.query(`
20
- CREATE TABLE "users" (
21
- "_id" VARCHAR(255) PRIMARY KEY,
22
- "_orgId" VARCHAR(255),
23
- "email" VARCHAR(255) NOT NULL,
24
- "firstName" VARCHAR(255),
25
- "lastName" VARCHAR(255),
26
- "displayName" VARCHAR(255),
27
- "password" VARCHAR(255) NOT NULL,
28
- "_lastLoggedIn" TIMESTAMP,
29
- "_lastPasswordChange" TIMESTAMP,
30
- "_created" TIMESTAMP NOT NULL,
31
- "_createdBy" VARCHAR(255) NOT NULL,
32
- "_updated" TIMESTAMP NOT NULL,
33
- "_updatedBy" VARCHAR(255) NOT NULL,
34
- "_deleted" TIMESTAMP,
35
- "_deletedBy" VARCHAR(255),
36
- CONSTRAINT "uk_users_email" UNIQUE ("_orgId", "email")${fkConstraint}
37
- )
19
+ await this.client.query(`
20
+ CREATE TABLE "users" (
21
+ "_id" VARCHAR(255) PRIMARY KEY,
22
+ "_orgId" VARCHAR(255),
23
+ "email" VARCHAR(255) NOT NULL,
24
+ "firstName" VARCHAR(255),
25
+ "lastName" VARCHAR(255),
26
+ "displayName" VARCHAR(255),
27
+ "password" VARCHAR(255) NOT NULL,
28
+ "_lastLoggedIn" TIMESTAMP,
29
+ "_lastPasswordChange" TIMESTAMP,
30
+ "_created" TIMESTAMP NOT NULL,
31
+ "_createdBy" VARCHAR(255) NOT NULL,
32
+ "_updated" TIMESTAMP NOT NULL,
33
+ "_updatedBy" VARCHAR(255) NOT NULL,
34
+ "_deleted" TIMESTAMP,
35
+ "_deletedBy" VARCHAR(255),
36
+ CONSTRAINT "uk_users_email" UNIQUE ("_orgId", "email")${fkConstraint}
37
+ )
38
38
  `);
39
39
  }
40
- const result = await this.client.query(`
41
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
42
- VALUES ('${_id}', ${this.index}, TRUE, FALSE);
40
+ const result = await this.client.query(`
41
+ INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
42
+ VALUES ('${_id}', ${this.index}, TRUE, FALSE);
43
43
  `);
44
44
  if (result.rowCount === 0) {
45
45
  await this.client.query('ROLLBACK');
@@ -56,11 +56,11 @@ export class CreateUsersTableMigration {
56
56
  async revert() {
57
57
  try {
58
58
  await this.client.query('BEGIN');
59
- await this.client.query(`
60
- DROP TABLE "users";
59
+ await this.client.query(`
60
+ DROP TABLE "users";
61
61
  `);
62
- const updateResult = await this.client.query(`
63
- UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
62
+ const updateResult = await this.client.query(`
63
+ UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
64
64
  `);
65
65
  if (updateResult.rowCount === 0) {
66
66
  await this.client.query('ROLLBACK');
@@ -16,22 +16,22 @@ export class CreateRefreshTokenTableMigration {
16
16
  const fkConstraint = config.app.isMultiTenant
17
17
  ? ',\n CONSTRAINT "fk_refreshTokens_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE'
18
18
  : '';
19
- await this.client.query(`
20
- CREATE TABLE "refreshTokens" (
21
- "_id" VARCHAR(255) PRIMARY KEY,
22
- "_orgId" VARCHAR(255),
23
- "token" VARCHAR(255) NOT NULL,
24
- "deviceId" VARCHAR(255) NOT NULL,
25
- "userId" VARCHAR(255) NOT NULL,
26
- "expiresOn" BIGINT NOT NULL,
27
- "created" TIMESTAMP NOT NULL,
28
- "createdBy" VARCHAR(255) NOT NULL${fkConstraint}
29
- )
19
+ await this.client.query(`
20
+ CREATE TABLE "refreshTokens" (
21
+ "_id" VARCHAR(255) PRIMARY KEY,
22
+ "_orgId" VARCHAR(255),
23
+ "token" VARCHAR(255) NOT NULL,
24
+ "deviceId" VARCHAR(255) NOT NULL,
25
+ "userId" VARCHAR(255) NOT NULL,
26
+ "expiresOn" BIGINT NOT NULL,
27
+ "created" TIMESTAMP NOT NULL,
28
+ "createdBy" VARCHAR(255) NOT NULL${fkConstraint}
29
+ )
30
30
  `);
31
31
  }
32
- const result = await this.client.query(`
33
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
34
- VALUES ('${_id}', ${this.index}, TRUE, FALSE);
32
+ const result = await this.client.query(`
33
+ INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
34
+ VALUES ('${_id}', ${this.index}, TRUE, FALSE);
35
35
  `);
36
36
  if (result.rowCount === 0) {
37
37
  await this.client.query('ROLLBACK');
@@ -50,12 +50,12 @@ export class CreateRefreshTokenTableMigration {
50
50
  await this.client.query('BEGIN');
51
51
  const tableExists = await doesTableExist(this.client, 'refreshTokens');
52
52
  if (tableExists) {
53
- await this.client.query(`
54
- DROP TABLE "refreshTokens";
53
+ await this.client.query(`
54
+ DROP TABLE "refreshTokens";
55
55
  `);
56
56
  }
57
- const updateResult = await this.client.query(`
58
- UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
57
+ const updateResult = await this.client.query(`
58
+ UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
59
59
  `);
60
60
  if (updateResult.rowCount === 0) {
61
61
  await this.client.query('ROLLBACK');
@@ -11,19 +11,19 @@ export class CreateMetaOrgMigration {
11
11
  const _id = randomUUID().toString();
12
12
  try {
13
13
  await this.client.query('BEGIN');
14
- const orgResult = await this.client.query(`
15
- INSERT INTO "organizations" ("_id", "name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy")
16
- VALUES ('${_id}', '${config.app.metaOrgName}', '${config.app.metaOrgCode}', 1, true, NOW(), 'system', NOW(), 'system')
17
- RETURNING "_id", "name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy";
14
+ const orgResult = await this.client.query(`
15
+ INSERT INTO "organizations" ("_id", "name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy")
16
+ VALUES ('${_id}', '${config.app.metaOrgName}', '${config.app.metaOrgCode}', 1, true, NOW(), 'system', NOW(), 'system')
17
+ RETURNING "_id", "name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy";
18
18
  `);
19
19
  if (orgResult.rowCount === 0) {
20
20
  await this.client.query('ROLLBACK');
21
21
  return { success: false, error: new Error(`Error creating meta org: No row returned`) };
22
22
  }
23
23
  initializeSystemUserContext(config.email?.systemEmailAddress || 'system@example.com', orgResult.rows[0]);
24
- const migrationResult = await this.client.query(`
25
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
26
- VALUES ('${_id}', ${this.index}, TRUE, FALSE);
24
+ const migrationResult = await this.client.query(`
25
+ INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
26
+ VALUES ('${_id}', ${this.index}, TRUE, FALSE);
27
27
  `);
28
28
  if (migrationResult.rowCount === 0) {
29
29
  await this.client.query('ROLLBACK');
@@ -45,8 +45,8 @@ export class CreateMetaOrgMigration {
45
45
  await this.client.query('ROLLBACK');
46
46
  return { success: false, error: new Error(`Error reverting meta org: No row returned`) };
47
47
  }
48
- const updateResult = await this.client.query(`
49
- UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
48
+ const updateResult = await this.client.query(`
49
+ UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
50
50
  `);
51
51
  if (updateResult.rowCount === 0) {
52
52
  await this.client.query('ROLLBACK');
@@ -31,9 +31,9 @@ export class CreateAdminUserMigration {
31
31
  return { success: false, error: new Error(`Error creating admin user: ${error.message}`) };
32
32
  }
33
33
  try {
34
- const result = await this.client.query(`
35
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
36
- VALUES ('${_id}', ${this.index}, TRUE, FALSE);
34
+ const result = await this.client.query(`
35
+ INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
36
+ VALUES ('${_id}', ${this.index}, TRUE, FALSE);
37
37
  `);
38
38
  if (result.rowCount === 0) {
39
39
  console.error(`Error inserting migration ${this.index} to migrations table: No row returned`);
@@ -16,18 +16,18 @@ export class CreateRoleTableMigration {
16
16
  const fkConstraint = config.app.isMultiTenant
17
17
  ? ',\n CONSTRAINT "fk_roles_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE'
18
18
  : '';
19
- await this.client.query(`
20
- CREATE TABLE "roles" (
21
- "_id" VARCHAR(255) PRIMARY KEY,
22
- "_orgId" VARCHAR(255),
23
- "name" VARCHAR(255) NOT NULL,
24
- CONSTRAINT "uk_roles_name" UNIQUE ("_orgId", "name")${fkConstraint}
25
- )
19
+ await this.client.query(`
20
+ CREATE TABLE "roles" (
21
+ "_id" VARCHAR(255) PRIMARY KEY,
22
+ "_orgId" VARCHAR(255),
23
+ "name" VARCHAR(255) NOT NULL,
24
+ CONSTRAINT "uk_roles_name" UNIQUE ("_orgId", "name")${fkConstraint}
25
+ )
26
26
  `);
27
27
  }
28
- const result = await this.client.query(`
29
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
30
- VALUES ('${_id}', ${this.index}, TRUE, FALSE);
28
+ const result = await this.client.query(`
29
+ INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
30
+ VALUES ('${_id}', ${this.index}, TRUE, FALSE);
31
31
  `);
32
32
  if (result.rowCount === 0) {
33
33
  await this.client.query('ROLLBACK');
@@ -44,11 +44,11 @@ export class CreateRoleTableMigration {
44
44
  async revert() {
45
45
  try {
46
46
  await this.client.query('BEGIN');
47
- await this.client.query(`
48
- DROP TABLE "roles";
47
+ await this.client.query(`
48
+ DROP TABLE "roles";
49
49
  `);
50
- const updateResult = await this.client.query(`
51
- UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
50
+ const updateResult = await this.client.query(`
51
+ UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
52
52
  `);
53
53
  if (updateResult.rowCount === 0) {
54
54
  await this.client.query('ROLLBACK');
@@ -16,28 +16,28 @@ export class CreateUserRolesTableMigration {
16
16
  const fkConstraint = config.app.isMultiTenant
17
17
  ? '\n CONSTRAINT "fk_user_roles_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE,'
18
18
  : '';
19
- await this.client.query(`
20
- CREATE TABLE "user_roles" (
21
- "_id" VARCHAR(255) PRIMARY KEY,
22
- "_orgId" VARCHAR(255),
23
- "userId" VARCHAR(255) NOT NULL,
24
- "roleId" VARCHAR(255) NOT NULL,
25
- "_created" TIMESTAMP NOT NULL,
26
- "_createdBy" VARCHAR(255) NOT NULL,
27
- "_updated" TIMESTAMP NOT NULL,
28
- "_updatedBy" VARCHAR(255) NOT NULL,
29
- "_deleted" TIMESTAMP,
30
- "_deletedBy" VARCHAR(255),
31
- ${fkConstraint}
32
- CONSTRAINT "fk_user_roles_user" FOREIGN KEY ("userId") REFERENCES "users"("_id") ON DELETE CASCADE,
33
- CONSTRAINT "fk_user_roles_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
34
- CONSTRAINT "uk_user_roles" UNIQUE ("_orgId", "userId", "roleId")
35
- )
19
+ await this.client.query(`
20
+ CREATE TABLE "user_roles" (
21
+ "_id" VARCHAR(255) PRIMARY KEY,
22
+ "_orgId" VARCHAR(255),
23
+ "userId" VARCHAR(255) NOT NULL,
24
+ "roleId" VARCHAR(255) NOT NULL,
25
+ "_created" TIMESTAMP NOT NULL,
26
+ "_createdBy" VARCHAR(255) NOT NULL,
27
+ "_updated" TIMESTAMP NOT NULL,
28
+ "_updatedBy" VARCHAR(255) NOT NULL,
29
+ "_deleted" TIMESTAMP,
30
+ "_deletedBy" VARCHAR(255),
31
+ ${fkConstraint}
32
+ CONSTRAINT "fk_user_roles_user" FOREIGN KEY ("userId") REFERENCES "users"("_id") ON DELETE CASCADE,
33
+ CONSTRAINT "fk_user_roles_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
34
+ CONSTRAINT "uk_user_roles" UNIQUE ("_orgId", "userId", "roleId")
35
+ )
36
36
  `);
37
37
  }
38
- const result = await this.client.query(`
39
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
40
- VALUES ('${_id}', ${this.index}, TRUE, FALSE);
38
+ const result = await this.client.query(`
39
+ INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
40
+ VALUES ('${_id}', ${this.index}, TRUE, FALSE);
41
41
  `);
42
42
  if (result.rowCount === 0) {
43
43
  await this.client.query('ROLLBACK');
@@ -54,11 +54,11 @@ export class CreateUserRolesTableMigration {
54
54
  async revert() {
55
55
  try {
56
56
  await this.client.query('BEGIN');
57
- await this.client.query(`
58
- DROP TABLE "user_roles";
57
+ await this.client.query(`
58
+ DROP TABLE "user_roles";
59
59
  `);
60
- const updateResult = await this.client.query(`
61
- UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
60
+ const updateResult = await this.client.query(`
61
+ UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
62
62
  `);
63
63
  if (updateResult.rowCount === 0) {
64
64
  await this.client.query('ROLLBACK');
@@ -16,18 +16,18 @@ export class CreateFeaturesTableMigration {
16
16
  const fkConstraint = config.app.isMultiTenant
17
17
  ? ',\n CONSTRAINT "fk_features_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE'
18
18
  : '';
19
- await this.client.query(`
20
- CREATE TABLE "features" (
21
- "_id" VARCHAR(255) PRIMARY KEY,
22
- "_orgId" VARCHAR(255),
23
- "name" VARCHAR(255) NOT NULL,
24
- CONSTRAINT "uk_features" UNIQUE ("_orgId", "name")${fkConstraint}
25
- )
19
+ await this.client.query(`
20
+ CREATE TABLE "features" (
21
+ "_id" VARCHAR(255) PRIMARY KEY,
22
+ "_orgId" VARCHAR(255),
23
+ "name" VARCHAR(255) NOT NULL,
24
+ CONSTRAINT "uk_features" UNIQUE ("_orgId", "name")${fkConstraint}
25
+ )
26
26
  `);
27
27
  }
28
- const result = await this.client.query(`
29
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
30
- VALUES ('${_id}', ${this.index}, TRUE, FALSE);
28
+ const result = await this.client.query(`
29
+ INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
30
+ VALUES ('${_id}', ${this.index}, TRUE, FALSE);
31
31
  `);
32
32
  if (result.rowCount === 0) {
33
33
  await this.client.query('ROLLBACK');
@@ -44,11 +44,11 @@ export class CreateFeaturesTableMigration {
44
44
  async revert() {
45
45
  try {
46
46
  await this.client.query('BEGIN');
47
- await this.client.query(`
48
- DROP TABLE "features";
47
+ await this.client.query(`
48
+ DROP TABLE "features";
49
49
  `);
50
- const updateResult = await this.client.query(`
51
- UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
50
+ const updateResult = await this.client.query(`
51
+ UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
52
52
  `);
53
53
  if (updateResult.rowCount === 0) {
54
54
  await this.client.query('ROLLBACK');
@@ -16,30 +16,30 @@ export class CreateAuthorizationsTableMigration {
16
16
  const fkConstraint = config.app.isMultiTenant
17
17
  ? ',\n CONSTRAINT "fk_authorizations_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE'
18
18
  : '';
19
- await this.client.query(`
20
- CREATE TABLE "authorizations" (
21
- "_id" VARCHAR(255) PRIMARY KEY,
22
- "_orgId" VARCHAR(255),
23
- "roleId" VARCHAR(255) NOT NULL,
24
- "featureId" VARCHAR(255) NOT NULL,
25
- "startDate" TIMESTAMP,
26
- "endDate" TIMESTAMP,
27
- "config" JSONB,
28
- "_created" TIMESTAMP NOT NULL,
29
- "_createdBy" VARCHAR(255) NOT NULL,
30
- "_updated" TIMESTAMP NOT NULL,
31
- "_updatedBy" VARCHAR(255) NOT NULL,
32
- "_deleted" TIMESTAMP,
33
- "_deletedBy" VARCHAR(255),
34
- CONSTRAINT "fk_authorizations_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
35
- CONSTRAINT "fk_authorizations_feature" FOREIGN KEY ("featureId") REFERENCES "features"("_id") ON DELETE CASCADE,
36
- CONSTRAINT "uk_authorizations" UNIQUE ("_orgId", "roleId", "featureId")${fkConstraint}
37
- )
19
+ await this.client.query(`
20
+ CREATE TABLE "authorizations" (
21
+ "_id" VARCHAR(255) PRIMARY KEY,
22
+ "_orgId" VARCHAR(255),
23
+ "roleId" VARCHAR(255) NOT NULL,
24
+ "featureId" VARCHAR(255) NOT NULL,
25
+ "startDate" TIMESTAMP,
26
+ "endDate" TIMESTAMP,
27
+ "config" JSONB,
28
+ "_created" TIMESTAMP NOT NULL,
29
+ "_createdBy" VARCHAR(255) NOT NULL,
30
+ "_updated" TIMESTAMP NOT NULL,
31
+ "_updatedBy" VARCHAR(255) NOT NULL,
32
+ "_deleted" TIMESTAMP,
33
+ "_deletedBy" VARCHAR(255),
34
+ CONSTRAINT "fk_authorizations_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
35
+ CONSTRAINT "fk_authorizations_feature" FOREIGN KEY ("featureId") REFERENCES "features"("_id") ON DELETE CASCADE,
36
+ CONSTRAINT "uk_authorizations" UNIQUE ("_orgId", "roleId", "featureId")${fkConstraint}
37
+ )
38
38
  `);
39
39
  }
40
- const result = await this.client.query(`
41
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
42
- VALUES ('${_id}', ${this.index}, TRUE, FALSE);
40
+ const result = await this.client.query(`
41
+ INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
42
+ VALUES ('${_id}', ${this.index}, TRUE, FALSE);
43
43
  `);
44
44
  if (result.rowCount === 0) {
45
45
  await this.client.query('ROLLBACK');
@@ -56,11 +56,11 @@ export class CreateAuthorizationsTableMigration {
56
56
  async revert() {
57
57
  try {
58
58
  await this.client.query('BEGIN');
59
- await this.client.query(`
60
- DROP TABLE "authorizations";
59
+ await this.client.query(`
60
+ DROP TABLE "authorizations";
61
61
  `);
62
- const updateResult = await this.client.query(`
63
- UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
62
+ const updateResult = await this.client.query(`
63
+ UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
64
64
  `);
65
65
  if (updateResult.rowCount === 0) {
66
66
  await this.client.query('ROLLBACK');
@@ -27,47 +27,47 @@ export class CreateAdminAuthorizationMigration {
27
27
  }
28
28
  await this.client.query('BEGIN');
29
29
  const roleId = randomUUID().toString();
30
- const roleResult = await this.client.query(`
31
- INSERT INTO "roles" ("_id", "_orgId", "name")
32
- VALUES ($1, $2, 'admin')
30
+ const roleResult = await this.client.query(`
31
+ INSERT INTO "roles" ("_id", "_orgId", "name")
32
+ VALUES ($1, $2, 'admin')
33
33
  `, [roleId, metaOrg?._id]);
34
34
  if (roleResult.rowCount === 0) {
35
35
  await this.client.query('ROLLBACK');
36
36
  return { success: false, error: new Error('Failed to create admin role') };
37
37
  }
38
38
  const userRoleId = randomUUID().toString();
39
- const userRoleResult = await this.client.query(`
40
- INSERT INTO "user_roles" ("_id", "_orgId", "userId", "roleId", "_created", "_createdBy", "_updated", "_updatedBy")
41
- VALUES ($1, $2, $3, $4, NOW(), 'system', NOW(), 'system')
39
+ const userRoleResult = await this.client.query(`
40
+ INSERT INTO "user_roles" ("_id", "_orgId", "userId", "roleId", "_created", "_createdBy", "_updated", "_updatedBy")
41
+ VALUES ($1, $2, $3, $4, NOW(), 'system', NOW(), 'system')
42
42
  `, [userRoleId, metaOrg?._id, adminUser?._id, roleId]);
43
43
  if (userRoleResult.rowCount === 0) {
44
44
  await this.client.query('ROLLBACK');
45
45
  return { success: false, error: new Error('Failed to create user role') };
46
46
  }
47
47
  const featureId = randomUUID().toString();
48
- const featureResult = await this.client.query(`
49
- INSERT INTO "features" ("_id", "_orgId", "name")
50
- VALUES ($1, $2, 'admin')
48
+ const featureResult = await this.client.query(`
49
+ INSERT INTO "features" ("_id", "_orgId", "name")
50
+ VALUES ($1, $2, 'admin')
51
51
  `, [featureId, metaOrg?._id]);
52
52
  if (featureResult.rowCount === 0) {
53
53
  await this.client.query('ROLLBACK');
54
54
  return { success: false, error: new Error('Failed to create admin feature') };
55
55
  }
56
56
  const authorizationId = randomUUID().toString();
57
- const authorizationResult = await this.client.query(`
58
- INSERT INTO "authorizations" (
59
- "_id", "_orgId", "roleId", "featureId",
60
- "_created", "_createdBy", "_updated", "_updatedBy"
61
- )
62
- VALUES ($1, $2, $3, $4, NOW(), 'system', NOW(), 'system')
57
+ const authorizationResult = await this.client.query(`
58
+ INSERT INTO "authorizations" (
59
+ "_id", "_orgId", "roleId", "featureId",
60
+ "_created", "_createdBy", "_updated", "_updatedBy"
61
+ )
62
+ VALUES ($1, $2, $3, $4, NOW(), 'system', NOW(), 'system')
63
63
  `, [authorizationId, metaOrg?._id, roleId, featureId]);
64
64
  if (authorizationResult.rowCount === 0) {
65
65
  await this.client.query('ROLLBACK');
66
66
  return { success: false, error: new Error('Failed to create admin authorization') };
67
67
  }
68
- const migrationResult = await this.client.query(`
69
- INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
70
- VALUES ($1, $2, TRUE, FALSE)
68
+ const migrationResult = await this.client.query(`
69
+ INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
70
+ VALUES ($1, $2, TRUE, FALSE)
71
71
  `, [_id, this.index]);
72
72
  if (migrationResult.rowCount === 0) {
73
73
  await this.client.query('ROLLBACK');
@@ -84,36 +84,36 @@ export class CreateAdminAuthorizationMigration {
84
84
  async revert(metaOrgId) {
85
85
  try {
86
86
  await this.client.query('BEGIN');
87
- await this.client.query(`
88
- DELETE FROM "authorizations"
89
- WHERE "_orgId" = $1
90
- AND "_featureId" IN (
91
- SELECT "_id" FROM "features"
92
- WHERE "_orgId" = $1 AND "name" = 'admin'
93
- )
94
- AND "_roleId" IN (
95
- SELECT "_id" FROM "roles"
96
- WHERE "_orgId" = $1 AND "name" = 'admin'
97
- )
87
+ await this.client.query(`
88
+ DELETE FROM "authorizations"
89
+ WHERE "_orgId" = $1
90
+ AND "_featureId" IN (
91
+ SELECT "_id" FROM "features"
92
+ WHERE "_orgId" = $1 AND "name" = 'admin'
93
+ )
94
+ AND "_roleId" IN (
95
+ SELECT "_id" FROM "roles"
96
+ WHERE "_orgId" = $1 AND "name" = 'admin'
97
+ )
98
98
  `, [metaOrgId]);
99
- await this.client.query(`
100
- DELETE FROM "features"
101
- WHERE "_orgId" = $1 AND "name" = 'admin'
99
+ await this.client.query(`
100
+ DELETE FROM "features"
101
+ WHERE "_orgId" = $1 AND "name" = 'admin'
102
102
  `, [metaOrgId]);
103
- await this.client.query(`
104
- DELETE FROM "user_roles"
105
- WHERE "_orgId" = $1
106
- AND "_roleId" IN (
107
- SELECT "_id" FROM "roles"
108
- WHERE "_orgId" = $1 AND "name" = 'admin'
109
- )
103
+ await this.client.query(`
104
+ DELETE FROM "user_roles"
105
+ WHERE "_orgId" = $1
106
+ AND "_roleId" IN (
107
+ SELECT "_id" FROM "roles"
108
+ WHERE "_orgId" = $1 AND "name" = 'admin'
109
+ )
110
110
  `, [metaOrgId]);
111
- await this.client.query(`
112
- DELETE FROM "roles"
113
- WHERE "_orgId" = $1 AND "name" = 'admin'
111
+ await this.client.query(`
112
+ DELETE FROM "roles"
113
+ WHERE "_orgId" = $1 AND "name" = 'admin'
114
114
  `, [metaOrgId]);
115
- const updateResult = await this.client.query(`
116
- UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = $1
115
+ const updateResult = await this.client.query(`
116
+ UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = $1
117
117
  `, [this.index]);
118
118
  if (updateResult.rowCount === 0) {
119
119
  await this.client.query('ROLLBACK');
@@ -42,10 +42,10 @@ export class DatabaseBuilder {
42
42
  async build() {
43
43
  let runMigrations = [];
44
44
  if (await doesTableExist(this.client, 'migrations')) {
45
- const migrations = await this.client.query(`
46
- SELECT "_id", "index"
47
- FROM migrations
48
- WHERE "hasRun" = TRUE AND "reverted" = FALSE
45
+ const migrations = await this.client.query(`
46
+ SELECT "_id", "index"
47
+ FROM migrations
48
+ WHERE "hasRun" = TRUE AND "reverted" = FALSE
49
49
  `);
50
50
  runMigrations = migrations.rows.map((row) => {
51
51
  return row.index;