vr-migrations 1.0.2

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 (40) hide show
  1. package/README.md +1 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.js +60 -0
  4. package/dist/create-migration.d.ts +1 -0
  5. package/dist/create-migration.js +26 -0
  6. package/dist/create-seeder.d.ts +1 -0
  7. package/dist/create-seeder.js +26 -0
  8. package/dist/db.d.ts +12 -0
  9. package/dist/db.js +54 -0
  10. package/dist/index.d.ts +8 -0
  11. package/dist/index.js +29 -0
  12. package/dist/migrate.d.ts +1 -0
  13. package/dist/migrate.js +36 -0
  14. package/dist/migrations/001-create-security-clearances.js +62 -0
  15. package/dist/migrations/002-create-users.js +141 -0
  16. package/dist/migrations/003-create-products.js +52 -0
  17. package/dist/migrations/004-create-pricing.js +82 -0
  18. package/dist/migrations/005-create-devices.js +63 -0
  19. package/dist/migrations/006-create-device-payment-plans.js +115 -0
  20. package/dist/migrations/007-create-idempotency-records.js +61 -0
  21. package/dist/migrations/008-create-payments.js +106 -0
  22. package/dist/migrations/009-create-transactions.js +80 -0
  23. package/dist/migrations/010-create-eventLogs.js +117 -0
  24. package/dist/migrations/index.d.ts +0 -0
  25. package/dist/migrations/index.js +1 -0
  26. package/dist/migrations/index.ts +1 -0
  27. package/dist/reset.d.ts +1 -0
  28. package/dist/reset.js +9 -0
  29. package/dist/rollback.d.ts +1 -0
  30. package/dist/rollback.js +40 -0
  31. package/dist/seed.d.ts +1 -0
  32. package/dist/seed.js +38 -0
  33. package/dist/seeders/001-security-clearance-demo.js +116 -0
  34. package/dist/seeders/002-users-demo.js +94 -0
  35. package/dist/seeders/index.d.ts +0 -0
  36. package/dist/seeders/index.js +1 -0
  37. package/dist/seeders/index.ts +1 -0
  38. package/dist/types.d.ts +5 -0
  39. package/dist/types.js +2 -0
  40. package/package.json +56 -0
