vr-migrations 1.0.18 → 1.0.20

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.
@@ -10,20 +10,10 @@ module.exports = {
10
10
  primaryKey: true,
11
11
  allowNull: false,
12
12
  },
13
-
14
13
  firstName: {
15
14
  type: Sequelize.STRING(100),
16
15
  allowNull: false,
17
16
  },
18
- securityClearanceId: {
19
- type: Sequelize.UUID,
20
- allowNull: false,
21
- references: {
22
- model: "security_clearances",
23
- key: "id",
24
- },
25
- },
26
-
27
17
  lastName: {
28
18
  type: Sequelize.STRING(100),
29
19
  allowNull: false,
@@ -55,6 +45,10 @@ module.exports = {
55
45
  securityClearanceId: {
56
46
  type: Sequelize.UUID,
57
47
  allowNull: false,
48
+ references: {
49
+ model: "security_clearances",
50
+ key: "id",
51
+ },
58
52
  },
59
53
  plateNumber: {
60
54
  type: Sequelize.STRING(100),
@@ -128,8 +122,5 @@ module.exports = {
128
122
 
129
123
  async down(queryInterface) {
130
124
  await queryInterface.dropTable("users");
131
- await queryInterface.sequelize.query(
132
- 'DROP TYPE IF EXISTS "enum_users_role";'
133
- );
134
125
  },
135
126
  };
@@ -1,117 +1,149 @@
1
- // migrations/XXXXXXXXXXXXXX-create-installments.js
2
1
  "use strict";
3
2
 
4
3
  module.exports = {
5
4
  up: async (queryInterface, Sequelize) => {
6
- await queryInterface.createTable("installments", {
7
- id: {
8
- type: Sequelize.UUID,
9
- defaultValue: Sequelize.UUIDV4,
10
- primaryKey: true,
11
- allowNull: false,
12
- },
13
- devicePaymentPlanId: {
14
- type: Sequelize.UUID,
15
- allowNull: false,
16
- references: {
17
- model: "device_payment_plans",
18
- key: "id",
5
+ // Check if table already exists
6
+ const tables = await queryInterface.sequelize.query(
7
+ "SELECT table_name FROM information_schema.tables WHERE table_name = 'installments';"
8
+ );
9
+
10
+ const tableExists = tables[0].length > 0;
11
+
12
+ if (!tableExists) {
13
+ // Create table only if it doesn't exist
14
+ await queryInterface.createTable("installments", {
15
+ id: {
16
+ type: Sequelize.UUID,
17
+ defaultValue: Sequelize.UUIDV4,
18
+ primaryKey: true,
19
+ allowNull: false,
20
+ },
21
+ devicePaymentPlanId: {
22
+ type: Sequelize.UUID,
23
+ allowNull: false,
24
+ references: {
25
+ model: "device_payment_plans",
26
+ key: "id",
27
+ },
28
+ onUpdate: "CASCADE",
29
+ onDelete: "CASCADE",
30
+ },
31
+ installmentNumber: {
32
+ type: Sequelize.INTEGER,
33
+ allowNull: false,
34
+ },
35
+ amount: {
36
+ type: Sequelize.DECIMAL(10, 2),
37
+ allowNull: false,
38
+ },
39
+ dueDate: {
40
+ type: Sequelize.DATE,
41
+ allowNull: false,
19
42
  },
20
- onUpdate: "CASCADE",
21
- onDelete: "CASCADE",
22
- },
23
- installmentNumber: {
24
- type: Sequelize.INTEGER,
25
- allowNull: false,
26
- },
27
- amount: {
28
- type: Sequelize.DECIMAL(10, 2),
29
- allowNull: false,
30
- validate: {
31
- min: 0,
43
+ paidAt: {
44
+ type: Sequelize.DATE,
45
+ allowNull: true,
32
46
  },
33
- },
34
- dueDate: {
35
- type: Sequelize.DATE,
36
- allowNull: false,
37
- },
38
- paidAt: {
39
- type: Sequelize.DATE,
40
- allowNull: true,
41
- },
42
- paidAmount: {
43
- type: Sequelize.DECIMAL(10, 2),
44
- allowNull: true,
45
- },
46
- status: {
47
- type: Sequelize.ENUM("PENDING", "PAID", "OVERDUE", "SKIPPED"),
48
- allowNull: false,
49
- defaultValue: "PENDING",
50
- },
51
- paymentId: {
52
- type: Sequelize.UUID,
53
- allowNull: true,
54
- references: {
55
- model: "payments",
56
- key: "id",
47
+ paidAmount: {
48
+ type: Sequelize.DECIMAL(10, 2),
49
+ allowNull: true,
57
50
  },
58
- onUpdate: "CASCADE",
59
- onDelete: "SET NULL",
60
- },
61
- isAutoGenerated: {
62
- type: Sequelize.BOOLEAN,
63
- allowNull: false,
64
- defaultValue: true,
65
- },
66
- metadata: {
67
- type: Sequelize.JSONB,
68
- allowNull: false,
69
- defaultValue: {},
70
- },
71
- createdAt: {
72
- type: Sequelize.DATE,
73
- allowNull: false,
74
- defaultValue: Sequelize.literal("CURRENT_TIMESTAMP"),
75
- },
76
- updatedAt: {
77
- type: Sequelize.DATE,
78
- allowNull: false,
79
- defaultValue: Sequelize.literal("CURRENT_TIMESTAMP"),
80
- },
81
- });
51
+ status: {
52
+ type: Sequelize.ENUM("PENDING", "PAID", "OVERDUE", "SKIPPED"),
53
+ allowNull: false,
54
+ defaultValue: "PENDING",
55
+ },
56
+ paymentId: {
57
+ type: Sequelize.UUID,
58
+ allowNull: true,
59
+ references: {
60
+ model: "payments",
61
+ key: "id",
62
+ },
63
+ onUpdate: "CASCADE",
64
+ onDelete: "SET NULL",
65
+ },
66
+ isAutoGenerated: {
67
+ type: Sequelize.BOOLEAN,
68
+ allowNull: false,
69
+ defaultValue: true,
70
+ },
71
+ metadata: {
72
+ type: Sequelize.JSONB,
73
+ allowNull: false,
74
+ defaultValue: {},
75
+ },
76
+ createdAt: {
77
+ type: Sequelize.DATE,
78
+ allowNull: false,
79
+ defaultValue: Sequelize.literal("CURRENT_TIMESTAMP"),
80
+ },
81
+ updatedAt: {
82
+ type: Sequelize.DATE,
83
+ allowNull: false,
84
+ defaultValue: Sequelize.literal("CURRENT_TIMESTAMP"),
85
+ },
86
+ });
87
+ }
82
88
 
83
- // Add unique constraint for (devicePaymentPlanId, installmentNumber)
84
- await queryInterface.addConstraint("installments", {
85
- fields: ["devicePaymentPlanId", "installmentNumber"],
86
- type: "unique",
87
- name: "unique_installment_number_per_plan",
88
- });
89
+ // Add unique constraint - safely check if it exists first
90
+ try {
91
+ const constraints = await queryInterface.sequelize.query(
92
+ `SELECT constraint_name FROM information_schema.table_constraints
93
+ WHERE table_name = 'installments' AND constraint_name = 'unique_installment_number_per_plan';`
94
+ );
89
95
 
90
- // Add indexes
91
- await queryInterface.addIndex("installments", ["devicePaymentPlanId"], {
92
- name: "installments_plan_id_idx",
93
- });
96
+ if (constraints[0].length === 0) {
97
+ await queryInterface.addConstraint("installments", {
98
+ fields: ["devicePaymentPlanId", "installmentNumber"],
99
+ type: "unique",
100
+ name: "unique_installment_number_per_plan",
101
+ });
102
+ }
103
+ } catch (error) {
104
+ console.log("Constraint might already exist, skipping:", error.message);
105
+ }
94
106
 
95
- await queryInterface.addIndex("installments", ["status"], {
96
- name: "installments_status_idx",
97
- });
107
+ // Add indexes - safely check if they exist
108
+ const indexes = [
109
+ { fields: ["devicePaymentPlanId"], name: "installments_plan_id_idx" },
110
+ { fields: ["status"], name: "installments_status_idx" },
111
+ { fields: ["dueDate"], name: "installments_due_date_idx" },
112
+ { fields: ["paymentId"], name: "installments_payment_id_idx" },
113
+ ];
98
114
 
99
- await queryInterface.addIndex("installments", ["dueDate"], {
100
- name: "installments_due_date_idx",
101
- });
115
+ for (const index of indexes) {
116
+ try {
117
+ // Check if index exists
118
+ const indexExists = await queryInterface.sequelize.query(
119
+ `SELECT indexname FROM pg_indexes WHERE tablename = 'installments' AND indexname = '${index.name}';`
120
+ );
102
121
 
103
- await queryInterface.addIndex("installments", ["paymentId"], {
104
- name: "installments_payment_id_idx",
105
- });
122
+ if (indexExists[0].length === 0) {
123
+ await queryInterface.addIndex("installments", index.fields, {
124
+ name: index.name,
125
+ });
126
+ }
127
+ } catch (error) {
128
+ console.log(
129
+ `Index ${index.name} might already exist, skipping:`,
130
+ error
131
+ );
132
+ }
133
+ }
106
134
  },
107
135
 
108
136
  down: async (queryInterface, Sequelize) => {
109
- // Drop ENUM first
110
- await queryInterface.sequelize.query(
111
- 'DROP TYPE IF EXISTS "enum_installments_status";'
112
- );
137
+ // Drop table (cascade will handle constraints)
138
+ await queryInterface.dropTable("installments", { cascade: true });
113
139
 
114
- // Drop table
115
- await queryInterface.dropTable("installments");
140
+ // Drop ENUM type if it exists
141
+ try {
142
+ await queryInterface.sequelize.query(
143
+ 'DROP TYPE IF EXISTS "enum_installments_status";'
144
+ );
145
+ } catch (error) {
146
+ console.log("Error dropping enum:", error);
147
+ }
116
148
  },
117
149
  };
@@ -2,6 +2,13 @@
2
2
 
3
3
  module.exports = {
4
4
  up: async (queryInterface, Sequelize) => {
5
+ // Create ENUM type first (if not exists)
6
+ await queryInterface.sequelize
7
+ .query(
8
+ `CREATE TYPE "enum_bans_appealStatus" AS ENUM ('pending', 'approved', 'rejected');`
9
+ )
10
+ .catch(() => {}); // Ignore if already exists
11
+
5
12
  await queryInterface.createTable("bans", {
6
13
  id: {
7
14
  type: Sequelize.UUID,
@@ -11,7 +18,7 @@ module.exports = {
11
18
  },
12
19
  userId: {
13
20
  type: Sequelize.UUID,
14
- allowNull: true,
21
+ allowNull: false,
15
22
  references: {
16
23
  model: "users",
17
24
  key: "id",
@@ -26,6 +33,8 @@ module.exports = {
26
33
  model: "users",
27
34
  key: "id",
28
35
  },
36
+ onUpdate: "CASCADE",
37
+ onDelete: "CASCADE",
29
38
  },
30
39
  reason: {
31
40
  type: Sequelize.TEXT,
@@ -41,11 +50,7 @@ module.exports = {
41
50
  allowNull: false,
42
51
  defaultValue: false,
43
52
  },
44
- isActive: {
45
- type: Sequelize.BOOLEAN,
46
- allowNull: false,
47
- defaultValue: true,
48
- },
53
+ // REMOVED: isActive - not in model, use revokedAt instead
49
54
  appealedAt: {
50
55
  type: Sequelize.DATE,
51
56
  allowNull: true,
@@ -69,6 +74,8 @@ module.exports = {
69
74
  model: "users",
70
75
  key: "id",
71
76
  },
77
+ onUpdate: "CASCADE",
78
+ onDelete: "SET NULL",
72
79
  },
73
80
  revocationReason: {
74
81
  type: Sequelize.TEXT,
@@ -77,19 +84,25 @@ module.exports = {
77
84
  createdAt: {
78
85
  allowNull: false,
79
86
  type: Sequelize.DATE,
87
+ defaultValue: Sequelize.NOW,
80
88
  },
81
89
  updatedAt: {
82
90
  allowNull: false,
83
91
  type: Sequelize.DATE,
92
+ defaultValue: Sequelize.NOW,
84
93
  },
85
94
  });
86
95
 
87
96
  await queryInterface.addIndex("bans", ["userId"]);
88
- await queryInterface.addIndex("bans", ["isActive"]);
89
97
  await queryInterface.addIndex("bans", ["isPermanent"]);
98
+ await queryInterface.addIndex("bans", ["revokedAt"]);
99
+ await queryInterface.addIndex("bans", ["appealStatus"]);
90
100
  },
91
101
 
92
102
  down: async (queryInterface) => {
93
103
  await queryInterface.dropTable("bans");
104
+ await queryInterface.sequelize
105
+ .query('DROP TYPE IF EXISTS "enum_bans_appealStatus";')
106
+ .catch(() => {});
94
107
  },
95
108
  };
@@ -2,6 +2,13 @@
2
2
 
3
3
  module.exports = {
4
4
  up: async (queryInterface, Sequelize) => {
5
+ // Create ENUM types first (if not exists)
6
+ await queryInterface.sequelize
7
+ .query(
8
+ `CREATE TYPE "enum_suspensions_appealStatus" AS ENUM ('pending', 'approved', 'rejected');`
9
+ )
10
+ .catch(() => {}); // Ignore if already exists
11
+
5
12
  await queryInterface.createTable("suspensions", {
6
13
  id: {
7
14
  type: Sequelize.UUID,
@@ -11,7 +18,7 @@ module.exports = {
11
18
  },
12
19
  userId: {
13
20
  type: Sequelize.UUID,
14
- allowNull: true,
21
+ allowNull: false,
15
22
  references: {
16
23
  model: "users",
17
24
  key: "id",
@@ -26,6 +33,8 @@ module.exports = {
26
33
  model: "users",
27
34
  key: "id",
28
35
  },
36
+ onUpdate: "CASCADE",
37
+ onDelete: "CASCADE",
29
38
  },
30
39
  reason: {
31
40
  type: Sequelize.TEXT,
@@ -68,6 +77,8 @@ module.exports = {
68
77
  model: "users",
69
78
  key: "id",
70
79
  },
80
+ onUpdate: "CASCADE",
81
+ onDelete: "SET NULL",
71
82
  },
72
83
  revocationReason: {
73
84
  type: Sequelize.TEXT,
@@ -76,19 +87,26 @@ module.exports = {
76
87
  createdAt: {
77
88
  allowNull: false,
78
89
  type: Sequelize.DATE,
90
+ defaultValue: Sequelize.NOW,
79
91
  },
80
92
  updatedAt: {
81
93
  allowNull: false,
82
94
  type: Sequelize.DATE,
95
+ defaultValue: Sequelize.NOW,
83
96
  },
84
97
  });
85
98
 
86
99
  await queryInterface.addIndex("suspensions", ["userId"]);
87
100
  await queryInterface.addIndex("suspensions", ["isActive"]);
88
101
  await queryInterface.addIndex("suspensions", ["endsAt"]);
102
+ await queryInterface.addIndex("suspensions", ["revokedAt"]);
103
+ await queryInterface.addIndex("suspensions", ["appealStatus"]);
89
104
  },
90
105
 
91
106
  down: async (queryInterface) => {
92
107
  await queryInterface.dropTable("suspensions");
108
+ await queryInterface.sequelize
109
+ .query('DROP TYPE IF EXISTS "enum_suspensions_appealStatus";')
110
+ .catch(() => {});
93
111
  },
94
112
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vr-migrations",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "description": "Database migration and seeding package for VR applications",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",