vr-models 1.0.1 → 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.
@@ -1,8 +1,25 @@
1
- import { Model, InferAttributes, InferCreationAttributes, CreationOptional, NonAttribute } from "vr-migrations";
1
+ import { Model, InferAttributes, InferCreationAttributes, CreationOptional, NonAttribute, ModelStatic } from "vr-migrations";
2
2
  import type { Product } from "./product.models";
3
3
  import type { DevicePaymentPlan } from "./devicePaymentPlan.models";
4
4
  export type DeviceStatus = "locked" | "unlocked" | "disabled";
5
- export declare class Device extends Model<InferAttributes<Device>, InferCreationAttributes<Device>> {
5
+ export interface DeviceAttributes {
6
+ id: string;
7
+ serialNumber: string;
8
+ productId: string;
9
+ status: DeviceStatus;
10
+ isPermanentlyUnlocked: boolean;
11
+ activatedAt: Date | null;
12
+ createdAt: Date;
13
+ updatedAt: Date;
14
+ product?: Product;
15
+ paymentPlans?: DevicePaymentPlan[];
16
+ }
17
+ export interface DeviceCreationAttributes extends Omit<DeviceAttributes, "id" | "createdAt" | "updatedAt" | "status" | "isPermanentlyUnlocked"> {
18
+ id?: string;
19
+ status?: DeviceStatus;
20
+ isPermanentlyUnlocked?: boolean;
21
+ }
22
+ export declare class Device extends Model<InferAttributes<Device>, InferCreationAttributes<Device>> implements DeviceAttributes {
6
23
  id: CreationOptional<string>;
7
24
  serialNumber: string;
8
25
  productId: string;
@@ -13,6 +30,14 @@ export declare class Device extends Model<InferAttributes<Device>, InferCreation
13
30
  readonly updatedAt: CreationOptional<Date>;
14
31
  product?: NonAttribute<Product>;
15
32
  paymentPlans?: NonAttribute<DevicePaymentPlan[]>;
33
+ static initialize(sequelize: any): void;
34
+ static associate(models: Record<string, ModelStatic<Model>>): void;
35
+ activate(): Promise<void>;
36
+ lock(): Promise<void>;
37
+ unlock(): Promise<void>;
38
+ disable(): Promise<void>;
39
+ makePermanent(): Promise<void>;
40
+ isActive(): boolean;
41
+ canBeActivated(): boolean;
16
42
  }
17
- export declare const initDeviceModel: (sequelize: any) => void;
18
43
  export type DeviceModel = typeof Device;
@@ -1,55 +1,98 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.initDeviceModel = exports.Device = void 0;
3
+ exports.Device = void 0;
4
4
  // src/models/device.models.ts
5
5
  const vr_migrations_1 = require("vr-migrations");
6
6
  class Device extends vr_migrations_1.Model {
7
+ // Static initialization method
8
+ static initialize(sequelize) {
9
+ this.init({
10
+ id: {
11
+ type: vr_migrations_1.DataTypes.UUID,
12
+ defaultValue: vr_migrations_1.DataTypes.UUIDV4,
13
+ primaryKey: true,
14
+ },
15
+ serialNumber: {
16
+ type: vr_migrations_1.DataTypes.STRING(64),
17
+ allowNull: false,
18
+ unique: true,
19
+ },
20
+ productId: {
21
+ type: vr_migrations_1.DataTypes.UUID,
22
+ allowNull: false,
23
+ },
24
+ status: {
25
+ type: vr_migrations_1.DataTypes.ENUM("locked", "unlocked", "disabled"),
26
+ allowNull: false,
27
+ defaultValue: "locked",
28
+ },
29
+ isPermanentlyUnlocked: {
30
+ type: vr_migrations_1.DataTypes.BOOLEAN,
31
+ allowNull: false,
32
+ defaultValue: false,
33
+ },
34
+ activatedAt: {
35
+ type: vr_migrations_1.DataTypes.DATE,
36
+ allowNull: true,
37
+ },
38
+ createdAt: {
39
+ type: vr_migrations_1.DataTypes.DATE,
40
+ defaultValue: vr_migrations_1.DataTypes.NOW,
41
+ },
42
+ updatedAt: {
43
+ type: vr_migrations_1.DataTypes.DATE,
44
+ defaultValue: vr_migrations_1.DataTypes.NOW,
45
+ },
46
+ }, {
47
+ sequelize,
48
+ modelName: "Device",
49
+ tableName: "devices",
50
+ timestamps: true,
51
+ freezeTableName: true,
52
+ });
53
+ }
54
+ // Static association method
55
+ static associate(models) {
56
+ this.belongsTo(models.Product, {
57
+ foreignKey: "productId",
58
+ as: "product",
59
+ onDelete: "RESTRICT",
60
+ onUpdate: "CASCADE",
61
+ });
62
+ this.hasMany(models.DevicePaymentPlan, {
63
+ foreignKey: "deviceId",
64
+ as: "paymentPlans",
65
+ onDelete: "CASCADE",
66
+ onUpdate: "CASCADE",
67
+ });
68
+ }
69
+ // Custom instance methods
70
+ async activate() {
71
+ this.status = "unlocked";
72
+ this.activatedAt = new Date();
73
+ await this.save();
74
+ }
75
+ async lock() {
76
+ this.status = "locked";
77
+ await this.save();
78
+ }
79
+ async unlock() {
80
+ this.status = "unlocked";
81
+ await this.save();
82
+ }
83
+ async disable() {
84
+ this.status = "disabled";
85
+ await this.save();
86
+ }
87
+ async makePermanent() {
88
+ this.isPermanentlyUnlocked = true;
89
+ await this.save();
90
+ }
91
+ isActive() {
92
+ return this.status === "unlocked" || this.isPermanentlyUnlocked;
93
+ }
94
+ canBeActivated() {
95
+ return this.status !== "disabled";
96
+ }
7
97
  }
8
98
  exports.Device = Device;
9
- const initDeviceModel = (sequelize) => {
10
- Device.init({
11
- id: {
12
- type: vr_migrations_1.DataTypes.UUID,
13
- defaultValue: vr_migrations_1.DataTypes.UUIDV4,
14
- primaryKey: true,
15
- },
16
- serialNumber: {
17
- type: vr_migrations_1.DataTypes.STRING(64),
18
- allowNull: false,
19
- unique: true,
20
- },
21
- productId: {
22
- type: vr_migrations_1.DataTypes.UUID,
23
- allowNull: false,
24
- },
25
- status: {
26
- type: vr_migrations_1.DataTypes.ENUM("locked", "unlocked", "disabled"),
27
- allowNull: false,
28
- defaultValue: "locked",
29
- },
30
- isPermanentlyUnlocked: {
31
- type: vr_migrations_1.DataTypes.BOOLEAN,
32
- allowNull: false,
33
- defaultValue: false,
34
- },
35
- activatedAt: {
36
- type: vr_migrations_1.DataTypes.DATE,
37
- allowNull: true,
38
- },
39
- createdAt: {
40
- type: vr_migrations_1.DataTypes.DATE,
41
- defaultValue: vr_migrations_1.DataTypes.NOW,
42
- },
43
- updatedAt: {
44
- type: vr_migrations_1.DataTypes.DATE,
45
- defaultValue: vr_migrations_1.DataTypes.NOW,
46
- },
47
- }, {
48
- sequelize,
49
- modelName: "Device",
50
- tableName: "devices",
51
- timestamps: true,
52
- freezeTableName: true,
53
- });
54
- };
55
- exports.initDeviceModel = initDeviceModel;
@@ -1,9 +1,38 @@
1
- import { Model, InferAttributes, InferCreationAttributes, CreationOptional, NonAttribute } from "vr-migrations";
1
+ import { Model, InferAttributes, InferCreationAttributes, CreationOptional, NonAttribute, ModelStatic } from "vr-migrations";
2
2
  import type { Device } from "./device.models";
3
3
  import type { User } from "./user.models";
4
4
  export type PaymentPlanStatus = "ACTIVE" | "COMPLETED" | "DEFAULTED" | "CANCELLED";
5
- export type InstallmentFrequency = "daily" | "weekly" | "monthly";
6
- export declare class DevicePaymentPlan extends Model<InferAttributes<DevicePaymentPlan>, InferCreationAttributes<DevicePaymentPlan>> {
5
+ export type InstallmentFrequency = "DAILY" | "WEEKLY" | "MONTHLY";
6
+ export interface DevicePaymentPlanAttributes {
7
+ id: string;
8
+ deviceId: string;
9
+ userId: string;
10
+ pricingSnapshot: Record<string, any>;
11
+ totalAmount: number;
12
+ downPayment: number;
13
+ installmentAmount: number;
14
+ installmentFrequency: InstallmentFrequency;
15
+ paidAmount: number;
16
+ outstandingAmount: number;
17
+ lastPaymentAt: Date | null;
18
+ nextInstallmentDueAt: Date | null;
19
+ gracePeriodDays: number;
20
+ autoLockOnMiss: boolean;
21
+ status: PaymentPlanStatus;
22
+ completedAt: Date | null;
23
+ createdAt: Date;
24
+ updatedAt: Date;
25
+ device?: Device;
26
+ user?: User;
27
+ }
28
+ export interface DevicePaymentPlanCreationAttributes extends Omit<DevicePaymentPlanAttributes, "id" | "createdAt" | "updatedAt" | "paidAmount" | "status" | "gracePeriodDays" | "autoLockOnMiss"> {
29
+ id?: string;
30
+ paidAmount?: number;
31
+ status?: PaymentPlanStatus;
32
+ gracePeriodDays?: number;
33
+ autoLockOnMiss?: boolean;
34
+ }
35
+ export declare class DevicePaymentPlan extends Model<InferAttributes<DevicePaymentPlan>, InferCreationAttributes<DevicePaymentPlan>> implements DevicePaymentPlanAttributes {
7
36
  id: CreationOptional<string>;
8
37
  deviceId: string;
9
38
  userId: string;
@@ -24,6 +53,14 @@ export declare class DevicePaymentPlan extends Model<InferAttributes<DevicePayme
24
53
  readonly updatedAt: CreationOptional<Date>;
25
54
  device?: NonAttribute<Device>;
26
55
  user?: NonAttribute<User>;
56
+ static initialize(sequelize: any): void;
57
+ static associate(models: Record<string, ModelStatic<Model>>): void;
58
+ makePayment(amount: number): Promise<void>;
59
+ markAsDefaulted(): Promise<void>;
60
+ cancel(): Promise<void>;
61
+ calculateProgress(): number;
62
+ isOverdue(): boolean;
63
+ getDaysOverdue(): number;
64
+ shouldAutoLock(): boolean;
27
65
  }
28
- export declare const initDevicePaymentPlanModel: (sequelize: any) => void;
29
66
  export type DevicePaymentPlanModel = typeof DevicePaymentPlan;
@@ -1,98 +1,166 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.initDevicePaymentPlanModel = exports.DevicePaymentPlan = void 0;
3
+ exports.DevicePaymentPlan = void 0;
4
4
  // src/models/devicePaymentPlan.models.ts
5
5
  const vr_migrations_1 = require("vr-migrations");
6
6
  class DevicePaymentPlan extends vr_migrations_1.Model {
7
+ // Static initialization method
8
+ static initialize(sequelize) {
9
+ this.init({
10
+ id: {
11
+ type: vr_migrations_1.DataTypes.UUID,
12
+ defaultValue: vr_migrations_1.DataTypes.UUIDV4,
13
+ primaryKey: true,
14
+ },
15
+ deviceId: {
16
+ type: vr_migrations_1.DataTypes.UUID,
17
+ allowNull: false,
18
+ unique: true,
19
+ },
20
+ userId: {
21
+ type: vr_migrations_1.DataTypes.UUID,
22
+ allowNull: false,
23
+ },
24
+ pricingSnapshot: {
25
+ type: vr_migrations_1.DataTypes.JSONB,
26
+ allowNull: false,
27
+ },
28
+ totalAmount: {
29
+ type: vr_migrations_1.DataTypes.FLOAT,
30
+ allowNull: false,
31
+ },
32
+ downPayment: {
33
+ type: vr_migrations_1.DataTypes.FLOAT,
34
+ allowNull: false,
35
+ },
36
+ installmentAmount: {
37
+ type: vr_migrations_1.DataTypes.FLOAT,
38
+ allowNull: false,
39
+ },
40
+ installmentFrequency: {
41
+ type: vr_migrations_1.DataTypes.ENUM("DAILY", "WEEKLY", "MONTHLY"),
42
+ allowNull: false,
43
+ defaultValue: "WEEKLY",
44
+ },
45
+ paidAmount: {
46
+ type: vr_migrations_1.DataTypes.FLOAT,
47
+ allowNull: false,
48
+ defaultValue: 0,
49
+ },
50
+ outstandingAmount: {
51
+ type: vr_migrations_1.DataTypes.FLOAT,
52
+ allowNull: false,
53
+ },
54
+ lastPaymentAt: {
55
+ type: vr_migrations_1.DataTypes.DATE,
56
+ allowNull: true,
57
+ },
58
+ nextInstallmentDueAt: {
59
+ type: vr_migrations_1.DataTypes.DATE,
60
+ allowNull: true,
61
+ },
62
+ gracePeriodDays: {
63
+ type: vr_migrations_1.DataTypes.INTEGER,
64
+ allowNull: false,
65
+ defaultValue: 2,
66
+ },
67
+ autoLockOnMiss: {
68
+ type: vr_migrations_1.DataTypes.BOOLEAN,
69
+ allowNull: false,
70
+ defaultValue: true,
71
+ },
72
+ status: {
73
+ type: vr_migrations_1.DataTypes.ENUM("ACTIVE", "COMPLETED", "DEFAULTED", "CANCELLED"),
74
+ allowNull: false,
75
+ defaultValue: "ACTIVE",
76
+ },
77
+ completedAt: {
78
+ type: vr_migrations_1.DataTypes.DATE,
79
+ allowNull: true,
80
+ },
81
+ createdAt: {
82
+ type: vr_migrations_1.DataTypes.DATE,
83
+ defaultValue: vr_migrations_1.DataTypes.NOW,
84
+ },
85
+ updatedAt: {
86
+ type: vr_migrations_1.DataTypes.DATE,
87
+ defaultValue: vr_migrations_1.DataTypes.NOW,
88
+ },
89
+ }, {
90
+ sequelize,
91
+ modelName: "DevicePaymentPlan",
92
+ tableName: "device_payment_plans",
93
+ timestamps: true,
94
+ freezeTableName: true,
95
+ });
96
+ }
97
+ // Static association method
98
+ static associate(models) {
99
+ this.belongsTo(models.Device, {
100
+ foreignKey: "deviceId",
101
+ as: "device",
102
+ onDelete: "CASCADE",
103
+ onUpdate: "CASCADE",
104
+ });
105
+ this.belongsTo(models.User, {
106
+ foreignKey: "userId",
107
+ as: "user",
108
+ onDelete: "CASCADE",
109
+ onUpdate: "CASCADE",
110
+ });
111
+ }
112
+ // Custom instance methods
113
+ async makePayment(amount) {
114
+ this.paidAmount = (this.paidAmount || 0) + amount;
115
+ this.outstandingAmount = Math.max(0, this.outstandingAmount - amount);
116
+ this.lastPaymentAt = new Date();
117
+ // Update next installment due date
118
+ if (this.installmentFrequency === "DAILY") {
119
+ this.nextInstallmentDueAt = new Date(Date.now() + 24 * 60 * 60 * 1000);
120
+ }
121
+ else if (this.installmentFrequency === "WEEKLY") {
122
+ this.nextInstallmentDueAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
123
+ }
124
+ else if (this.installmentFrequency === "MONTHLY") {
125
+ this.nextInstallmentDueAt = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);
126
+ }
127
+ // Check if completed
128
+ if (this.outstandingAmount <= 0) {
129
+ this.status = "COMPLETED";
130
+ this.completedAt = new Date();
131
+ }
132
+ await this.save();
133
+ }
134
+ async markAsDefaulted() {
135
+ this.status = "DEFAULTED";
136
+ await this.save();
137
+ }
138
+ async cancel() {
139
+ this.status = "CANCELLED";
140
+ await this.save();
141
+ }
142
+ calculateProgress() {
143
+ return (this.paidAmount / this.totalAmount) * 100;
144
+ }
145
+ isOverdue() {
146
+ if (!this.nextInstallmentDueAt || this.status !== "ACTIVE") {
147
+ return false;
148
+ }
149
+ const overdueDate = new Date(this.nextInstallmentDueAt);
150
+ overdueDate.setDate(overdueDate.getDate() + this.gracePeriodDays);
151
+ return new Date() > overdueDate;
152
+ }
153
+ getDaysOverdue() {
154
+ if (!this.isOverdue() || !this.nextInstallmentDueAt) {
155
+ return 0;
156
+ }
157
+ const overdueDate = new Date(this.nextInstallmentDueAt);
158
+ overdueDate.setDate(overdueDate.getDate() + this.gracePeriodDays);
159
+ const diffTime = Math.abs(new Date().getTime() - overdueDate.getTime());
160
+ return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
161
+ }
162
+ shouldAutoLock() {
163
+ return this.autoLockOnMiss && this.isOverdue();
164
+ }
7
165
  }
8
166
  exports.DevicePaymentPlan = DevicePaymentPlan;
9
- const initDevicePaymentPlanModel = (sequelize) => {
10
- DevicePaymentPlan.init({
11
- id: {
12
- type: vr_migrations_1.DataTypes.UUID,
13
- defaultValue: vr_migrations_1.DataTypes.UUIDV4,
14
- primaryKey: true,
15
- },
16
- deviceId: {
17
- type: vr_migrations_1.DataTypes.UUID,
18
- allowNull: false,
19
- unique: true,
20
- },
21
- userId: {
22
- type: vr_migrations_1.DataTypes.UUID,
23
- allowNull: false,
24
- },
25
- pricingSnapshot: {
26
- type: vr_migrations_1.DataTypes.JSONB,
27
- allowNull: false,
28
- },
29
- totalAmount: {
30
- type: vr_migrations_1.DataTypes.FLOAT,
31
- allowNull: false,
32
- },
33
- downPayment: {
34
- type: vr_migrations_1.DataTypes.FLOAT,
35
- allowNull: false,
36
- },
37
- installmentAmount: {
38
- type: vr_migrations_1.DataTypes.FLOAT,
39
- allowNull: false,
40
- },
41
- installmentFrequency: {
42
- type: vr_migrations_1.DataTypes.ENUM("DAILY", "WEEKLY", "MONTHLY"),
43
- allowNull: false,
44
- defaultValue: "WEEKLY",
45
- },
46
- paidAmount: {
47
- type: vr_migrations_1.DataTypes.FLOAT,
48
- allowNull: false,
49
- defaultValue: 0,
50
- },
51
- outstandingAmount: {
52
- type: vr_migrations_1.DataTypes.FLOAT,
53
- allowNull: false,
54
- },
55
- lastPaymentAt: {
56
- type: vr_migrations_1.DataTypes.DATE,
57
- allowNull: true,
58
- },
59
- nextInstallmentDueAt: {
60
- type: vr_migrations_1.DataTypes.DATE,
61
- allowNull: true,
62
- },
63
- gracePeriodDays: {
64
- type: vr_migrations_1.DataTypes.INTEGER,
65
- allowNull: false,
66
- defaultValue: 2,
67
- },
68
- autoLockOnMiss: {
69
- type: vr_migrations_1.DataTypes.BOOLEAN,
70
- allowNull: false,
71
- defaultValue: true,
72
- },
73
- status: {
74
- type: vr_migrations_1.DataTypes.ENUM("ACTIVE", "COMPLETED", "DEFAULTED", "CANCELLED"),
75
- allowNull: false,
76
- defaultValue: "ACTIVE",
77
- },
78
- completedAt: {
79
- type: vr_migrations_1.DataTypes.DATE,
80
- allowNull: true,
81
- },
82
- createdAt: {
83
- type: vr_migrations_1.DataTypes.DATE,
84
- defaultValue: vr_migrations_1.DataTypes.NOW,
85
- },
86
- updatedAt: {
87
- type: vr_migrations_1.DataTypes.DATE,
88
- defaultValue: vr_migrations_1.DataTypes.NOW,
89
- },
90
- }, {
91
- sequelize,
92
- modelName: "DevicePaymentPlan",
93
- tableName: "device_payment_plans",
94
- timestamps: true,
95
- freezeTableName: true,
96
- });
97
- };
98
- exports.initDevicePaymentPlanModel = initDevicePaymentPlanModel;
@@ -1,18 +1,45 @@
1
- import { Model, InferAttributes, InferCreationAttributes, CreationOptional } from "vr-migrations";
1
+ import { Model, InferAttributes, InferCreationAttributes, CreationOptional, NonAttribute, ModelStatic } from "vr-migrations";
2
+ import type { User } from "./user.models";
2
3
  export declare const EVENT_ACTIONS: readonly ["USER_READ", "USER_UPDATED", "USERS_LISTED", "ADMIN_FORGOT_PASSWORD", "ADMIN_LOGGED_IN", "ADMIN_LOGGED_OUT", "PASSENGER_ACCOUNT_DEACTIVATED", "PASSENGER_ACCOUNT_DELETED", "AGENT_CREATED_RIDER", "AGENT_UPDATED_RIDER", "ADMIN_CREATED_USER", "ADMIN_UPDATED_USER", "SUPER_ADMIN_PASSWORD_CHANGED", "SUPER_ADMIN_CHANGED_USER_ACCOUNT_STATUS", "SUPER_ADMIN_UPDATED_USER", "SUPER_ADMIN_CREATED_USER", "PRODUCT_CREATED", "PRODUCT_READ", "PRODUCT_UPDATED", "PRODUCT_DELETED", "PRODUCTS_LISTED", "DEVICE_ASSIGNED", "DEVICE_READ", "DEVICE_UPDATED", "DEVICES_LISTED", "DEVICE_REPOSSESSED", "DEVICE_PAYMENT_PLAN_CREATED", "DEVICE_PAYMENT_PLAN_READ", "DEVICE_PAYMENT_PLAN_UPDATED", "DEVICE_PAYMENT_DEFAULT_MARKED", "PAYMENT_CREATED", "PAYMENT_READ", "PAYMENTS_LISTED", "TRANSACTION_READ", "TRANSACTIONS_LISTED", "EVENT_LOG_READ", "EVENT_LOGS_LISTED", "SECURITY_CLEARANCE_MANAGED", "DEVICE_LOCK_OVERRIDDEN"];
3
4
  export type EventAction = (typeof EVENT_ACTIONS)[number];
4
5
  export type EventActorType = "USER" | "SYSTEM";
5
- export declare class EventLog extends Model<InferAttributes<EventLog>, InferCreationAttributes<EventLog>> {
6
- id: CreationOptional<string>;
6
+ export interface EventLogAttributes {
7
+ id: string;
8
+ actorType: EventActorType;
9
+ actorId: string | null;
10
+ action: EventAction;
11
+ entity: string;
12
+ entityId: string | null;
13
+ metadata: Record<string, any>;
14
+ ipAddress: string | null;
15
+ userAgent: string | null;
16
+ createdAt: Date;
17
+ actor?: User;
18
+ }
19
+ export interface EventLogCreationAttributes extends Omit<EventLogAttributes, "id" | "createdAt" | "metadata" | "actorType"> {
20
+ id?: string;
21
+ metadata?: Record<string, any>;
7
22
  actorType?: EventActorType;
23
+ }
24
+ export declare class EventLog extends Model<InferAttributes<EventLog>, InferCreationAttributes<EventLog>> implements EventLogAttributes {
25
+ id: CreationOptional<string>;
26
+ actorType: CreationOptional<EventActorType>;
8
27
  actorId: CreationOptional<string | null>;
9
28
  action: EventAction;
10
29
  entity: string;
11
- entityId?: CreationOptional<string | null>;
12
- metadata?: CreationOptional<Record<string, any>>;
13
- ipAddress?: CreationOptional<string | null>;
14
- userAgent?: CreationOptional<string | null>;
30
+ entityId: CreationOptional<string | null>;
31
+ metadata: CreationOptional<Record<string, any>>;
32
+ ipAddress: CreationOptional<string | null>;
33
+ userAgent: CreationOptional<string | null>;
15
34
  readonly createdAt: CreationOptional<Date>;
35
+ actor?: NonAttribute<User>;
16
36
  static initialize(sequelize: any): void;
37
+ static associate(models: Record<string, ModelStatic<Model>>): void;
38
+ static logEvent(data: Omit<EventLogCreationAttributes, "id" | "createdAt">): Promise<EventLog>;
39
+ static getUserEvents(userId: string, limit?: number): Promise<EventLog[]>;
40
+ static getEntityEvents(entity: string, entityId: string, limit?: number): Promise<EventLog[]>;
41
+ getSummary(): string;
42
+ isUserAction(): boolean;
43
+ isSystemAction(): boolean;
17
44
  }
18
45
  export type EventLogModel = typeof EventLog;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EventLog = exports.EVENT_ACTIONS = void 0;
4
4
  const vr_migrations_1 = require("vr-migrations");
5
+ // Constants
5
6
  exports.EVENT_ACTIONS = [
6
7
  "USER_READ",
7
8
  "USER_UPDATED",
@@ -44,6 +45,7 @@ exports.EVENT_ACTIONS = [
44
45
  "DEVICE_LOCK_OVERRIDDEN",
45
46
  ];
46
47
  class EventLog extends vr_migrations_1.Model {
48
+ // Static initialization method
47
49
  static initialize(sequelize) {
48
50
  this.init({
49
51
  id: {
@@ -54,6 +56,7 @@ class EventLog extends vr_migrations_1.Model {
54
56
  actorType: {
55
57
  type: vr_migrations_1.DataTypes.ENUM("USER", "SYSTEM"),
56
58
  allowNull: false,
59
+ defaultValue: "SYSTEM",
57
60
  },
58
61
  actorId: {
59
62
  type: vr_migrations_1.DataTypes.UUID,
@@ -96,5 +99,42 @@ class EventLog extends vr_migrations_1.Model {
96
99
  updatedAt: false,
97
100
  });
98
101
  }
102
+ // Static association method
103
+ static associate(models) {
104
+ this.belongsTo(models.User, {
105
+ foreignKey: "actorId",
106
+ as: "actor",
107
+ constraints: false, // Since actor can be SYSTEM
108
+ onDelete: "SET NULL",
109
+ onUpdate: "CASCADE",
110
+ });
111
+ }
112
+ // Custom instance methods
113
+ static async logEvent(data) {
114
+ return await this.create(data);
115
+ }
116
+ static async getUserEvents(userId, limit = 50) {
117
+ return await this.findAll({
118
+ where: { actorId: userId },
119
+ order: [["createdAt", "DESC"]],
120
+ limit,
121
+ });
122
+ }
123
+ static async getEntityEvents(entity, entityId, limit = 50) {
124
+ return await this.findAll({
125
+ where: { entity, entityId },
126
+ order: [["createdAt", "DESC"]],
127
+ limit,
128
+ });
129
+ }
130
+ getSummary() {
131
+ return `${this.actorType}:${this.actorId || "SYSTEM"} performed ${this.action} on ${this.entity}${this.entityId ? `:${this.entityId}` : ""}`;
132
+ }
133
+ isUserAction() {
134
+ return this.actorType === "USER";
135
+ }
136
+ isSystemAction() {
137
+ return this.actorType === "SYSTEM";
138
+ }
99
139
  }
100
140
  exports.EventLog = EventLog;
@@ -1,5 +1,22 @@
1
- import { Model, InferAttributes, InferCreationAttributes, CreationOptional } from "vr-migrations";
2
- export declare class IdempotencyRecord extends Model<InferAttributes<IdempotencyRecord>, InferCreationAttributes<IdempotencyRecord>> {
1
+ import { Model, InferAttributes, InferCreationAttributes, CreationOptional, ModelStatic } from "vr-migrations";
2
+ export interface IdempotencyRecordAttributes {
3
+ id: string;
4
+ key: string;
5
+ requestMethod: string;
6
+ requestPath: string;
7
+ requestParams: Record<string, any> | null;
8
+ responseStatusCode: number | null;
9
+ responseBody: Record<string, any>;
10
+ createdAt: Date;
11
+ expiresAt: Date;
12
+ }
13
+ export interface IdempotencyRecordCreationAttributes extends Omit<IdempotencyRecordAttributes, "id" | "createdAt" | "expiresAt" | "requestParams" | "responseBody" | "responseStatusCode"> {
14
+ id?: string;
15
+ requestParams?: Record<string, any> | null;
16
+ responseBody?: Record<string, any>;
17
+ responseStatusCode?: number | null;
18
+ }
19
+ export declare class IdempotencyRecord extends Model<InferAttributes<IdempotencyRecord>, InferCreationAttributes<IdempotencyRecord>> implements IdempotencyRecordAttributes {
3
20
  id: CreationOptional<string>;
4
21
  key: string;
5
22
  requestMethod: string;
@@ -10,5 +27,13 @@ export declare class IdempotencyRecord extends Model<InferAttributes<Idempotency
10
27
  readonly createdAt: CreationOptional<Date>;
11
28
  expiresAt: Date;
12
29
  static initialize(sequelize: any): void;
30
+ static associate(models: Record<string, ModelStatic<Model>>): void;
31
+ static invalidate(key: string): Promise<boolean>;
32
+ isValid(): boolean;
33
+ isExpired(): boolean;
34
+ getResponse(): {
35
+ statusCode: number | null;
36
+ body: Record<string, any>;
37
+ } | null;
13
38
  }
14
39
  export type IdempotencyRecordModel = typeof IdempotencyRecord;