@fplpool/fpl-models 1.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.
@@ -0,0 +1,53 @@
1
+ import { Document, Schema, Types, model } from "mongoose";
2
+ import config from "../config";
3
+
4
+
5
+ export interface IPoolMember extends Document {
6
+ _id: Types.ObjectId;
7
+ pool: Types.ObjectId;
8
+ user: Types.ObjectId;
9
+ isAdmin: boolean;
10
+ status: PoolMemberStatus;
11
+ joinedAt: Date;
12
+ }
13
+
14
+ export enum PoolMemberStatus {
15
+ Active = "active",
16
+ Inactive = "inactive",
17
+ // Banned = "banned"
18
+ }
19
+
20
+ const poolMemberSchema = new Schema<IPoolMember>({
21
+ user: {
22
+ type: Schema.Types.ObjectId,
23
+ ref: config.models.user,
24
+ required: true
25
+ },
26
+ pool: {
27
+ type: Schema.Types.ObjectId,
28
+ ref: config.models.pool,
29
+ required: true
30
+ },
31
+ isAdmin: {
32
+ type: Boolean,
33
+ default: false
34
+ },
35
+ status: {
36
+ type: String,
37
+ enum: PoolMemberStatus,
38
+ default: PoolMemberStatus.Active
39
+ }
40
+ }, {
41
+ timestamps: {
42
+ createdAt: 'joinedAt',
43
+ updatedAt: false
44
+ },
45
+ toJSON: {virtuals: true},
46
+ toObject: {virtuals: true}
47
+ })
48
+
49
+
50
+ const PoolMember = model<IPoolMember>(config.models.poolMember, poolMemberSchema);
51
+
52
+
53
+ export default PoolMember;
@@ -0,0 +1,130 @@
1
+ import { randomUUID } from "node:crypto";
2
+
3
+ import { Schema, model, Types, Document } from "mongoose";
4
+
5
+ import config from "../config";
6
+ import { TransactionMethod, TransactionStatus, TransactionType } from "../types/wallet";
7
+
8
+
9
+
10
+
11
+
12
+ export interface IPoolTransaction extends Document {
13
+ _id: Types.ObjectId;
14
+ key: Types.UUID;
15
+ wallet: Types.ObjectId;
16
+ member: Types.ObjectId;
17
+ paymentIntentId?: string;
18
+ amount: string;
19
+ description: string;
20
+ method: TransactionMethod;
21
+ type: TransactionType;
22
+ status: TransactionStatus;
23
+ metadata: {
24
+ cardId?: Types.ObjectId;
25
+ receiver?: Types.ObjectId;
26
+ gameweeks?: number[];
27
+ };
28
+ createdAt: Date;
29
+ updatedAt: Date;
30
+ }
31
+
32
+ export const poolAmountPattern = /^\d+(\.\d{1,2})?$/;
33
+
34
+ const poolTransactionSchema = new Schema<IPoolTransaction>({
35
+ wallet: {
36
+ type: Schema.Types.ObjectId,
37
+ ref: config.models.poolWallet,
38
+ },
39
+ member: {
40
+ type: Schema.Types.ObjectId,
41
+ ref: config.models.poolMember
42
+ },
43
+ key: {
44
+ type: Schema.Types.UUID,
45
+ required: false,
46
+ unique: true,
47
+ default: () => new Types.UUID(randomUUID())
48
+ },
49
+ paymentIntentId: {
50
+ type: String,
51
+ required: false
52
+ },
53
+ amount: {
54
+ type: String,
55
+ required: false,
56
+ default: "0.00",
57
+ set: function(value: string) {
58
+ // If value already looks like a float (has a .), ensure two decimals
59
+ if (typeof value === "string") {
60
+ if (poolAmountPattern.test(value)) {
61
+ // If it has a dot but is not two decimals, pad right
62
+ if (value.indexOf('.') !== -1) {
63
+ let [whole, decimals] = value.split('.');
64
+ if (decimals === undefined) return whole + ".00";
65
+ if (decimals.length === 1) return whole + "." + decimals + "0";
66
+ if (decimals.length === 2) return value;
67
+ if (decimals.length > 2) return whole + "." + decimals.slice(0,2);
68
+ }
69
+ // No decimal: add .00
70
+ return value + ".00";
71
+ }
72
+ // If it's an integer, add .00
73
+ if (/^\d+$/.test(value)) {
74
+ return value + ".00";
75
+ }
76
+ }
77
+ return value;
78
+ }
79
+ },
80
+ description: {
81
+ type: String,
82
+ required: true
83
+ },
84
+ method: {
85
+ type: String,
86
+ enum: TransactionMethod,
87
+ default: TransactionMethod.Wallet,
88
+ required: true
89
+ },
90
+ metadata: {
91
+ cardId: {
92
+ type: Schema.Types.ObjectId,
93
+ ref: config.models.card,
94
+ required: false,
95
+ default: null
96
+ },
97
+ receiver: {
98
+ type: Schema.Types.ObjectId,
99
+ ref: config.models.user,
100
+ required: false,
101
+ default: null
102
+ },
103
+ gameweeks: {
104
+ type: Array<number>,
105
+ required: false,
106
+ default: null
107
+ }
108
+ },
109
+ type: {
110
+ type: String,
111
+ enum: TransactionType,
112
+ required: true
113
+ },
114
+ status: {
115
+ type: String,
116
+ enum: TransactionStatus,
117
+ required: true,
118
+ default: TransactionStatus.Pending
119
+ }
120
+ }, {
121
+ timestamps: true,
122
+ toJSON: {virtuals: true},
123
+ toObject: {virtuals: true}
124
+ })
125
+
126
+
127
+ const PoolTransaction = model<IPoolTransaction>(config.models.poolTransaction, poolTransactionSchema);
128
+
129
+
130
+ export default PoolTransaction;
@@ -0,0 +1,89 @@
1
+ import { Schema, model, Types, Document } from "mongoose";
2
+ import config from "../config";
3
+ import { poolAmountPattern } from "./pool-transaction.model";
4
+
5
+
6
+
7
+ export interface IPoolWallet extends Document {
8
+ _id: Types.ObjectId;
9
+ pool: Types.ObjectId;
10
+ balance: string;
11
+ availableBalance: string;
12
+ createdAt: Date;
13
+ updatedAt: Date;
14
+ }
15
+
16
+ const poolWalletSchema = new Schema<IPoolWallet>({
17
+ pool: {
18
+ type: Schema.Types.ObjectId,
19
+ ref: config.models.pool,
20
+ required: true
21
+ },
22
+ balance: {
23
+ type: String,
24
+ required: true,
25
+ match: poolAmountPattern,
26
+ set: function(value: string) {
27
+ // If value already looks like a float (has a .), ensure two decimals
28
+ if (typeof value === "string") {
29
+ if (poolAmountPattern.test(value)) {
30
+ // If it has a dot but is not two decimals, pad right
31
+ if (value.indexOf('.') !== -1) {
32
+ let [whole, decimals] = value.split('.');
33
+ if (decimals === undefined) return whole + ".00";
34
+ if (decimals.length === 1) return whole + "." + decimals + "0";
35
+ if (decimals.length === 2) return value;
36
+ if (decimals.length > 2) return whole + "." + decimals.slice(0,2);
37
+ }
38
+ // No decimal: add .00
39
+ return value + ".00";
40
+ }
41
+ // If it's an integer, add .00
42
+ if (/^\d+$/.test(value)) {
43
+ return value + ".00";
44
+ }
45
+ }
46
+ return value;
47
+ },
48
+ default: "0.00"
49
+ },
50
+ availableBalance: {
51
+ type: String,
52
+ required: false,
53
+ match: poolAmountPattern,
54
+ set: function(value: string) {
55
+ // If value already looks like a float (has a .), ensure two decimals
56
+ if (typeof value === "string") {
57
+ if (poolAmountPattern.test(value)) {
58
+ // If it has a dot but is not two decimals, pad right
59
+ if (value.indexOf('.') !== -1) {
60
+ let [whole, decimals] = value.split('.');
61
+ if (decimals === undefined) return whole + ".00";
62
+ if (decimals.length === 1) return whole + "." + decimals + "0";
63
+ if (decimals.length === 2) return value;
64
+ if (decimals.length > 2) return whole + "." + decimals.slice(0,2);
65
+ }
66
+ // No decimal: add .00
67
+ return value + ".00";
68
+ }
69
+ // If it's an integer, add .00
70
+ if (/^\d+$/.test(value)) {
71
+ return value + ".00";
72
+ }
73
+ }
74
+ return value;
75
+ },
76
+ default: "0.00"
77
+ }
78
+ }, {
79
+ timestamps: true,
80
+ toJSON: {virtuals: true},
81
+ toObject: {virtuals: true}
82
+ })
83
+
84
+
85
+
86
+
87
+ const PoolWallet = model<IPoolWallet>(config.models.poolWallet, poolWalletSchema);
88
+
89
+ export default PoolWallet;
@@ -0,0 +1,146 @@
1
+ import { Document, Schema, Types, model } from "mongoose";
2
+ import config from "../config";
3
+ import { PoolType } from "../types/pool";
4
+ import { poolService } from "../services/pool.service";
5
+
6
+
7
+
8
+
9
+ export interface IPool extends Document {
10
+ _id: Types.ObjectId;
11
+ uid: string | null;
12
+ admin: Types.ObjectId;
13
+ code: string;
14
+ private: boolean;
15
+ name: string;
16
+ description: string;
17
+ amount: number;
18
+ startGameweek: number;
19
+ currency: string;
20
+ members: number;
21
+ maxMembers: number;
22
+ type: PoolType;
23
+ status: PoolStatus;
24
+ createdAt: Date;
25
+ updatedAt: Date;
26
+ settings: PoolSettings;
27
+ }
28
+
29
+ export interface PoolSettings {
30
+ poolType: PoolSettingsType,
31
+ percentages: number[];
32
+ }
33
+
34
+ export enum PoolSettingsType {
35
+ WinnerTakesAll = 'winner-takes-all',
36
+ Top3 = 'top-3-split'
37
+ }
38
+
39
+ export enum PoolStatus {
40
+ Active = "active",
41
+ Inactive = "inactive"
42
+ }
43
+
44
+
45
+ const poolSchema = new Schema<IPool>({
46
+ uid: {
47
+ type: String,
48
+ required: false,
49
+ default: null
50
+ },
51
+ admin: {
52
+ type: Schema.Types.ObjectId,
53
+ ref: config.models.user,
54
+ required: true
55
+ },
56
+ code: {
57
+ type: String,
58
+ required: [true, 'Code is required'],
59
+ trim: true,
60
+ unique: true,
61
+ length: [12, 'Code must be 12 characters'],
62
+ },
63
+ private: {
64
+ type: Boolean,
65
+ required: [true, 'Private is required'],
66
+ default: false
67
+ },
68
+ name: {
69
+ type: String,
70
+ required: [true, 'Name is required'],
71
+ trim: true, // This option removes leading and trailing whitespace from the value before saving to the database
72
+ unique: [true, 'Pool name already exists'],
73
+ maxLength: [50, 'Name must be less than 50 characters'],
74
+ },
75
+ description: {
76
+ type: String,
77
+ required: [true, 'Description is required'],
78
+ trim: true,
79
+ maxLength: [200, 'Description must be less than 200 characters'],
80
+ },
81
+ members: {
82
+ type: Number,
83
+ default: 1
84
+ },
85
+ maxMembers: {
86
+ type: Number,
87
+ default: 100
88
+ },
89
+ amount: {
90
+ type: Number,
91
+ required: [true, 'Amount is required'],
92
+ default: 0
93
+ },
94
+ startGameweek: {
95
+ type: Number,
96
+ required: [true, 'Start gameweek is required'],
97
+ default: 1
98
+ },
99
+ currency: {
100
+ type: String,
101
+ required: [true, 'Currency is required'],
102
+ default: 'USD'
103
+ },
104
+ type: {
105
+ type: String,
106
+ required: [true, 'Type is required'],
107
+ enum: PoolType,
108
+ default: PoolType.Weekly
109
+ },
110
+ status: {
111
+ type: String,
112
+ required: [true, 'Status is required'],
113
+ enum: PoolStatus,
114
+ default: PoolStatus.Active
115
+ },
116
+ settings: {
117
+ poolType: {
118
+ type: String,
119
+ required: [true, 'Pool type is required'],
120
+ enum: PoolSettingsType,
121
+ default: PoolSettingsType.WinnerTakesAll
122
+ },
123
+ percentages: [{
124
+ type: Number,
125
+ required: [true, 'Percentage is required']
126
+ }]
127
+ },
128
+ }, {
129
+ timestamps: true,
130
+ toJSON: {virtuals: true},
131
+ toObject: {virtuals: true}
132
+ })
133
+
134
+
135
+ // poolSchema.method("generateLink", async function(){
136
+ // const link = await poolService.getPoolInviteLink(this);
137
+ // return link;
138
+ // })
139
+
140
+
141
+
142
+
143
+ const Pool = model<IPool>(config.models.pool, poolSchema);
144
+
145
+
146
+ export default Pool;
@@ -0,0 +1,45 @@
1
+ import {Schema, model, Types, Document} from "mongoose";
2
+
3
+ import config from "../config";
4
+
5
+
6
+
7
+
8
+ export interface ISession extends Document{
9
+ _id: Types.ObjectId;
10
+ user: Types.ObjectId;
11
+ userAgent: String;
12
+ device: Object;
13
+ expired: Boolean;
14
+ createdAt: Date;
15
+ updatedAt: Date;
16
+ }
17
+
18
+
19
+ const sessionSchema = new Schema<ISession>({
20
+ user: {
21
+ type: Schema.Types.ObjectId,
22
+ ref: config.models.user,
23
+ required: true
24
+ },
25
+ device: Object,
26
+ userAgent: String,
27
+ expired: {
28
+ required: true,
29
+ type: Boolean,
30
+ default: false
31
+ },
32
+ },
33
+ {
34
+ timestamps: true,
35
+ toJSON: {virtuals: true},
36
+ toObject: {virtuals: true}
37
+ });
38
+
39
+
40
+
41
+
42
+ const Session = model<ISession>(config.models.session, sessionSchema);
43
+
44
+
45
+ export default Session;
@@ -0,0 +1,144 @@
1
+ import { randomUUID } from "node:crypto";
2
+
3
+ import { Schema, model, Types, Document } from "mongoose";
4
+
5
+ import config from "../config";
6
+ import { poolAmountPattern } from "./pool-transaction.model";
7
+ import { TransactionMethod, TransactionStatus, TransactionType } from "../types/wallet";
8
+
9
+
10
+
11
+
12
+
13
+ export interface ITransaction extends Document {
14
+ _id: Types.ObjectId;
15
+ key: Types.UUID;
16
+ wallet: Types.ObjectId;
17
+ type: TransactionType;
18
+ paymentIntentId?: string;
19
+ description: string;
20
+ amount: string;
21
+ // currency: string;
22
+ method: TransactionMethod;
23
+ metadata: {
24
+ address?: string;
25
+ hash?: string;
26
+ chainId?: number;
27
+ token?: string;
28
+ value?: string;
29
+ cardId?: Types.ObjectId;
30
+ };
31
+ status: TransactionStatus;
32
+ createdAt: Date;
33
+ updatedAt: Date;
34
+ }
35
+
36
+
37
+
38
+ const transactionSchema = new Schema<ITransaction>({
39
+ wallet: {
40
+ type: Schema.Types.ObjectId,
41
+ ref: config.models.wallet,
42
+ required: true
43
+ },
44
+ key: {
45
+ type: Schema.Types.UUID,
46
+ required: false,
47
+ unique: true,
48
+ default: () => new Types.UUID(randomUUID())
49
+ },
50
+ type: {
51
+ type: String,
52
+ enum: TransactionType,
53
+ required: true
54
+ },
55
+ description: {
56
+ type: String,
57
+ required: false,
58
+ default: "No description"
59
+ },
60
+ paymentIntentId: {
61
+ type: String,
62
+ required: false,
63
+ default: null
64
+ },
65
+ amount: {
66
+ type: String,
67
+ required: false,
68
+ default: "0.00",
69
+ set: function(value: string) {
70
+ // If value already looks like a float (has a .), ensure two decimals
71
+ if (typeof value === "string") {
72
+ if (poolAmountPattern.test(value)) {
73
+ // If it has a dot but is not two decimals, pad right
74
+ if (value.indexOf('.') !== -1) {
75
+ let [whole, decimals] = value.split('.');
76
+ if (decimals === undefined) return whole + ".00";
77
+ if (decimals.length === 1) return whole + "." + decimals + "0";
78
+ if (decimals.length === 2) return value;
79
+ if (decimals.length > 2) return whole + "." + decimals.slice(0,2);
80
+ }
81
+ // No decimal: add .00
82
+ return value + ".00";
83
+ }
84
+ // If it's an integer, add .00
85
+ if (/^\d+$/.test(value)) {
86
+ return value + ".00";
87
+ }
88
+ }
89
+ return value;
90
+ }
91
+ },
92
+ method: {
93
+ type: String,
94
+ enum: TransactionMethod,
95
+ required: false,
96
+ default: TransactionMethod.Card
97
+ },
98
+ metadata: {
99
+ cardId: {
100
+ type: Schema.Types.ObjectId,
101
+ ref: config.models.card,
102
+ required: false,
103
+ default: null
104
+ },
105
+ address: {
106
+ type: String,
107
+ required: false,
108
+ default: null
109
+ },
110
+ hash: {
111
+ type: String,
112
+ required: false,
113
+ default: null
114
+ },
115
+ chainId: {
116
+ type: Number,
117
+ required: false,
118
+ default: null
119
+ },
120
+ token: {
121
+ type: String,
122
+ required: false,
123
+ default: null
124
+ },
125
+ },
126
+ status: {
127
+ type: String,
128
+ enum: TransactionStatus,
129
+ required: false,
130
+ default: TransactionStatus.Pending
131
+ }
132
+ }, {
133
+ timestamps: true,
134
+ toJSON: {virtuals: true},
135
+ toObject: {virtuals: true}
136
+ })
137
+
138
+
139
+ // transactionSchema.index({paymentIntentId: 1}, {unique: true});
140
+
141
+
142
+ const Transaction = model<ITransaction>(config.models.transaction, transactionSchema);
143
+
144
+ export default Transaction;
@@ -0,0 +1,53 @@
1
+ import {Document, Schema, model} from "mongoose";
2
+ import { Types } from "mongoose";
3
+
4
+ import config from "../config";
5
+
6
+
7
+
8
+
9
+ export interface IUserSettings extends Document {
10
+ _id: Types.ObjectId;
11
+ twoFaEnabled: boolean;
12
+ twoFaSecret?: string;
13
+ country: string;
14
+ currency: string;
15
+ createdAt: Date;
16
+ updatedAt: Date;
17
+ }
18
+
19
+
20
+ const userSettingsSchema = new Schema<IUserSettings>({
21
+ twoFaEnabled: {
22
+ type: Boolean,
23
+ required: [true, 'Two factor authentication is required'],
24
+ default: false
25
+ },
26
+ twoFaSecret: {
27
+ type: String,
28
+ required: false,
29
+ default: null
30
+ },
31
+ country: {
32
+ type: String,
33
+ required: [true, 'Country is required'],
34
+ trim: true,
35
+ maxLength: [50, 'Country must be less than 50 characters'],
36
+ },
37
+ currency: {
38
+ type: String,
39
+ required: [true, 'Currency is required'],
40
+ trim: true,
41
+ maxLength: [50, 'Currency must be less than 50 characters']
42
+ },
43
+ }, {
44
+ timestamps: true,
45
+ toJSON: {virtuals: true},
46
+ toObject: {virtuals: true}
47
+ })
48
+
49
+
50
+
51
+ const UserSettings = model<IUserSettings>(config.models.userSettings, userSettingsSchema);
52
+
53
+ export default UserSettings;