ojamoto_models 1.0.0 → 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.
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ module.exports = {
4
+ async up(queryInterface, Sequelize) {
5
+ await queryInterface.createTable("admin_sessions", {
6
+ admin_session_id: {
7
+ type: Sequelize.INTEGER,
8
+ primaryKey: true,
9
+ autoIncrement: true,
10
+ allowNull: false,
11
+ },
12
+ admin_id: {
13
+ type: Sequelize.INTEGER,
14
+ allowNull: false,
15
+ references: { model: "admin_users", key: "admin_id" },
16
+ onDelete: "CASCADE",
17
+ onUpdate: "CASCADE",
18
+ },
19
+ ip_address: {
20
+ type: Sequelize.STRING(45),
21
+ allowNull: true,
22
+ },
23
+ expires_at: {
24
+ type: Sequelize.DATE,
25
+ allowNull: false,
26
+ },
27
+ revoked: {
28
+ type: Sequelize.BOOLEAN,
29
+ allowNull: false,
30
+ defaultValue: false,
31
+ },
32
+ created_at: {
33
+ type: Sequelize.DATE,
34
+ allowNull: false,
35
+ },
36
+ });
37
+
38
+ await queryInterface.addIndex("admin_sessions", ["admin_id"]);
39
+ await queryInterface.addIndex("admin_sessions", ["admin_id", "revoked"]);
40
+ },
41
+
42
+ async down(queryInterface) {
43
+ await queryInterface.dropTable("admin_sessions");
44
+ },
45
+ };
@@ -0,0 +1,15 @@
1
+ ("use strict");
2
+
3
+ module.exports = {
4
+ async up(queryInterface, Sequelize) {
5
+ await queryInterface.addColumn("admin_users", "totp_secret", {
6
+ type: Sequelize.STRING,
7
+ allowNull: true,
8
+ after: "two_factor_enabled",
9
+ comment: "Base32 TOTP secret",
10
+ });
11
+ },
12
+ async down(queryInterface) {
13
+ await queryInterface.removeColumn("admin_users", "totp_secret");
14
+ },
15
+ };
@@ -0,0 +1,15 @@
1
+ ("use strict");
2
+
3
+ module.exports = {
4
+ async up(queryInterface, Sequelize) {
5
+ await queryInterface.addColumn("users", "totp_secret", {
6
+ type: Sequelize.STRING,
7
+ allowNull: true,
8
+ after: "two_factor_enabled",
9
+ comment: "Base32 TOTP secret",
10
+ });
11
+ },
12
+ async down(queryInterface) {
13
+ await queryInterface.removeColumn("users", "totp_secret");
14
+ },
15
+ };
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ module.exports = {
4
+ async up(queryInterface, Sequelize) {
5
+ await queryInterface.addColumn("admin_users", "must_change_password", {
6
+ type: Sequelize.BOOLEAN,
7
+ allowNull: false,
8
+ defaultValue: false,
9
+ after: "password_hash",
10
+ });
11
+ },
12
+ async down(queryInterface) {
13
+ await queryInterface.removeColumn("admin_users", "must_change_password");
14
+ },
15
+ };
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ module.exports = {
4
+ async up(queryInterface, Sequelize) {
5
+ await queryInterface.addColumn("users", "is_transaction_pin_set", {
6
+ type: Sequelize.BOOLEAN,
7
+ allowNull: true,
8
+ defaultValue: false,
9
+ after: "transaction_pin_hash",
10
+ });
11
+
12
+ await queryInterface.addColumn("users", "is_seller_profile_created", {
13
+ type: Sequelize.BOOLEAN,
14
+ allowNull: true,
15
+ defaultValue: false,
16
+ after: "is_transaction_pin_set",
17
+ });
18
+ },
19
+
20
+ async down(queryInterface) {
21
+ await queryInterface.removeColumn("users", "is_transaction_pin_set");
22
+
23
+ await queryInterface.removeColumn("users", "is_seller_profile_created");
24
+ },
25
+ };
@@ -0,0 +1,22 @@
1
+ ("use strict");
2
+
3
+ module.exports = {
4
+ async up(queryInterface, Sequelize) {
5
+ await queryInterface.addColumn(
6
+ "wallet_transactions",
7
+ "provider_reference_id",
8
+ {
9
+ type: Sequelize.STRING(100),
10
+ allowNull: true,
11
+ after: "user_id",
12
+ comment: "Flutterwave's own transfer/transaction ID",
13
+ },
14
+ );
15
+ },
16
+ async down(queryInterface) {
17
+ await queryInterface.removeColumn(
18
+ "wallet_transactions",
19
+ "provider_reference_id",
20
+ );
21
+ },
22
+ };
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ const { Model, DataTypes } = require("sequelize");
4
+
5
+ module.exports = (sequelize) => {
6
+ class AdminSession extends Model {
7
+ static associate(models) {
8
+ AdminSession.belongsTo(models.AdminUser, {
9
+ foreignKey: "admin_id",
10
+ as: "admin",
11
+ });
12
+ }
13
+ }
14
+
15
+ AdminSession.init(
16
+ {
17
+ admin_session_id: {
18
+ type: DataTypes.INTEGER,
19
+ primaryKey: true,
20
+ autoIncrement: true,
21
+ },
22
+ admin_id: {
23
+ type: DataTypes.INTEGER,
24
+ allowNull: false,
25
+ references: { model: "admin_users", key: "admin_id" },
26
+ onDelete: "CASCADE",
27
+ },
28
+ ip_address: {
29
+ type: DataTypes.STRING(45),
30
+ allowNull: true,
31
+ },
32
+ expires_at: {
33
+ type: DataTypes.DATE,
34
+ allowNull: false,
35
+ comment: "8 hours from issuance — matches admin access token lifetime",
36
+ },
37
+ revoked: {
38
+ type: DataTypes.BOOLEAN,
39
+ allowNull: false,
40
+ defaultValue: false,
41
+ },
42
+ },
43
+ {
44
+ sequelize,
45
+ modelName: "AdminSession",
46
+ tableName: "admin_sessions",
47
+ timestamps: true,
48
+ createdAt: "created_at",
49
+ updatedAt: false,
50
+ },
51
+ );
52
+
53
+ AdminSession.removeAttribute("id");
54
+ return AdminSession;
55
+ };
@@ -1,115 +1,132 @@
1
- "use strict";
2
-
3
- const { Model, DataTypes } = require("sequelize");
4
- const { ADMIN_ROLE, ADMIN_STATUS } = require("../services/constants");
5
-
6
- module.exports = (sequelize) => {
7
- class AdminUser extends Model {
8
- static associate(models) {
9
- // Self-referential: who created this admin account
10
- AdminUser.belongsTo(models.AdminUser, {
11
- foreignKey: "created_by",
12
- as: "createdByAdmin",
13
- });
14
-
15
- AdminUser.hasMany(models.AdminUser, {
16
- foreignKey: "created_by",
17
- as: "createdAdmins",
18
- });
19
-
20
- // Disputes assigned to this admin
21
- AdminUser.hasMany(models.Dispute, {
22
- foreignKey: "assigned_admin",
23
- as: "assignedDisputes",
24
- });
25
-
26
- // Audit logs performed by this admin
27
- AdminUser.hasMany(models.AuditLog, {
28
- foreignKey: "admin_id",
29
- as: "auditLogs",
30
- });
31
-
32
- // Notifications
33
- AdminUser.hasMany(models.AdminNotification, {
34
- foreignKey: "admin_id",
35
- as: "notifications",
36
- });
37
- }
38
- }
39
-
40
- AdminUser.init(
41
- {
42
- admin_id: {
43
- type: DataTypes.INTEGER,
44
- primaryKey: true,
45
- autoIncrement: true,
46
- },
47
- uuid: {
48
- type: DataTypes.UUID,
49
- defaultValue: DataTypes.UUIDV4,
50
- allowNull: false,
51
- unique: true,
52
- },
53
- first_name: {
54
- type: DataTypes.STRING(100),
55
- allowNull: false,
56
- },
57
- last_name: {
58
- type: DataTypes.STRING(100),
59
- allowNull: false,
60
- },
61
- email: {
62
- type: DataTypes.STRING(255),
63
- allowNull: false,
64
- unique: true,
65
- validate: { isEmail: true },
66
- },
67
- phone: {
68
- type: DataTypes.STRING(20),
69
- allowNull: false,
70
- unique: true,
71
- },
72
- password_hash: {
73
- type: DataTypes.STRING(255),
74
- allowNull: false,
75
- },
76
- role: {
77
- type: DataTypes.ENUM(...Object.values(ADMIN_ROLE)),
78
- allowNull: false,
79
- },
80
- status: {
81
- type: DataTypes.ENUM(...Object.values(ADMIN_STATUS)),
82
- allowNull: false,
83
- defaultValue: ADMIN_STATUS.ACTIVE,
84
- },
85
- two_factor_enabled: {
86
- type: DataTypes.BOOLEAN,
87
- allowNull: false,
88
- defaultValue: true,
89
- comment: "Mandatory for all admin accounts",
90
- },
91
- last_login_at: {
92
- type: DataTypes.DATE,
93
- allowNull: true,
94
- },
95
- created_by: {
96
- type: DataTypes.INTEGER,
97
- allowNull: true,
98
- references: { model: "admin_users", key: "admin_id" },
99
- onDelete: "SET NULL",
100
- comment: "Which super admin created this account",
101
- },
102
- },
103
- {
104
- sequelize,
105
- modelName: "AdminUser",
106
- tableName: "admin_users",
107
- timestamps: true,
108
- createdAt: "created_at",
109
- updatedAt: "updated_at",
110
- },
111
- );
112
-
113
- AdminUser.removeAttribute("id");
114
- return AdminUser;
115
- };
1
+ "use strict";
2
+
3
+ const { Model, DataTypes } = require("sequelize");
4
+ const { ADMIN_ROLE, ADMIN_STATUS } = require("../services/constants");
5
+
6
+ module.exports = (sequelize) => {
7
+ class AdminUser extends Model {
8
+ static associate(models) {
9
+ // Self-referential: who created this admin account
10
+ AdminUser.belongsTo(models.AdminUser, {
11
+ foreignKey: "created_by",
12
+ as: "createdByAdmin",
13
+ });
14
+
15
+ AdminUser.hasMany(models.AdminUser, {
16
+ foreignKey: "created_by",
17
+ as: "createdAdmins",
18
+ });
19
+
20
+ // Disputes assigned to this admin
21
+ AdminUser.hasMany(models.Dispute, {
22
+ foreignKey: "assigned_admin",
23
+ as: "assignedDisputes",
24
+ });
25
+
26
+ // Audit logs performed by this admin
27
+ AdminUser.hasMany(models.AuditLog, {
28
+ foreignKey: "admin_id",
29
+ as: "auditLogs",
30
+ });
31
+
32
+ // Notifications
33
+ AdminUser.hasMany(models.AdminNotification, {
34
+ foreignKey: "admin_id",
35
+ as: "notifications",
36
+ });
37
+
38
+ // Sessions
39
+ AdminUser.hasMany(models.AdminSession, {
40
+ foreignKey: "admin_id",
41
+ as: "sessions",
42
+ });
43
+ }
44
+ }
45
+
46
+ AdminUser.init(
47
+ {
48
+ admin_id: {
49
+ type: DataTypes.INTEGER,
50
+ primaryKey: true,
51
+ autoIncrement: true,
52
+ },
53
+ uuid: {
54
+ type: DataTypes.UUID,
55
+ defaultValue: DataTypes.UUIDV4,
56
+ allowNull: false,
57
+ unique: true,
58
+ },
59
+ first_name: {
60
+ type: DataTypes.STRING(100),
61
+ allowNull: false,
62
+ },
63
+ last_name: {
64
+ type: DataTypes.STRING(100),
65
+ allowNull: false,
66
+ },
67
+ email: {
68
+ type: DataTypes.STRING(255),
69
+ allowNull: false,
70
+ unique: true,
71
+ validate: { isEmail: true },
72
+ },
73
+ phone: {
74
+ type: DataTypes.STRING(20),
75
+ allowNull: false,
76
+ unique: true,
77
+ },
78
+ password_hash: {
79
+ type: DataTypes.STRING(255),
80
+ allowNull: false,
81
+ },
82
+ must_change_password: {
83
+ type: DataTypes.BOOLEAN,
84
+ allowNull: false,
85
+ defaultValue: false,
86
+ comment:
87
+ "True after createAdminUser — forces password change before any other action",
88
+ },
89
+ role: {
90
+ type: DataTypes.ENUM(...Object.values(ADMIN_ROLE)),
91
+ allowNull: false,
92
+ },
93
+ status: {
94
+ type: DataTypes.ENUM(...Object.values(ADMIN_STATUS)),
95
+ allowNull: false,
96
+ defaultValue: ADMIN_STATUS.ACTIVE,
97
+ },
98
+ two_factor_enabled: {
99
+ type: DataTypes.BOOLEAN,
100
+ allowNull: false,
101
+ defaultValue: true,
102
+ comment: "Mandatory for all admin accounts",
103
+ },
104
+ totp_secret: {
105
+ type: DataTypes.STRING,
106
+ allowNull: true,
107
+ },
108
+ last_login_at: {
109
+ type: DataTypes.DATE,
110
+ allowNull: true,
111
+ },
112
+ created_by: {
113
+ type: DataTypes.INTEGER,
114
+ allowNull: true,
115
+ references: { model: "admin_users", key: "admin_id" },
116
+ onDelete: "SET NULL",
117
+ comment: "Which super admin created this account",
118
+ },
119
+ },
120
+ {
121
+ sequelize,
122
+ modelName: "AdminUser",
123
+ tableName: "admin_users",
124
+ timestamps: true,
125
+ createdAt: "created_at",
126
+ updatedAt: "updated_at",
127
+ },
128
+ );
129
+
130
+ AdminUser.removeAttribute("id");
131
+ return AdminUser;
132
+ };
@@ -1,70 +1,70 @@
1
- "use strict";
2
-
3
- const { Model, DataTypes } = require("sequelize");
4
-
5
- module.exports = (sequelize) => {
6
- class AuditLog extends Model {
7
- static associate(models) {
8
- // Actor can be a regular user
9
- AuditLog.belongsTo(models.User, {
10
- foreignKey: "user_id",
11
- as: "user",
12
- });
13
-
14
- // Or an admin user — use admin_id to distinguish
15
- AuditLog.belongsTo(models.AdminUser, {
16
- foreignKey: "admin_id",
17
- as: "admin",
18
- });
19
- }
20
- }
21
-
22
- AuditLog.init(
23
- {
24
- audit_log_id: {
25
- type: DataTypes.INTEGER,
26
- primaryKey: true,
27
- autoIncrement: true,
28
- },
29
- user_id: {
30
- type: DataTypes.INTEGER,
31
- allowNull: true,
32
- references: { model: "users", key: "user_id" },
33
- onDelete: "SET NULL",
34
- comment: "Populated when the actor is a regular user",
35
- },
36
- admin_id: {
37
- type: DataTypes.INTEGER,
38
- allowNull: true,
39
- references: { model: "admin_users", key: "admin_id" },
40
- onDelete: "SET NULL",
41
- comment: "Populated when the actor is an admin",
42
- },
43
- action: {
44
- type: DataTypes.STRING(255),
45
- allowNull: false,
46
- comment: "e.g. ESCROW_RELEASED | USER_BANNED | KYC_APPROVED",
47
- },
48
- metadata_json: {
49
- type: DataTypes.JSON,
50
- allowNull: true,
51
- comment: "Contextual data — before/after values, entity IDs etc.",
52
- },
53
- ip_address: {
54
- type: DataTypes.STRING(45),
55
- allowNull: true,
56
- },
57
- },
58
- {
59
- sequelize,
60
- modelName: "AuditLog",
61
- tableName: "audit_logs",
62
- timestamps: true,
63
- createdAt: "created_at",
64
- updatedAt: false,
65
- },
66
- );
67
-
68
- AuditLog.removeAttribute("id");
69
- return AuditLog;
70
- };
1
+ "use strict";
2
+
3
+ const { Model, DataTypes } = require("sequelize");
4
+
5
+ module.exports = (sequelize) => {
6
+ class AuditLog extends Model {
7
+ static associate(models) {
8
+ // Actor can be a regular user
9
+ AuditLog.belongsTo(models.User, {
10
+ foreignKey: "user_id",
11
+ as: "user",
12
+ });
13
+
14
+ // Or an admin user — use admin_id to distinguish
15
+ AuditLog.belongsTo(models.AdminUser, {
16
+ foreignKey: "admin_id",
17
+ as: "admin",
18
+ });
19
+ }
20
+ }
21
+
22
+ AuditLog.init(
23
+ {
24
+ audit_log_id: {
25
+ type: DataTypes.INTEGER,
26
+ primaryKey: true,
27
+ autoIncrement: true,
28
+ },
29
+ user_id: {
30
+ type: DataTypes.INTEGER,
31
+ allowNull: true,
32
+ references: { model: "users", key: "user_id" },
33
+ onDelete: "SET NULL",
34
+ comment: "Populated when the actor is a regular user",
35
+ },
36
+ admin_id: {
37
+ type: DataTypes.INTEGER,
38
+ allowNull: true,
39
+ references: { model: "admin_users", key: "admin_id" },
40
+ onDelete: "SET NULL",
41
+ comment: "Populated when the actor is an admin",
42
+ },
43
+ action: {
44
+ type: DataTypes.STRING(255),
45
+ allowNull: false,
46
+ comment: "e.g. ESCROW_RELEASED | USER_BANNED | KYC_APPROVED",
47
+ },
48
+ metadata_json: {
49
+ type: DataTypes.JSON,
50
+ allowNull: true,
51
+ comment: "Contextual data — before/after values, entity IDs etc.",
52
+ },
53
+ ip_address: {
54
+ type: DataTypes.STRING(45),
55
+ allowNull: true,
56
+ },
57
+ },
58
+ {
59
+ sequelize,
60
+ modelName: "AuditLog",
61
+ tableName: "audit_logs",
62
+ timestamps: true,
63
+ createdAt: "created_at",
64
+ updatedAt: false,
65
+ },
66
+ );
67
+
68
+ AuditLog.removeAttribute("id");
69
+ return AuditLog;
70
+ };