codebase-models 2.1.23 → 3.0.0

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 (43) hide show
  1. package/.github/workflows/npm-publish-stage.yml +33 -0
  2. package/dist/index.d.ts +8 -5
  3. package/dist/index.js +17 -10
  4. package/dist/src/constant.d.ts +25 -1
  5. package/dist/src/constant.js +100 -3
  6. package/dist/src/models/Client.d.ts +1 -1
  7. package/dist/src/models/Client.js +7 -4
  8. package/dist/src/models/{SegmentCombination.d.ts → Invitation.d.ts} +15 -14
  9. package/dist/src/models/Invitation.js +55 -0
  10. package/dist/src/models/Organization.d.ts +8 -15
  11. package/dist/src/models/Organization.js +10 -58
  12. package/dist/src/models/{QueryLog.d.ts → Package.d.ts} +7 -7
  13. package/dist/src/models/{QueryLog.js → Package.js} +10 -19
  14. package/dist/src/models/Role.js +16 -7
  15. package/dist/src/models/{Segment.d.ts → Thread.d.ts} +7 -10
  16. package/dist/src/models/Thread.js +78 -0
  17. package/dist/src/models/ThreadMessage.d.ts +35 -0
  18. package/dist/src/models/ThreadMessage.js +86 -0
  19. package/dist/src/models/User.d.ts +8 -5
  20. package/dist/src/models/User.js +13 -37
  21. package/dist/src/models/UserIdentity.d.ts +35 -0
  22. package/dist/src/models/{SegmentCombination.js → UserIdentity.js} +11 -47
  23. package/dist/src/models/UserOrganization.d.ts +33 -0
  24. package/dist/src/models/{Segment.js → UserOrganization.js} +10 -33
  25. package/dist/src/models/UserPermission.d.ts +4 -11
  26. package/dist/src/models/UserPermission.js +27 -10
  27. package/index.ts +18 -11
  28. package/package.json +1 -1
  29. package/src/constant.ts +104 -4
  30. package/src/models/Client.ts +8 -5
  31. package/src/models/Invitation.ts +50 -0
  32. package/src/models/Organization.ts +18 -73
  33. package/src/models/Package.ts +24 -0
  34. package/src/models/Role.ts +51 -39
  35. package/src/models/Thread.ts +57 -0
  36. package/src/models/ThreadMessage.ts +67 -0
  37. package/src/models/User.ts +21 -43
  38. package/src/models/UserIdentity.ts +26 -0
  39. package/src/models/UserOrganization.ts +23 -0
  40. package/src/models/UserPermission.ts +31 -21
  41. package/src/models/QueryLog.ts +0 -35
  42. package/src/models/Segment.ts +0 -50
  43. package/src/models/SegmentCombination.ts +0 -68
package/src/constant.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { v4 as uuidv4 } from 'uuid';
1
+ import { v4 as uuidv4 } from "uuid";
2
2
 
