@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
|
@@ -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;
|