1
+ import { NextFunction , Request , Response } from 'express'
2
+ import { getDatabaseTokenByCode , updateDatabaseToken } from '../services/token'
3
+ import { getDatabaseUserById , updateDatabaseUser } from '../services/user'
4
+ import config from '../config'
5
+
6
+ export async function claim ( request : Request , response : Response , next : NextFunction ) : Promise < void > {
7
+ try {
8
+ if ( ! config . claim . enabled ) {
9
+ response . json ( {
10
+ status : 'error' ,
11
+ message : config . claim . disabledMessage
12
+ } )
13
+ return
14
+ }
15
+
16
+ const { body : { code, email : userId , name : tag } } = request
17
+
18
+ if ( ! code ) {
19
+ response . json ( {
20
+ status : 'error' ,
21
+ message : 'No code was provided'
22
+ } )
23
+ return
24
+ }
25
+
26
+ const token = await getDatabaseTokenByCode ( code )
27
+
28
+ const { claimedBy, remainingClaims, value, decreaseValue, minimumValue, expireAt } = token
29
+
30
+ if ( ! remainingClaims ) {
31
+ response . json ( {
32
+ status : 'error' ,
33
+ message : 'Vish, acabaram os resgates disponíveis para esse token :('
34
+ } )
35
+ return
36
+ }
37
+
38
+ const isExpired = expireAt && new Date ( Date . now ( ) ) > new Date ( expireAt )
39
+ if ( isExpired ) {
40
+ response . json ( {
41
+ status : 'error' ,
42
+ message : 'Esse token expirou :('
43
+ } )
44
+ return
45
+ }
46
+
47
+ const hasAlreadyClaimed = claimedBy . some ( claimedUser => claimedUser . id === userId )
48
+ if ( hasAlreadyClaimed ) {
49
+ response . json ( {
50
+ status : 'error' ,
51
+ message : 'Você já resgatou esse token :eyes:'
52
+ } )
53
+ return
54
+ }
55
+
56
+ const timesClaimed = claimedBy . length
57
+ let scoreAcquired = value - ( timesClaimed * decreaseValue )
58
+ if ( scoreAcquired < minimumValue ) {
59
+ scoreAcquired = minimumValue
60
+ }
61
+
62
+ let userCurrentScore = 0
63
+ let tokensClaimed = [ ]
64
+ const user = await getDatabaseUserById ( userId )
65
+ if ( user ) {
66
+ userCurrentScore = user . score
67
+ tokensClaimed = user . tokens
68
+ }
69
+
70
+ const score = {
71
+ acquired : scoreAcquired ,
72
+ total : userCurrentScore + scoreAcquired
73
+ }
74
+
75
+ const date = new Date ( Date . now ( ) )
76
+ const dateString = date . toISOString ( )
77
+ const claimUser = {
78
+ tag : tag ,
79
+ id : String ( userId ) ,
80
+ claimedAt : dateString
81
+ }
82
+
83
+ const updatedToken = {
84
+ ...token ,
85
+ remainingClaims : remainingClaims - 1 ,
86
+ claimedBy : claimedBy . concat ( claimUser )
87
+ }
88
+
89
+ const updatedUser = {
90
+ userId,
91
+ tag,
92
+ score : score . total ,
93
+ tokens : tokensClaimed . concat ( {
94
+ code,
95
+ value : scoreAcquired ,
96
+ claimedAt : dateString
97
+ } )
98
+ }
99
+
100
+ const userClaimSuccess = await updateDatabaseUser ( updatedUser )
101
+ if ( ! userClaimSuccess ) {
102
+ response . json ( {
103
+ status : 'error' ,
104
+ message : 'Putz, deu ruim ao atualizar o usuário'
105
+ } )
106
+ return
107
+ }
108
+
109
+ const databaseUpdatedToken = await updateDatabaseToken ( updatedToken )
110
+ if ( ! databaseUpdatedToken ) {
111
+ response . json ( {
112
+ status : 'error' ,
113
+ message : 'Putz, deu ruim ao atualizar o token'
114
+ } )
115
+ return
116
+ }
117
+
118
+ response . json ( {
119
+ status : 'success' ,
120
+ message : `O código ${ code } foi resgatado por ${ userId } .`
121
+ } )
122
+ return
123
+ } catch ( error ) {
124
+ next ( error )
125
+ console . log ( error )
126
+ }
127
+ }
128
+
129
+ export default {
130
+ claim
131
+ }
0 commit comments