package/README.md ADDED
@@ -0,0 +1 @@
1
+
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ export declare const program: Command;
package/dist/cli.js ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.program = void 0;
8
+ const commander_1 = require("commander");
9
+ const migrate_1 = require("./migrate");
10
+ const rollback_1 = require("./rollback");
11
+ const seed_1 = require("./seed");
12
+ const reset_1 = require("./reset");
13
+ const create_migration_1 = require("./create-migration");
14
+ const create_seeder_1 = require("./create-seeder");
15
+ const db_1 = require("./db");
16
+ const dotenv_1 = __importDefault(require("dotenv"));
17
+ dotenv_1.default.config();
18
+ exports.program = new commander_1.Command();
19
+ exports.program
20
+ .name("vr-migrate") //
21
+ .description("CENTRALIZED VR Migration Tool") //
22
+ .version("1.0.0")
23
+ .hook("preAction", async () => {
24
+ const sequelize = await (0, db_1.initializeDatabase)({
25
+ DB_HOST: process.env.DB_HOST,
26
+ DB_PORT: parseInt(process.env.DB_PORT || "5432"),
27
+ DB_USER: process.env.DB_USER,
28
+ DB_PASSWORD: process.env.DB_PASSWORD,
29
+ DB_NAME: process.env.DB_NAME,
30
+ NODE_ENV: process.env.NODE_ENV,
31
+ });
32
+ await sequelize.authenticate();
33
+ });
34
+ // Centralized Commands (No path overrides allowed)
35
+ exports.program
36
+ .command("migrate")
37
+ .description("Run CENTRALIZED migrations from vr-migrations package") //
38
+ .action(async () => await (0, migrate_1.migrate)());
39
+ exports.program
40
+ .command("rollback")
41
+ .description("Rollback CENTRALIZED migrations")
42
+ .option("--all", "Rollback all migrations")
43
+ .action(async (options) => await (0, rollback_1.rollback)(options.all ? "all" : 1));
44
+ exports.program
45
+ .command("seed")
46
+ .description("Run CENTRALIZED seeders")
47
+ .action(async () => await (0, seed_1.seed)());
48
+ exports.program
49
+ .command("reset")
50
+ .description("Reset database (DANGER!)")
51
+ .action(async () => await (0, reset_1.reset)());
52
+ exports.program
53
+ .command("create:migration <name>")
54
+ .description("Create new migration in vr-migrations package") //
55
+ .action((name) => (0, create_migration_1.createMigration)(name));
56
+ exports.program
57
+ .command("create:seeder <name>")
58
+ .description("Create new seeder in vr-migrations package") //
59
+ .action((name) => (0, create_seeder_1.createSeeder)(name));
60
+ exports.program.parse(process.argv);
@@ -0,0 +1 @@
1
+ export declare function createMigration(name: string): void;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createMigration = createMigration;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ // const migrationsDir = path.join(__dirname, "../migrations");
10
+ const migrationsDir = path_1.default.join(__dirname, "migrations");
11
+ const template = `module.exports = {
12
+ async up(queryInterface, Sequelize) {
13
+ // Migration code here
14
+ },
15
+ async down(queryInterface) {
16
+ // Rollback code here
17
+ }
18
+ };`;
19
+ function createMigration(name) {
20
+ const timestamp = new Date().toISOString().replace(/\D/g, "").slice(0, 14);
21
+ const fileName = `${timestamp}-${name}.js`;
22
+ const filePath = path_1.default.join(migrationsDir, fileName);
23
+ fs_1.default.mkdirSync(migrationsDir, { recursive: true });
24
+ fs_1.default.writeFileSync(filePath, template);
25
+ console.log(`✅ Created migration: ${fileName}`);
26
+ }
@@ -0,0 +1 @@
1
+ export declare function createSeeder(name: string): void;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createSeeder = createSeeder;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ // const seedersDir = path.join(__dirname, "../seeders");
10
+ const seedersDir = path_1.default.join(__dirname, "seeders");
11
+ const template = `module.exports = {
12
+ async up(queryInterface, Sequelize) {
13
+ // Migration code here
14
+ },
15
+ async down(queryInterface) {
16
+ // Rollback code here
17
+ }
18
+ };`;
19
+ function createSeeder(name) {
20
+ const timestamp = new Date().toISOString().replace(/\D/g, "").slice(0, 14);
21
+ const fileName = `${timestamp}-${name}.js`;
22
+ const filePath = path_1.default.join(seedersDir, fileName);
23
+ fs_1.default.mkdirSync(seedersDir, { recursive: true });
24
+ fs_1.default.writeFileSync(filePath, template);
25
+ console.log(`✅ Created CENTRALIZED seeder: ${fileName}`);
26
+ }
package/dist/db.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { Sequelize } from "sequelize";
2
+ export declare function getSequelize(): Sequelize;
3
+ export declare function initializeDatabase(config: {
4
+ DB_HOST: string;
5
+ DB_PORT: number;
6
+ DB_USER: string;
7
+ DB_PASSWORD: string;
8
+ DB_NAME: string;
9
+ NODE_ENV?: string;
10
+ }): Promise<Sequelize>;
11
+ export declare function closeDatabase(): Promise<void>;
12
+ export { Model, InferAttributes, InferCreationAttributes, DataTypes, CreationOptional, ModelStatic, ModelAttributes, NonAttribute, Op, } from "sequelize";
package/dist/db.js ADDED
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Op = exports.DataTypes = exports.Model = void 0;
4
+ exports.getSequelize = getSequelize;
5
+ exports.initializeDatabase = initializeDatabase;
6
+ exports.closeDatabase = closeDatabase;
7
+ const sequelize_1 = require("sequelize");
8
+ let _sequelize = null;
9
+ let _isInitialized = false;
10
+ function getSequelize() {
11
+ if (!_isInitialized) {
12
+ throw new Error("Database not initialized. Call initializeDatabase() first");
13
+ }
14
+ return _sequelize;
15
+ }
16
+ async function initializeDatabase(config) {
17
+ if (_isInitialized)
18
+ return _sequelize;
19
+ _sequelize = new sequelize_1.Sequelize({
20
+ dialect: "postgres",
21
+ host: config.DB_HOST,
22
+ port: config.DB_PORT,
23
+ username: config.DB_USER,
24
+ password: config.DB_PASSWORD,
25
+ database: config.DB_NAME,
26
+ logging: false,
27
+ pool: {
28
+ max: 20,
29
+ min: 2,
30
+ acquire: 120000,
31
+ idle: 10000,
32
+ },
33
+ dialectOptions: config.NODE_ENV === "production"
34
+ ? {
35
+ ssl: { require: true, rejectUnauthorized: false },
36
+ }
37
+ : {},
38
+ });
39
+ await _sequelize.authenticate();
40
+ _isInitialized = true;
41
+ return _sequelize;
42
+ }
43
+ async function closeDatabase() {
44
+ if (_sequelize) {
45
+ await _sequelize.close();
46
+ _sequelize = null;
47
+ _isInitialized = false;
48
+ }
49
+ }
50
+ // Export types for models
51
+ var sequelize_2 = require("sequelize");
52
+ Object.defineProperty(exports, "Model", { enumerable: true, get: function () { return sequelize_2.Model; } });
53
+ Object.defineProperty(exports, "DataTypes", { enumerable: true, get: function () { return sequelize_2.DataTypes; } });
54
+ Object.defineProperty(exports, "Op", { enumerable: true, get: function () { return sequelize_2.Op; } });
@@ -0,0 +1,8 @@
1
+ export * from "./types";
2
+ export * from "./db";
3
+ export * from "./migrate";
4
+ export * from "./rollback";
5
+ export * from "./seed";
6
+ export * from "./reset";
7
+ export * from "./create-migration";
8
+ export * from "./create-seeder";
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ // Export types first
18
+ __exportStar(require("./types"), exports);
19
+ // Then export functionality
20
+ __exportStar(require("./db"), exports);
21
+ __exportStar(require("./migrate"), exports);
22
+ __exportStar(require("./rollback"), exports);
23
+ __exportStar(require("./seed"), exports);
24
+ __exportStar(require("./reset"), exports);
25
+ __exportStar(require("./create-migration"), exports);
26
+ __exportStar(require("./create-seeder"), exports);
27
+ // // CLI export
28
+ // import { program } from "./cli";
29
+ // export default program;
@@ -0,0 +1 @@
1
+ export declare function migrate(): Promise<void>;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.migrate = migrate;
7
+ const umzug_1 = require("umzug");
8
+ const db_1 = require("./db");
9
+ const sequelize_1 = require("sequelize");
10
+ const path_1 = __importDefault(require("path"));
11
+ // const migrationsPath = path.join(__dirname, "../migrations/[0-9]*-*.js");
12
+ const migrationsPath = path_1.default.join(__dirname, "migrations/[0-9]*-*.js");
13
+ async function migrate() {
14
+ console.log("looking for migrations at:", migrationsPath);
15
+ const sequelize = (0, db_1.getSequelize)();
16
+ const migrator = new umzug_1.Umzug({
17
+ migrations: {
18
+ glob: migrationsPath,
19
+ resolve: ({ name, path: filePath }) => ({
20
+ name,
21
+ up: async () => {
22
+ const migration = require(filePath);
23
+ return migration.up(sequelize.getQueryInterface(), sequelize_1.Sequelize);
24
+ },
25
+ down: async () => {
26
+ const migration = require(filePath);
27
+ return migration.down(sequelize.getQueryInterface());
28
+ },
29
+ }),
30
+ },
31
+ storage: new umzug_1.SequelizeStorage({ sequelize }),
32
+ logger: console,
33
+ });
34
+ await migrator.up();
35
+ console.log("✅ Migrations completed");
36
+ }
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ /** @type {import('sequelize-cli').Migration} */
4
+ module.exports = {
5
+ async up(queryInterface, Sequelize) {
6
+ await queryInterface.createTable("security_clearances", {
7
+ id: {
8
+ type: Sequelize.UUID,
9
+ defaultValue: Sequelize.UUIDV4,
10
+ primaryKey: true,
11
+ allowNull: false
12
+ },
13
+ role: {
14
+ type: Sequelize.ENUM(
15
+ "RIDER",
16
+ "PASSENGER",
17
+ "ADMIN",
18
+ "AGENT",
19
+ "SUPER_ADMIN"
20
+ ),
21
+ allowNull: false,
22
+ unique: true
23
+ },
24
+ description: {
25
+ type: Sequelize.TEXT,
26
+ allowNull: true
27
+ },
28
+ level: {
29
+ type: Sequelize.INTEGER,
30
+ allowNull: false,
31
+ defaultValue: 0
32
+ },
33
+ permissions: {
34
+ type: Sequelize.ARRAY(Sequelize.STRING),
35
+ allowNull: false,
36
+ defaultValue: []
37
+ },
38
+ isDefault: {
39
+ type: Sequelize.BOOLEAN,
40
+ allowNull: false,
41
+ defaultValue: false
42
+ },
43
+ createdAt: {
44
+ type: Sequelize.DATE,
45
+ allowNull: false,
46
+ defaultValue: Sequelize.fn("NOW")
47
+ },
48
+ updatedAt: {
49
+ type: Sequelize.DATE,
50
+ allowNull: false,
51
+ defaultValue: Sequelize.fn("NOW")
52
+ }
53
+ });
54
+ },
55
+
56
+ async down(queryInterface) {
57
+ await queryInterface.dropTable("security_clearances");
58
+ await queryInterface.sequelize.query(
59
+ 'DROP TYPE IF EXISTS "enum_security_clearances_role";'
60
+ );
61
+ }
62
+ };
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+
3
+ /** @type {import('sequelize').Migration} */
4
+ module.exports = {
5
+ async up(queryInterface, Sequelize) {
6
+ await queryInterface.createTable("users", {
7
+ id: {
8
+ type: Sequelize.UUID,
9
+ defaultValue: Sequelize.UUIDV4,
10
+ primaryKey: true,
11
+ allowNull: false
12
+ },
13
+
14
+ firstName: {
15
+ type: Sequelize.STRING(50),
16
+ allowNull: false
17
+ },
18
+ securityClearanceId: {
19
+ type: Sequelize.UUID,
20
+ allowNull: false,
21
+ references: {
22
+ model: "security_clearances",
23
+ key: "id"
24
+ }
25
+ },
26
+ lastName: {
27
+ type: Sequelize.STRING(50),
28
+ allowNull: false
29
+ },
30
+
31
+ phoneNumber: {
32
+ type: Sequelize.STRING(20),
33
+ allowNull: false,
34
+ unique: true
35
+ },
36
+ email: {
37
+ type: Sequelize.STRING(100),
38
+ allowNull: true,
39
+ unique: true
40
+ },
41
+ password: {
42
+ type: Sequelize.STRING,
43
+ allowNull: true
44
+ },
45
+ jacketId: {
46
+ type: Sequelize.STRING(50),
47
+ allowNull: true,
48
+ unique: true
49
+ },
50
+
51
+ nationalId: {
52
+ type: Sequelize.STRING(60),
53
+ allowNull: true,
54
+ unique: true
55
+ },
56
+
57
+ role: {
58
+ type: Sequelize.ENUM("RIDER", "ADMIN", "AGENT"),
59
+ allowNull: false,
60
+ defaultValue: "RIDER"
61
+ },
62
+
63
+ plateNumber: {
64
+ type: Sequelize.STRING(20),
65
+ allowNull: true
66
+ },
67
+ isActive: {
68
+ type: Sequelize.BOOLEAN,
69
+ allowNull: false,
70
+ defaultValue: true
71
+ },
72
+ tokenVersion: {
73
+ type: Sequelize.INTEGER,
74
+ allowNull: false,
75
+ defaultValue: 1
76
+ },
77
+ forgotPassword: {
78
+ type: Sequelize.BOOLEAN,
79
+ defaultValue: false
80
+ },
81
+ otp: {
82
+ type: Sequelize.STRING(6),
83
+ allowNull: true
84
+ },
85
+ otpExpiresAt: {
86
+ type: Sequelize.DATE,
87
+ allowNull: true
88
+ },
89
+ isSuspended: {
90
+ type: Sequelize.BOOLEAN,
91
+ allowNull: false,
92
+ defaultValue: false
93
+ },
94
+ bannedAt: {
95
+ type: Sequelize.DATE,
96
+ allowNull: true
97
+ },
98
+ banReason: {
99
+ type: Sequelize.TEXT,
100
+ allowNull: true
101
+ },
102
+ suspendedAt: {
103
+ type: Sequelize.DATE,
104
+ allowNull: true
105
+ },
106
+ suspensionReason: {
107
+ type: Sequelize.TEXT,
108
+ allowNull: true
109
+ },
110
+ lastLoginAt: {
111
+ type: Sequelize.DATE,
112
+ allowNull: true
113
+ },
114
+ isDeactivated: {
115
+ type: Sequelize.BOOLEAN,
116
+ defaultValue: false
117
+ },
118
+ deactivatedAt: {
119
+ type: Sequelize.DATE,
120
+ allowNull: true
121
+ },
122
+ createdAt: {
123
+ type: Sequelize.DATE,
124
+ allowNull: false,
125
+ defaultValue: Sequelize.fn("NOW")
126
+ }
127
+ });
128
+
129
+ // Optional: explicit indexes (Postgres already enforces uniques, but this is clarity)
130
+ await queryInterface.addIndex("users", ["phoneNumber"]);
131
+ await queryInterface.addIndex("users", ["jacketId"]);
132
+ await queryInterface.addIndex("users", ["nationalId"]);
133
+ },
134
+
135
+ async down(queryInterface) {
136
+ await queryInterface.dropTable("users");
137
+ await queryInterface.sequelize.query(
138
+ 'DROP TYPE IF EXISTS "enum_users_role";'
139
+ );
140
+ }
141
+ };
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ module.exports = {
4
+ async up(queryInterface, Sequelize) {
5
+ await queryInterface.createTable("products", {
6
+ id: {
7
+ type: Sequelize.UUID,
8
+ defaultValue: Sequelize.UUIDV4,
9
+ primaryKey: true,
10
+ allowNull: false
11
+ },
12
+
13
+ name: {
14
+ type: Sequelize.STRING(100),
15
+ allowNull: false
16
+ },
17
+
18
+ description: {
19
+ type: Sequelize.TEXT,
20
+ allowNull: true
21
+ },
22
+
23
+ stock: {
24
+ type: Sequelize.INTEGER,
25
+ allowNull: false,
26
+ defaultValue: 0
27
+ },
28
+
29
+ isActive: {
30
+ type: Sequelize.BOOLEAN,
31
+ allowNull: false,
32
+ defaultValue: true
33
+ },
34
+
35
+ createdAt: {
36
+ type: Sequelize.DATE,
37
+ allowNull: false,
38
+ defaultValue: Sequelize.fn("NOW")
39
+ },
40
+
41
+ updatedAt: {
42
+ type: Sequelize.DATE,
43
+ allowNull: false,
44
+ defaultValue: Sequelize.fn("NOW")
45
+ }
46
+ });
47
+ },
48
+
49
+ async down(queryInterface) {
50
+ await queryInterface.dropTable("products");
51
+ }
52
+ };
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+
3
+ module.exports = {
4
+ async up(queryInterface, Sequelize) {
5
+ await queryInterface.createTable("pricings", {
6
+ id: {
7
+ type: Sequelize.UUID,
8
+ defaultValue: Sequelize.UUIDV4,
9
+ primaryKey: true,
10
+ allowNull: false
11
+ },
12
+
13
+ productId: {
14
+ type: Sequelize.UUID,
15
+ allowNull: false,
16
+ references: {
17
+ model: "products",
18
+ key: "id"
19
+ },
20
+ onUpdate: "CASCADE",
21
+ onDelete: "CASCADE"
22
+ },
23
+
24
+ name: {
25
+ type: Sequelize.STRING(100),
26
+ allowNull: false
27
+ },
28
+
29
+ upfrontPrice: {
30
+ type: Sequelize.DECIMAL(10, 2),
31
+ allowNull: false
32
+ },
33
+
34
+ downPayment: {
35
+ type: Sequelize.DECIMAL(10, 2),
36
+ allowNull: false,
37
+ defaultValue: 0
38
+ },
39
+
40
+ installmentAmount: {
41
+ type: Sequelize.DECIMAL(10, 2),
42
+ allowNull: true
43
+ },
44
+
45
+ installmentIntervalDays: {
46
+ type: Sequelize.INTEGER,
47
+ allowNull: true
48
+ },
49
+
50
+ totalAmount: {
51
+ type: Sequelize.DECIMAL(10, 2),
52
+ allowNull: false
53
+ },
54
+
55
+ isActive: {
56
+ type: Sequelize.BOOLEAN,
57
+ allowNull: false,
58
+ defaultValue: true
59
+ },
60
+
61
+ createdAt: {
62
+ type: Sequelize.DATE,
63
+ allowNull: false,
64
+ defaultValue: Sequelize.fn("NOW")
65
+ },
66
+
67
+ updatedAt: {
68
+ type: Sequelize.DATE,
69
+ allowNull: false,
70
+ defaultValue: Sequelize.fn("NOW")
71
+ }
72
+ });
73
+
74
+ // Optional but recommended indexes
75
+ await queryInterface.addIndex("pricings", ["productId"]);
76
+ await queryInterface.addIndex("pricings", ["isActive"]);
77
+ },
78
+
79
+ async down(queryInterface) {
80
+ await queryInterface.dropTable("pricings");
81
+ }
82
+ };
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+
3
+ /** @type {import('sequelize').QueryInterface} */
4
+ module.exports = {
5
+ async up(queryInterface, Sequelize) {
6
+ await queryInterface.createTable("devices", {
7
+ id: {
8
+ type: Sequelize.UUID,
9
+ defaultValue: Sequelize.UUIDV4,
10
+ primaryKey: true,
11
+ allowNull: false
12
+ },
13
+ serialNumber: {
14
+ type: Sequelize.STRING(64),
15
+ allowNull: false,
16
+ unique: true
17
+ },
18
+ productId: {
19
+ type: Sequelize.UUID,
20
+ allowNull: false,
21
+ references: {
22
+ model: "products",
23
+ key: "id"
24
+ },
25
+ onUpdate: "CASCADE",
26
+ onDelete: "RESTRICT"
27
+ },
28
+
29
+ status: {
30
+ type: Sequelize.ENUM("locked", "unlocked", "disabled"),
31
+ allowNull: false,
32
+ defaultValue: "locked"
33
+ },
34
+ isPermanentlyUnlocked: {
35
+ type: Sequelize.BOOLEAN,
36
+ allowNull: false,
37
+ defaultValue: false
38
+ },
39
+ activatedAt: {
40
+ type: Sequelize.DATE,
41
+ allowNull: true
42
+ },
43
+ createdAt: {
44
+ type: Sequelize.DATE,
45
+ allowNull: false,
46
+ defaultValue: Sequelize.fn("NOW")
47
+ },
48
+ updatedAt: {
49
+ type: Sequelize.DATE,
50
+ allowNull: false,
51
+ defaultValue: Sequelize.fn("NOW")
52
+ }
53
+ });
54
+ },
55
+
56
+ async down(queryInterface) {
57
+ await queryInterface.dropTable("devices");
58
+
59
+ await queryInterface.sequelize.query(
60
+ 'DROP TYPE IF EXISTS "enum_devices_status"'
61
+ );
62
+ }
63
+ };