@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.
- package/package.json +32 -0
- package/src/config/index.ts +38 -0
- package/src/index.ts +19 -0
- package/src/models/card.model.ts +76 -0
- package/src/models/config.model.ts +52 -0
- package/src/models/invoice.model.ts +100 -0
- package/src/models/job.model.ts +62 -0
- package/src/models/pool-gameweek-deadline.model.ts +46 -0
- package/src/models/pool-gameweek-winner.model.ts +55 -0
- package/src/models/pool-gameweek.model.ts +114 -0
- package/src/models/pool-invite.model.ts +65 -0
- package/src/models/pool-member.model.ts +53 -0
- package/src/models/pool-transaction.model.ts +130 -0
- package/src/models/pool-wallet.model.ts +89 -0
- package/src/models/pool.model.ts +146 -0
- package/src/models/session.model.ts +45 -0
- package/src/models/transaction.model.ts +144 -0
- package/src/models/user-settings.model.ts +53 -0
- package/src/models/user.model.ts +81 -0
- package/src/models/wallet.model.ts +154 -0
- package/src/repositories/generic.repository.ts +86 -0
- package/tsconfig.json +103 -0
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fplpool/fpl-models",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [],
|
|
9
|
+
"author": "Akamelu Sopuruchukwu",
|
|
10
|
+
"license": "ISC",
|
|
11
|
+
"description": "Shared application models",
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"dotenv": "^17.3.1",
|
|
14
|
+
"mongoose": "^9.3.0"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/node": "^25.5.0",
|
|
21
|
+
"ts-node": "^10.9.2",
|
|
22
|
+
"typescript": "^5.9.3"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/austin230196/fpl-models.git"
|
|
27
|
+
},
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/austin230196/fpl-models/issues"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/austin230196/fpl-models#readme"
|
|
32
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {config} from "dotenv";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
config();
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
db: {
|
|
9
|
+
mongo: {
|
|
10
|
+
uri: process.env.MONGO_URI || ``,
|
|
11
|
+
host: process.env.MONGO_HOST || 'localhost',
|
|
12
|
+
port: process.env.MONGO_PORT || 27017,
|
|
13
|
+
database: process.env.MONGO_DATABASE || 'fpl',
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
models: {
|
|
17
|
+
user: 'User',
|
|
18
|
+
userSettings: 'UserSettings',
|
|
19
|
+
session: 'Session',
|
|
20
|
+
wallet: 'Wallet',
|
|
21
|
+
card: 'Card',
|
|
22
|
+
transaction: 'Transaction',
|
|
23
|
+
notification: 'Notification',
|
|
24
|
+
history: 'History',
|
|
25
|
+
pool: 'Pool',
|
|
26
|
+
poolGameweekDeadline: 'PoolGameweekDeadline',
|
|
27
|
+
poolMember: 'PoolMember',
|
|
28
|
+
poolWallet: 'PoolWallet',
|
|
29
|
+
poolGameweek: 'PoolGameweek',
|
|
30
|
+
poolGameweekWinner: 'PoolGameweekWinner',
|
|
31
|
+
poolInvite: 'PoolInvite',
|
|
32
|
+
poolTransaction: 'PoolTransaction',
|
|
33
|
+
poolHistory: 'PoolHistory',
|
|
34
|
+
job: 'Job',
|
|
35
|
+
invoice: 'Invoice',
|
|
36
|
+
config: 'Config',
|
|
37
|
+
},
|
|
38
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export * from "./models/user.model";
|
|
2
|
+
export * from "./models/user-settings.model";
|
|
3
|
+
export * from "./models/session.model";
|
|
4
|
+
export * from "./models/wallet.model";
|
|
5
|
+
export * from "./models/card.model";
|
|
6
|
+
export * from "./models/transaction.model";
|
|
7
|
+
export * from "./models/pool.model";
|
|
8
|
+
export * from "./models/pool-gameweek-deadline.model";
|
|
9
|
+
export * from "./models/pool-member.model";
|
|
10
|
+
export * from "./models/pool-wallet.model";
|
|
11
|
+
export * from "./models/pool-gameweek.model";
|
|
12
|
+
export * from "./models/pool-gameweek-winner.model";
|
|
13
|
+
export * from "./models/pool-invite.model";
|
|
14
|
+
export * from "./models/pool-transaction.model";
|
|
15
|
+
export * from "./models/job.model";
|
|
16
|
+
export * from "./models/invoice.model";
|
|
17
|
+
export * from "./models/config.model";
|
|
18
|
+
|
|
19
|
+
export * from "./repositories/generic.repository";
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Schema, model, Types, Document } from "mongoose";
|
|
2
|
+
import config from "../config";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export interface ICard extends Document {
|
|
7
|
+
_id: Types.ObjectId;
|
|
8
|
+
paymentMethodId: string;
|
|
9
|
+
last4: string;
|
|
10
|
+
brand: string;
|
|
11
|
+
expiryMonth: number;
|
|
12
|
+
expiryYear: number;
|
|
13
|
+
holderName: string;
|
|
14
|
+
isDefault: boolean;
|
|
15
|
+
addedAt: Date;
|
|
16
|
+
updatedAt: Date;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
const cardSchema = new Schema<ICard>({
|
|
22
|
+
paymentMethodId: {
|
|
23
|
+
type: String,
|
|
24
|
+
required: true,
|
|
25
|
+
unique: true,
|
|
26
|
+
trim: true
|
|
27
|
+
},
|
|
28
|
+
last4: {
|
|
29
|
+
type: String,
|
|
30
|
+
required: true
|
|
31
|
+
},
|
|
32
|
+
brand: {
|
|
33
|
+
type: String,
|
|
34
|
+
required: true
|
|
35
|
+
},
|
|
36
|
+
expiryMonth: {
|
|
37
|
+
type: Number,
|
|
38
|
+
required: true,
|
|
39
|
+
min: 1,
|
|
40
|
+
max: 12
|
|
41
|
+
},
|
|
42
|
+
expiryYear: {
|
|
43
|
+
type: Number,
|
|
44
|
+
required: true
|
|
45
|
+
},
|
|
46
|
+
holderName: {
|
|
47
|
+
type: String,
|
|
48
|
+
required: true
|
|
49
|
+
},
|
|
50
|
+
isDefault: {
|
|
51
|
+
type: Boolean,
|
|
52
|
+
default: false
|
|
53
|
+
},
|
|
54
|
+
}, {
|
|
55
|
+
timestamps: {
|
|
56
|
+
createdAt: 'addedAt',
|
|
57
|
+
updatedAt: true
|
|
58
|
+
},
|
|
59
|
+
toJSON: {virtuals: true},
|
|
60
|
+
toObject: {virtuals: true}
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
cardSchema.virtual('expired').get(function(){
|
|
65
|
+
const currentDate = new Date();
|
|
66
|
+
const currentYear = currentDate.getFullYear();
|
|
67
|
+
const currentMonth = currentDate.getMonth() + 1;
|
|
68
|
+
|
|
69
|
+
if (this.expiryYear < currentYear) return true;
|
|
70
|
+
if (this.expiryYear === currentYear && this.expiryMonth < currentMonth) return true;
|
|
71
|
+
return false;
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
const Card = model<ICard>(config.models.card, cardSchema);
|
|
75
|
+
|
|
76
|
+
export default Card;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Document, model, Schema, Types } from "mongoose";
|
|
2
|
+
|
|
3
|
+
export interface IConfig extends Document {
|
|
4
|
+
_id: Types.ObjectId;
|
|
5
|
+
name: string,
|
|
6
|
+
version: string,
|
|
7
|
+
gameweek: {
|
|
8
|
+
active: boolean,
|
|
9
|
+
current: number,
|
|
10
|
+
next: number | null,
|
|
11
|
+
activeTable: null | Record<string, number>
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
const configSchema = new Schema<IConfig>({
|
|
17
|
+
name: {
|
|
18
|
+
type: String,
|
|
19
|
+
required: true
|
|
20
|
+
},
|
|
21
|
+
version: {
|
|
22
|
+
type: String,
|
|
23
|
+
required: true
|
|
24
|
+
},
|
|
25
|
+
gameweek: {
|
|
26
|
+
active: {
|
|
27
|
+
type: Boolean,
|
|
28
|
+
required: true,
|
|
29
|
+
default: false
|
|
30
|
+
},
|
|
31
|
+
current: {
|
|
32
|
+
type: Number,
|
|
33
|
+
required: true,
|
|
34
|
+
},
|
|
35
|
+
next: {
|
|
36
|
+
type: Number,
|
|
37
|
+
required: true,
|
|
38
|
+
default: null
|
|
39
|
+
},
|
|
40
|
+
activeTable: {
|
|
41
|
+
type: Object,
|
|
42
|
+
required: false,
|
|
43
|
+
default: null
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
const Config = model<IConfig>("Config", configSchema);
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
export default Config;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {Document, Schema, Types, model} from "mongoose";
|
|
2
|
+
|
|
3
|
+
import config from "../config";
|
|
4
|
+
import sperseId from "sperse-id";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export enum InvoiceStatus {
|
|
11
|
+
Pending = "pending",
|
|
12
|
+
Completed = "completed",
|
|
13
|
+
Failed = "failed",
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface IInvoice extends Document {
|
|
17
|
+
_id: Types.ObjectId;
|
|
18
|
+
uid: string;
|
|
19
|
+
wallet: Types.ObjectId;
|
|
20
|
+
status: InvoiceStatus;
|
|
21
|
+
receipt?: string;
|
|
22
|
+
createdAt: Date;
|
|
23
|
+
updatedAt: Date;
|
|
24
|
+
description?: string;
|
|
25
|
+
amount: string;
|
|
26
|
+
metadata: {
|
|
27
|
+
paymentMethodType?: InvoicePaymentMethodType,
|
|
28
|
+
cardId?: Types.ObjectId;
|
|
29
|
+
currency: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export enum InvoicePaymentMethodType {
|
|
34
|
+
Card = "card",
|
|
35
|
+
BankTransfer = "bank_transfer",
|
|
36
|
+
// Crypto = "crypto",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
const invoiceSchema = new Schema<IInvoice>({
|
|
42
|
+
uid: {
|
|
43
|
+
type: String,
|
|
44
|
+
required: true,
|
|
45
|
+
unique: true,
|
|
46
|
+
default: () => sperseId(12, {numbers: true, capitalLetters: false, smallLetters: true})
|
|
47
|
+
},
|
|
48
|
+
wallet: {
|
|
49
|
+
type: Schema.Types.ObjectId,
|
|
50
|
+
ref: config.models.wallet,
|
|
51
|
+
required: true
|
|
52
|
+
},
|
|
53
|
+
receipt: {
|
|
54
|
+
type: String,
|
|
55
|
+
required: false,
|
|
56
|
+
default: null
|
|
57
|
+
},
|
|
58
|
+
status: {
|
|
59
|
+
type: String,
|
|
60
|
+
required: [true, 'Status is required'],
|
|
61
|
+
enum: InvoiceStatus,
|
|
62
|
+
default: InvoiceStatus.Pending
|
|
63
|
+
},
|
|
64
|
+
description: {
|
|
65
|
+
type: String,
|
|
66
|
+
required: false,
|
|
67
|
+
default: null
|
|
68
|
+
},
|
|
69
|
+
amount: {
|
|
70
|
+
type: String,
|
|
71
|
+
required: true,
|
|
72
|
+
default: "0.00"
|
|
73
|
+
},
|
|
74
|
+
metadata: {
|
|
75
|
+
paymentMethodType: {
|
|
76
|
+
type: String,
|
|
77
|
+
enum: InvoicePaymentMethodType,
|
|
78
|
+
default: InvoicePaymentMethodType.Card
|
|
79
|
+
},
|
|
80
|
+
cardId: {
|
|
81
|
+
type: String,
|
|
82
|
+
required: false,
|
|
83
|
+
default: null
|
|
84
|
+
},
|
|
85
|
+
currency: {
|
|
86
|
+
type: String,
|
|
87
|
+
required: true,
|
|
88
|
+
default: "USD"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}, {
|
|
92
|
+
timestamps: true,
|
|
93
|
+
toJSON: {virtuals: true},
|
|
94
|
+
toObject: {virtuals: true}
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
const Invoice = model<IInvoice>(config.models.invoice, invoiceSchema)
|
|
99
|
+
|
|
100
|
+
export default Invoice;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {Document, Schema, Types, model} from "mongoose";
|
|
2
|
+
|
|
3
|
+
import config from "../config";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export enum JobStatus {
|
|
8
|
+
Pending = "pending",
|
|
9
|
+
Completed = "completed",
|
|
10
|
+
Failed = "failed",
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface IJob extends Document {
|
|
14
|
+
_id: Types.ObjectId;
|
|
15
|
+
queueName: string;
|
|
16
|
+
payload: Record<string, any>;
|
|
17
|
+
status: JobStatus;
|
|
18
|
+
createdAt: Date;
|
|
19
|
+
updatedAt: Date;
|
|
20
|
+
lastAttemptedAt: Date | null;
|
|
21
|
+
finalizedAt: Date | null;
|
|
22
|
+
errorLogs: Array<any> | null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
const jobSchema = new Schema<IJob>({
|
|
27
|
+
queueName: {
|
|
28
|
+
type: String,
|
|
29
|
+
required: [true, 'Queue name is required'],
|
|
30
|
+
},
|
|
31
|
+
payload: {
|
|
32
|
+
type: Object
|
|
33
|
+
},
|
|
34
|
+
errorLogs: {
|
|
35
|
+
type: Array,
|
|
36
|
+
default: null
|
|
37
|
+
},
|
|
38
|
+
status: {
|
|
39
|
+
type: String,
|
|
40
|
+
required: [true, 'Status is required'],
|
|
41
|
+
enum: JobStatus,
|
|
42
|
+
default: JobStatus.Pending
|
|
43
|
+
},
|
|
44
|
+
lastAttemptedAt: {
|
|
45
|
+
type: Date,
|
|
46
|
+
default: null,
|
|
47
|
+
},
|
|
48
|
+
finalizedAt: {
|
|
49
|
+
type: Date,
|
|
50
|
+
default: null,
|
|
51
|
+
},
|
|
52
|
+
}, {
|
|
53
|
+
timestamps: true,
|
|
54
|
+
toJSON: {virtuals: true},
|
|
55
|
+
toObject: {virtuals: true}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
const Job = model<IJob>(config.models.job, jobSchema)
|
|
61
|
+
|
|
62
|
+
export default Job;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Document, Schema, Types, model } from "mongoose";
|
|
2
|
+
import config from "../config";
|
|
3
|
+
import { IPool } from "./pool.model";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export enum PoolGameweekDeadlineType {
|
|
7
|
+
Personal = 'personal',
|
|
8
|
+
Members = 'members'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface IPoolGameweekDeadline extends Document {
|
|
12
|
+
_id: Types.ObjectId;
|
|
13
|
+
pool: IPool;
|
|
14
|
+
type: PoolGameweekDeadlineType;
|
|
15
|
+
msBeforeDeadline: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
const poolGameweekDeadlineSchema = new Schema<IPoolGameweekDeadline>({
|
|
20
|
+
pool: {
|
|
21
|
+
type: Schema.Types.ObjectId,
|
|
22
|
+
ref: config.models.pool,
|
|
23
|
+
required: true
|
|
24
|
+
},
|
|
25
|
+
type: {
|
|
26
|
+
type: String,
|
|
27
|
+
enum: PoolGameweekDeadlineType,
|
|
28
|
+
default: PoolGameweekDeadlineType.Members
|
|
29
|
+
},
|
|
30
|
+
msBeforeDeadline: {
|
|
31
|
+
type: Number,
|
|
32
|
+
required: true,
|
|
33
|
+
default: 1000 * 60 * 30 //30 minutes before deadline
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
timestamps: true,
|
|
38
|
+
toJSON: {virtuals: true},
|
|
39
|
+
toObject: {virtuals: true}
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
const PoolGameweekDeadline = model<IPoolGameweekDeadline>(config.models.poolGameweekDeadline, poolGameweekDeadlineSchema);
|
|
45
|
+
|
|
46
|
+
export default PoolGameweekDeadline;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Schema, model, Types, Document } from "mongoose";
|
|
2
|
+
import config from "../config";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export enum PoolGameweekWinnerStatus {
|
|
8
|
+
Pending = "pending",
|
|
9
|
+
Paid = "paid",
|
|
10
|
+
Failed = "failed"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface IPoolGameweekWinner extends Document {
|
|
14
|
+
_id: Types.ObjectId;
|
|
15
|
+
gameweek: Types.ObjectId;
|
|
16
|
+
winner: Types.ObjectId;
|
|
17
|
+
score: number;
|
|
18
|
+
status: PoolGameweekWinnerStatus;
|
|
19
|
+
createdAt: Date;
|
|
20
|
+
updatedAt: Date;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
const poolGameweekWinnerSchema = new Schema<IPoolGameweekWinner>({
|
|
25
|
+
gameweek: {
|
|
26
|
+
type: Schema.Types.ObjectId,
|
|
27
|
+
ref: config.models.poolGameweek,
|
|
28
|
+
required: true
|
|
29
|
+
},
|
|
30
|
+
winner: {
|
|
31
|
+
type: Schema.Types.ObjectId,
|
|
32
|
+
ref: config.models.poolMember,
|
|
33
|
+
required: true
|
|
34
|
+
},
|
|
35
|
+
score: {
|
|
36
|
+
type: Number,
|
|
37
|
+
required: true,
|
|
38
|
+
default: 0
|
|
39
|
+
},
|
|
40
|
+
status: {
|
|
41
|
+
type: String,
|
|
42
|
+
enum: PoolGameweekWinnerStatus,
|
|
43
|
+
default: PoolGameweekWinnerStatus.Pending
|
|
44
|
+
},
|
|
45
|
+
}, {
|
|
46
|
+
timestamps: true,
|
|
47
|
+
toJSON: {virtuals: true},
|
|
48
|
+
toObject: {virtuals: true}
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
const PoolGameweekWinner = model<IPoolGameweekWinner>(config.models.poolGameweekWinner, poolGameweekWinnerSchema);
|
|
54
|
+
|
|
55
|
+
export default PoolGameweekWinner;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Schema, model, Types, Document } from "mongoose";
|
|
2
|
+
import config from "../config";
|
|
3
|
+
import { poolAmountPattern } from "./pool-transaction.model";
|
|
4
|
+
import AdvancedError from "../errors/advanced.error";
|
|
5
|
+
import StatusCode from "../enums/status-code.enum";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export interface IPoolGameweek extends Document {
|
|
11
|
+
_id: Types.ObjectId;
|
|
12
|
+
pool: Types.ObjectId;
|
|
13
|
+
gameweek: number;
|
|
14
|
+
active: boolean;
|
|
15
|
+
activePlayers: {member: Types.ObjectId, score: number}[];
|
|
16
|
+
winner: Types.ObjectId | null;
|
|
17
|
+
balance: string;
|
|
18
|
+
startedAt: Date | null;
|
|
19
|
+
participationRateBps: number;
|
|
20
|
+
createdAt: Date;
|
|
21
|
+
updatedAt: Date;
|
|
22
|
+
hasPaid: (memberId: Types.ObjectId) => Promise<boolean>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
const poolGameweekSchema = new Schema<IPoolGameweek>({
|
|
27
|
+
pool: {
|
|
28
|
+
type: Schema.Types.ObjectId,
|
|
29
|
+
ref: config.models.pool,
|
|
30
|
+
required: true
|
|
31
|
+
},
|
|
32
|
+
gameweek: {
|
|
33
|
+
type: Number,
|
|
34
|
+
required: true
|
|
35
|
+
},
|
|
36
|
+
activePlayers: [{
|
|
37
|
+
member: {
|
|
38
|
+
type: Schema.Types.ObjectId,
|
|
39
|
+
ref: config.models.poolMember,
|
|
40
|
+
},
|
|
41
|
+
score: {
|
|
42
|
+
type: Number,
|
|
43
|
+
required: true,
|
|
44
|
+
default: 0
|
|
45
|
+
}
|
|
46
|
+
}],
|
|
47
|
+
active: {
|
|
48
|
+
type: Boolean,
|
|
49
|
+
default: false
|
|
50
|
+
},
|
|
51
|
+
startedAt: {
|
|
52
|
+
type: Date,
|
|
53
|
+
required: false,
|
|
54
|
+
default: null
|
|
55
|
+
},
|
|
56
|
+
participationRateBps: {
|
|
57
|
+
type: Number,
|
|
58
|
+
required: false,
|
|
59
|
+
default: 0
|
|
60
|
+
},
|
|
61
|
+
balance: {
|
|
62
|
+
type: String,
|
|
63
|
+
required: false,
|
|
64
|
+
default: "0.00",
|
|
65
|
+
match: poolAmountPattern,
|
|
66
|
+
set: function(value: string) {
|
|
67
|
+
// If value already looks like a float (has a .), ensure two decimals
|
|
68
|
+
if (typeof value === "string") {
|
|
69
|
+
if (poolAmountPattern.test(value)) {
|
|
70
|
+
// If it has a dot but is not two decimals, pad right
|
|
71
|
+
if (value.indexOf('.') !== -1) {
|
|
72
|
+
let [whole, decimals] = value.split('.');
|
|
73
|
+
if (decimals === undefined) return whole + ".00";
|
|
74
|
+
if (decimals.length === 1) return whole + "." + decimals + "0";
|
|
75
|
+
if (decimals.length === 2) return value;
|
|
76
|
+
if (decimals.length > 2) return whole + "." + decimals.slice(0,2);
|
|
77
|
+
}
|
|
78
|
+
// No decimal: add .00
|
|
79
|
+
return value + ".00";
|
|
80
|
+
}
|
|
81
|
+
// If it's an integer, add .00
|
|
82
|
+
if (/^\d+$/.test(value)) {
|
|
83
|
+
return value + ".00";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
winner: {
|
|
90
|
+
type: Schema.Types.ObjectId,
|
|
91
|
+
ref: config.models.poolGameweekWinner,
|
|
92
|
+
required: false,
|
|
93
|
+
default: null
|
|
94
|
+
}
|
|
95
|
+
}, {
|
|
96
|
+
timestamps: true,
|
|
97
|
+
toJSON: {virtuals: true},
|
|
98
|
+
toObject: {virtuals: true}
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
poolGameweekSchema.methods.hasPaid = async function(memberId: Types.ObjectId): Promise<boolean> {
|
|
103
|
+
try{
|
|
104
|
+
return await this.activePlayers.some(({member}: {member: Types.ObjectId, score: number}) => member.toString() === memberId.toString());
|
|
105
|
+
}catch(e: any){
|
|
106
|
+
throw new AdvancedError(e.message, e.statusCode || StatusCode.INTERNAL_SERVER_ERROR)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
const PoolGameweek = model<IPoolGameweek>(config.models.poolGameweek, poolGameweekSchema);
|
|
113
|
+
|
|
114
|
+
export default PoolGameweek;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Schema, model, Types, Document } from "mongoose";
|
|
2
|
+
import config from "../config";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export interface IPoolInvite extends Document {
|
|
6
|
+
_id: Types.ObjectId;
|
|
7
|
+
pool: Types.ObjectId;
|
|
8
|
+
email: string;
|
|
9
|
+
status: PoolInviteStatus;
|
|
10
|
+
invitedAt: Date;
|
|
11
|
+
expiresAt: Date;
|
|
12
|
+
updatedAt: Date;
|
|
13
|
+
hasExpired: () => Promise<boolean>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export enum PoolInviteStatus {
|
|
17
|
+
Pending = "pending",
|
|
18
|
+
Accepted = "accepted",
|
|
19
|
+
Declined = "declined",
|
|
20
|
+
Expired = "expired",
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
const poolInviteSchema = new Schema<IPoolInvite>({
|
|
25
|
+
pool: {
|
|
26
|
+
type: Schema.Types.ObjectId,
|
|
27
|
+
ref: config.models.pool,
|
|
28
|
+
required: true
|
|
29
|
+
},
|
|
30
|
+
email: {
|
|
31
|
+
type: String,
|
|
32
|
+
required: true
|
|
33
|
+
},
|
|
34
|
+
status: {
|
|
35
|
+
type: String,
|
|
36
|
+
required: true,
|
|
37
|
+
enum: PoolInviteStatus,
|
|
38
|
+
default: PoolInviteStatus.Pending
|
|
39
|
+
},
|
|
40
|
+
expiresAt: {
|
|
41
|
+
type: Date,
|
|
42
|
+
required: true,
|
|
43
|
+
default: new Date(Date.now() + (1000 * 60 * 60 * 24 * 7)) //7 days
|
|
44
|
+
}
|
|
45
|
+
}, {
|
|
46
|
+
timestamps: {
|
|
47
|
+
createdAt: 'invitedAt',
|
|
48
|
+
updatedAt: true
|
|
49
|
+
},
|
|
50
|
+
toJSON: {virtuals: true},
|
|
51
|
+
toObject: {virtuals: true}
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
poolInviteSchema.methods.hasExpired = async function(): Promise<boolean> {
|
|
55
|
+
if(Date.now() >= this.expiresAt.getTime() && this.status.toString() !== PoolInviteStatus.Expired.toString()){
|
|
56
|
+
this.status = PoolInviteStatus.Expired;
|
|
57
|
+
await this.save();
|
|
58
|
+
}
|
|
59
|
+
return this.status.toString() === PoolInviteStatus.Expired.toString();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
const PoolInvite = model<IPoolInvite>(config.models.poolInvite, poolInviteSchema);
|
|
64
|
+
|
|
65
|
+
export default PoolInvite;
|