3
3
  const HypothesisSheetConstants = {
4
4
  NO: 0,
@@ -13,6 +13,15 @@ const HypothesisSheetConstants = {
13
13
  GOOD: 2,
14
14
  };
15
15
 
16
+ const RolesConstants = [
17
+ "USER",
18
+ "ADMIN",
19
+ "CLIENT",
20
+ "EXTERNAL",
21
+ "QA",
22
+ "OPTIMIZER",
23
+ ];
24
+
16
25
  /**
17
26
  * Generates a random unique identifier
18
27
  * @returns A 12-character uppercase string (increased from 8 for better uniqueness)
@@ -21,11 +30,102 @@ const HypothesisSheetConstants = {
21
30
  const generateRandomIID = (): string => {
22
31
  try {
23
32
  // Take first 12 characters instead of 8 for better uniqueness
24
- return uuidv4().replace(/-/g, '').substring(0, 12).toUpperCase();
33
+ return uuidv4().replace(/-/g, "").substring(0, 12).toUpperCase();
25
34
  } catch (error) {
26
- throw new Error(`Failed to generate random IID: ${error instanceof Error ? error.message : 'Unknown error'}`);
35
+ throw new Error(
36
+ `Failed to generate random IID: ${
37
+ error instanceof Error ? error.message : "Unknown error"
38
+ }`
39
+ );
27
40
  }
28
41
  };
42
+ const PermissionsConstants = {
43
+ dashboard: "dashboard",
44
+ reporting: "reporting",
45
+ insights: "insights",
46
+ documentsAndLinks: "documentsAndLinks",
47
+ cvrReports: "cvrReports",
48
+ abTesting: "abTesting",
49
+ abTestingDefault: "abTestingDefault",
50
+ manageOrganizations: "manageOrganizations",
51
+ manageInvitations: "manageInvitations",
52
+ manageClients: "manageClients",
53
+ };
54
+
55
+ const PackageFeaturesConstants = [
56
+ {
57
+ name: "DASHBOARD",
58
+ value: true,
59
+ description: "Access to the dashboard",
60
+ allowedCount: null,
61
+ },
62
+ {
63
+ name: "REPORTING",
64
+ value: true,
65
+ description: "Access to the reporting",
66
+ allowedCount: null,
67
+ },
68
+ {
69
+ name: "INSIGHTS",
70
+ value: true,
71
+ description: "Access to the insights",
72
+ allowedCount: null,
73
+ },
74
+ {
75
+ name: "DOCUMENTSANDLINKS",
76
+ value: true,
77
+ description: "Access to the documents and links",
78
+ allowedCount: 5,
79
+ },
80
+ {
81
+ name: "CVRREPORTS",
82
+ value: true,
83
+ description: "Access to the cvr reports",
84
+ allowedCount: null,
85
+ },
86
+ {
87
+ name: "ABTESTING",
88
+ value: false,
89
+ description: "Access to the ab testing",
90
+ allowedCount: null,
91
+ },
92
+ {
93
+ name: "ABTESTINGDEFAULT",
94
+ value: true,
95
+ description: "Access to the ab testing default",
96
+ allowedCount: null,
97
+ },
98
+ {
99
+ name: "MANAGEEXPERIMENTS",
100
+ value: true,
101
+ description: "Access to the experiments",
102
+ allowedCount: null,
103
+ },
104
+ {
105
+ name: "PRECALCULATIONS",
106
+ value: false,
107
+ description: "Access to the pre calculations",
108
+ allowedCount: null,
109
+ },
110
+ {
111
+ name: "MANAGEORGANIZATIONS",
112
+ value: true,
113
+ description: "Access to the organizations",
114
+ allowedCount: 1,
115
+ },
116
+ {
117
+ name: "MANAGEINVITATIONS",
118
+ value: true,
119
+ description: "Access to the invitations",
120
+ allowedCount: 1,
121
+ },
122
+ {
123
+ name: "MANAGECLIENTS",
124
+ value: true,
125
+ description: "Access to the clients",
126
+ allowedCount: 3,
127
+ },
128
+ ];
29
129
 
30
- export { generateRandomIID };
130
+ export { generateRandomIID, RolesConstants, PermissionsConstants, PackageFeaturesConstants };
31
131
  export default HypothesisSheetConstants;
@@ -18,7 +18,7 @@ const PropertySchema: Schema = new Schema<IProperty>({
18
18
 
19
19
  export interface IClient extends Document {
20
20
  iid: string;
21
- organizationId?: mongoose.Schema.Types.ObjectId;
21
+ organization: mongoose.Schema.Types.ObjectId;
22
22
  name: string;
23
23
  slug?: string;
24
24
  viewId?: string;
@@ -42,10 +42,14 @@ const ClientSchema: Schema = new Schema<IClient>(
42
42
  iid: {
43
43
  type: String,
44
44
  trim: true,
45
+ unique: true,
46
+ default: () => generateRandomIID()
45
47
  },
46
- organizationId: { type: mongoose.Schema.Types.ObjectId,
48
+ organization: { type: mongoose.Schema.Types.ObjectId,
47
49
  ref: "organization",
48
- default: null },
50
+ default: null,
51
+ required: true
52
+ },
49
53
  name: { type: String, required: true },
50
54
  slug: {
51
55
  type: String,
@@ -96,10 +100,9 @@ ClientSchema.pre('save', async function(next) {
96
100
  next();
97
101
  });
98
102
 
99
- ClientSchema.index({ iid: 1 }, { unique: true });
100
103
  // Add compound indexes for better query performance
101
104
  ClientSchema.index({ active: 1 });
102
- ClientSchema.index({ organizationId: 1, active: 1 });
105
+ ClientSchema.index({ organization: 1, active: 1 });
103
106
  ClientSchema.index({ name: 1 }, { collation: { locale: 'en', strength: 2 } }); // Case-insensitive search
104
107
  ClientSchema.index({ tier: 1, active: 1 }); // For tier-based queries
105
108
  ClientSchema.index({ onboardDate: 1 }); // For date-based queries
@@ -0,0 +1,50 @@
1
+ import mongoose, { Document, Schema, model } from "mongoose";
2
+ import { generateRandomIID } from "../constant";
3
+
4
+ export interface IInvitation extends Document {
5
+ iid: string;
6
+ email: string;
7
+ invitedBy: mongoose.Types.ObjectId; // user who sent the invite
8
+ organization: mongoose.Types.ObjectId;
9
+ client?: mongoose.Types.ObjectId; // optional (invite to specific client)
10
+ role?: string; // optional role name
11
+ permissions?: mongoose.Schema.Types.Mixed;
12
+ token: string;
13
+ status: string;
14
+ expiresAt: Date;
15
+ createdAt: Date;
16
+ updatedAt: Date;
17
+ }
18
+ const InvitationSchema = new Schema<IInvitation>({
19
+ iid: { type: String, unique: true, default: () => generateRandomIID() },
20
+ email: { type: String, required: true },
21
+ invitedBy: { type: mongoose.Schema.Types.ObjectId, ref: "user", required: true },
22
+ organization: { type: mongoose.Schema.Types.ObjectId, ref: "organization", required: true },
23
+ client: { type: mongoose.Schema.Types.ObjectId, ref: "client" },
24
+ role: { type: String, enum: ["owner", "admin", "member"], default: "member" },
25
+ permissions: { type: mongoose.Schema.Types.Mixed, required: true, default: {
26
+ dashboard: true,
27
+ reporting: false,
28
+ insights: false,
29
+ documentsAndLinks: false,
30
+ cvrReports: false,
31
+ abTesting: false,
32
+ abTestingDefault: true,
33
+ manageExperiments: false,
34
+ preCalculations: false,
35
+ } },
36
+ token: { type: String, unique: true, required: true },
37
+ status: { type: String, enum: ["pending", "accepted", "expired", "revoked"], default: "pending" },
38
+ expiresAt: { type: Date, default: Date.now() + 1000 * 60 * 60 * 24 * 30 },
39
+ },
40
+ {
41
+ timestamps: true
42
+ });
43
+
44
+ InvitationSchema.index({ email: 1, organization: 1 });
45
+ InvitationSchema.index({ token: 1 }, { unique: true });
46
+
47
+ const Invitation = mongoose.models.invitation || model<IInvitation>("invitation", InvitationSchema);
48
+
49
+
50
+ export default Invitation;
@@ -1,86 +1,31 @@
1
1
  import mongoose, { Document, Schema, model } from "mongoose";
2
+ import { generateRandomIID } from "../constant";
2
3
 
3
4
  export interface IOrganization extends Document {
5
+ iid: string;
4
6
  name: string;
5
- description: string;
6
- adminEmail: string;
7
- adminContact: string;
8
- createdBy: mongoose.Schema.Types.ObjectId;
9
- address: string;
10
- city: string;
11
- state: string;
12
- zip: string;
13
- country: string;
14
- phone: string;
15
- logo: string;
16
- website: string;
17
- createdAt: Date;
18
- updatedAt: Date;
19
- isActive: boolean;
7
+ ownerId: mongoose.Schema.Types.ObjectId;
8
+ stripeCustomerId?: string;
9
+ packageId?: mongoose.Schema.Types.ObjectId;
10
+ subscriptionId: String;
11
+ subscriptionStatus: String;
12
+ lastPaymentDate: Date;
13
+ currentPeriodEnd: Date;
20
14
  }
21
15
  const OrganizationSchema = new Schema<IOrganization>({
22
- name: {
23
- type: String,
24
- required: true,
25
- unique: true,
26
- },
27
- description: {
28
- type: String,
29
- required: true,
30
- },
31
- adminEmail: {
32
- type: String,
33
- required: true,
34
- },
35
- adminContact: {
36
- type: String,
37
- required: true,
38
- },
39
- createdBy: {
40
- type: mongoose.Schema.Types.ObjectId,
41
- ref: "user",
42
- },
43
- address: {
44
- type: String,
45
- required: true,
46
- },
47
- city: {
48
- type: String,
49
- required: true,
50
- },
51
- state: {
52
- type: String,
53
- required: true,
54
- },
55
- zip: {
56
- type: String,
57
- required: true,
58
- },
59
- country: {
60
- type: String,
61
- required: true,
62
- },
63
- phone: {
64
- type: String,
65
- required: true,
66
- },
67
- logo: {
68
- type: String,
69
- required: true,
70
- },
71
- website: {
72
- type: String,
73
- required: true,
74
- },
75
- isActive: {
76
- type: Boolean,
77
- default: true,
78
- },
16
+ iid: { type: String, default: () => generateRandomIID() },
17
+ name: { type: String, required: true },
18
+ ownerId: { type: mongoose.Schema.Types.ObjectId, ref: "user", required: true },
19
+ stripeCustomerId: String,
20
+ packageId: { type: mongoose.Types.ObjectId, ref: "package" },
21
+ subscriptionId: String,
22
+ subscriptionStatus: String,
23
+ lastPaymentDate: Date,
24
+ currentPeriodEnd: Date,
79
25
  }, {
80
26
  timestamps: true
81
27
  });
82
28
  const Organization = mongoose.models.organization || model<IOrganization>("organization", OrganizationSchema);
83
29
 
84
- OrganizationSchema.index({ name: 1, isActive: 1 });
85
30
 
86
31
  export default Organization;
@@ -0,0 +1,24 @@
1
+ import mongoose, { Document, Schema, model } from "mongoose";
2
+ import { generateRandomIID, PackageFeaturesConstants } from "../constant";
3
+
4
+ export interface IPackage extends Document {
5
+ iid: string;
6
+ name: string;
7
+ stripeProductId: string;
8
+ features: mongoose.Schema.Types.Mixed;
9
+ // userPermissions: mongoose.Schema.Types.ObjectId;
10
+ }
11
+ const PackageSchema = new Schema<IPackage>({
12
+ iid: { type: String, unique: true, default: () => generateRandomIID() },
13
+ name: { type: String, required: true },
14
+ stripeProductId: { type: String},
15
+ // userPermissions: { type: mongoose.Schema.Types.ObjectId, ref: "userpermission", required: true },
16
+ features: { type: mongoose.Schema.Types.Mixed, required: true, default: PackageFeaturesConstants },
17
+ },
18
+ {
19
+ timestamps: true
20
+ });
21
+ const Package = mongoose.models.package || model<IPackage>("package", PackageSchema);
22
+
23
+
24
+ export default Package;
@@ -20,44 +20,56 @@ export interface IRole extends Document {
20
20
  };
21
21
  }
22
22
 
23
- const RoleSchema = new Schema<IRole>({
24
- name: {
25
- type: String,
26
- unique: true,
27
- required: true,
28
- enum: ["USER", "ADMIN", "EDITOR", "COLLABORATOR", "CLIENT", "EXTERNAL"],
29
- trim: true,
30
- uppercase: true,
23
+ const RoleSchema = new Schema<IRole>(
24
+ {
25
+ name: {
26
+ type: String,
27
+ unique: true,
28
+ required: true,
29
+ enum: [
30
+ "USER",
31
+ "ADMIN",
32
+ "EDITOR",
33
+ "COLLABORATOR",
34
+ "CLIENT",
35
+ "EXTERNAL",
36
+ "QA",
37
+ "OPTIMIZER",
38
+ ],
39
+ trim: true,
40
+ uppercase: true,
41
+ },
42
+ description: {
43
+ type: String,
44
+ trim: true,
45
+ },
46
+ organizationId: {
47
+ type: mongoose.Schema.Types.ObjectId,
48
+ ref: "organization",
49
+ default: null,
50
+ },
51
+ isActive: {
52
+ type: Boolean,
53
+ default: true,
54
+ },
55
+ defaultPermissions: {
56
+ abTestingDefault: { type: Boolean, default: true },
57
+ abTesting: { type: Boolean, default: false },
58
+ preCalculations: { type: Boolean, default: true },
59
+ reporting: { type: Boolean, default: true },
60
+ insights: { type: Boolean, default: true },
61
+ documentsAndLinks: { type: Boolean, default: true },
62
+ cvrReports: { type: Boolean, default: true },
63
+ manageExperiments: { type: Boolean, default: true },
64
+ dashboard: { type: Boolean, default: true },
65
+ },
31
66
  },
32
- description: {
33
- type: String,
34
- trim: true,
35
- },
36
- organizationId: {
37
- type: mongoose.Schema.Types.ObjectId,
38
- ref: "organization",
39
- default: null,
40
- },
41
- isActive: {
42
- type: Boolean,
43
- default: true,
44
- },
45
- defaultPermissions: {
46
- abTestingDefault: { type: Boolean, default: true },
47
- abTesting: { type: Boolean, default: false },
48
- preCalculations: { type: Boolean, default: true },
49
- reporting: { type: Boolean, default: true },
50
- insights: { type: Boolean, default: true },
51
- documentsAndLinks: { type: Boolean, default: true },
52
- cvrReports: { type: Boolean, default: true },
53
- manageExperiments: { type: Boolean, default: true },
54
- dashboard: { type: Boolean, default: true },
67
+ {
68
+ timestamps: true,
55
69
  }
56
- }, {
57
- timestamps: true
58
- });
70
+ );
59
71
  // IF role is CLIENT then defaultPermissions should be false for all modules except reporting, insights, documentsAndLinks, cvrReports, dashboard
60
- RoleSchema.pre('save', function(next) {
72
+ RoleSchema.pre("save", function (next) {
61
73
  const allTrue = {
62
74
  abTestingDefault: true,
63
75
  abTesting: true,
@@ -69,7 +81,7 @@ RoleSchema.pre('save', function(next) {
69
81
  cvrReports: true,
70
82
  dashboard: true,
71
83
  };
72
- if (this.name === 'CLIENT') {
84
+ if (this.name === "CLIENT") {
73
85
  this.defaultPermissions = {
74
86
  ...allTrue,
75
87
  abTesting: false, // only this one is false
@@ -88,9 +100,9 @@ RoleSchema.index({ name: 1, isActive: 1 });
88
100
  RoleSchema.index({ organizationId: 1, name: 1 });
89
101
 
90
102
  // Add text index for search
91
- RoleSchema.index({
92
- name: 'text',
93
- description: 'text'
103
+ RoleSchema.index({
104
+ name: "text",
105
+ description: "text",
94
106
  });
95
107
 
96
108
  const Role = mongoose.models.role || model<IRole>("role", RoleSchema);
@@ -0,0 +1,57 @@
1
+ import mongoose, { Document, Schema, model } from "mongoose";
2
+ import { generateRandomIID } from "../constant";
3
+
4
+ export interface IThread extends Document {
5
+ iid: string;
6
+ organization: mongoose.Schema.Types.ObjectId;
7
+ user: mongoose.Schema.Types.ObjectId;
8
+ name: string;
9
+ }
10
+
11
+ const ThreadSchema = new Schema<IThread>(
12
+ {
13
+ iid: {
14
+ type: String,
15
+ trim: true,
16
+ },
17
+ name: {
18
+ type: String,
19
+ required: true,
20
+ default: "New Conversation",
21
+ },
22
+ organization: {
23
+ type: mongoose.Schema.Types.ObjectId,
24
+ ref: "organization",
25
+ default: null,
26
+ },
27
+ user: {
28
+ type: mongoose.Schema.Types.ObjectId,
29
+ ref: "user",
30
+ default: null,
31
+ },
32
+ },
33
+ {
34
+ timestamps: true,
35
+ }
36
+ );
37
+
38
+ ThreadSchema.pre('save', async function(next) {
39
+ if (!this.iid) {
40
+ let unique = false;
41
+ while (!unique) {
42
+ const id = generateRandomIID();
43
+ const existing = await mongoose.models.thread.findOne({ iid: id });
44
+ if (!existing) {
45
+ this.iid = id;
46
+ unique = true;
47
+ }
48
+ }
49
+ }
50
+ next();
51
+ });
52
+
53
+ ThreadSchema.index({ iid: 1 }, { unique: true });
54
+
55
+ const Thread = mongoose.models.thread || model<IThread>("thread", ThreadSchema);
56
+
57
+ export default Thread;
@@ -0,0 +1,67 @@
1
+ import mongoose, { Document, Schema, model } from "mongoose";
2
+ import { generateRandomIID } from "../constant";
3
+
4
+ export interface IThreadMessage extends Document {
5
+ iid: string;
6
+ organization: mongoose.Schema.Types.ObjectId;
7
+ thread: mongoose.Schema.Types.ObjectId;
8
+ status: string;
9
+ user: mongoose.Schema.Types.ObjectId;
10
+ message: mongoose.Schema.Types.Mixed;
11
+ }
12
+
13
+ const ThreadMessageSchema = new Schema<IThreadMessage>(
14
+ {
15
+ iid: {
16
+ type: String,
17
+ trim: true,
18
+ },
19
+ organization: {
20
+ type: mongoose.Schema.Types.ObjectId,
21
+ ref: "organization",
22
+ default: null,
23
+ },
24
+ thread: {
25
+ type: mongoose.Schema.Types.ObjectId,
26
+ ref: "thread",
27
+ default: null,
28
+ },
29
+ user: {
30
+ type: mongoose.Schema.Types.ObjectId,
31
+ ref: "user",
32
+ default: null,
33
+ },
34
+ status: {
35
+ type: String,
36
+ enum: ["pending", "success", "failed"],
37
+ default: "pending",
38
+ },
39
+ message: {
40
+ type: mongoose.Schema.Types.Mixed,
41
+ },
42
+ },
43
+ {
44
+ timestamps: true,
45
+ }
46
+ );
47
+
48
+ ThreadMessageSchema.pre('save', async function(next) {
49
+ if (!this.iid) {
50
+ let unique = false;
51
+ while (!unique) {
52
+ const id = generateRandomIID();
53
+ const existing = await mongoose.models.threadmessage.findOne({ iid: id });
54
+ if (!existing) {
55
+ this.iid = id;
56
+ unique = true;
57
+ }
58
+ }
59
+ }
60
+ next();
61
+ });
62
+
63
+ ThreadMessageSchema.index({ iid: 1 }, { unique: true });
64
+
65
+ const ThreadMessage = mongoose.models.threadmessage || model<IThreadMessage>("threadmessage", ThreadMessageSchema);
66
+
67
+ export default ThreadMessage;
@@ -1,70 +1,48 @@
1
1
  import mongoose, { Document, Schema, model } from "mongoose";
2
+ import { generateRandomIID, RolesConstants } from "../constant";
2
3
 
3
4
  export interface IUser extends Document {
5
+ iid: string;
4
6
  name: string;
5
7
  email: string;
8
+ image: string;
9
+ client: mongoose.Schema.Types.ObjectId[];
6
10
  password: string;
7
11
  token: string;
8
- role?: mongoose.Schema.Types.ObjectId[];
9
12
  deactivated: boolean;
10
- client?: mongoose.Schema.Types.ObjectId[];
11
13
  twoFactor: boolean;
12
- createdAt: Date;
13
- updatedAt: Date;
14
+ emailVerified: boolean;
14
15
  resetLink: string;
15
- organizationId?: mongoose.Schema.Types.ObjectId;
16
16
  bigqueryToken: string;
17
17
  expirybqToken: string;
18
18
  refreshToken: string;
19
+ createdAt: Date;
20
+ updatedAt: Date;
21
+ isSSOUser: boolean;
22
+ role: mongoose.Schema.Types.ObjectId[] | null;
19
23
  }
20
24
 
21
25
  const UserSchema = new Schema<IUser>(
22
26
  {
27
+ iid: { type: String, unique: true, default: () => generateRandomIID() },
23
28
  name: String,
24
- email: {
25
- type: String,
26
- unique: true,
27
- required: true,
28
- },
29
- password: {
30
- type: String,
31
- required: true,
32
- },
29
+ email: { type: String, unique: true, required: true },
30
+ client: { type: [mongoose.Schema.Types.ObjectId], ref: "client", default: null },
31
+ password: { type: String, required: true },
32
+ image: String,
33
33
  token: String,
34
- role: {
35
- type: [mongoose.Schema.Types.ObjectId],
36
- ref: "role",
37
- },
38
- deactivated: {
39
- type: Boolean,
40
- default: false,
41
- },
42
- client: {
43
- type: [mongoose.Schema.Types.ObjectId],
44
- ref: "client",
45
- default: null,
46
- },
47
- twoFactor: {
48
- type: Boolean,
49
- default: false,
50
- },
51
- organizationId: {
52
- type: mongoose.Schema.Types.ObjectId,
53
- ref: "organization",
54
- default: null,
55
- },
34
+ deactivated: { type: Boolean, default: false },
35
+ twoFactor: { type: Boolean, default: false },
36
+ emailVerified: { type: Boolean, default: false },
37
+ resetLink: String,
56
38
  bigqueryToken: String,
57
39
  expirybqToken: String,
58
40
  refreshToken: String,
41
+ isSSOUser: { type: Boolean, default: false },
42
+ role: { type: [mongoose.Schema.Types.ObjectId], ref: "role", default: null },
59
43
  },
60
- {
61
- timestamps: true,
62
- }
44
+ { timestamps: true }
63
45
  );
64
46
 
65
- // Add compound indexes for common query patterns
66
- UserSchema.index({ organizationId: 1, role: 1 });
67
- UserSchema.index({ organizationId: 1, client: 1 });
68
-
69
47
  const User = mongoose.models.user || model<IUser>("user", UserSchema);
70
48
  export default User;