Skip to content

Commit 6c016af

Browse files
committed
feat: add soft delete setter and filter
1 parent f7b9f0c commit 6c016af

File tree

7 files changed

+90
-11
lines changed

7 files changed

+90
-11
lines changed

src/controllers/user.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { Controller, Get, Response, Route, Security } from 'tsoa'
1+
import { Body, Controller, Get, Post, Response, Route, Security } from 'tsoa'
22
import { getRankService } from '../services/rank'
3-
import { checkForSuspiciousActivity, getDatabaseUserById, getDatabaseUsers } from '../services/user'
3+
import { checkForSuspiciousActivity, getDatabaseUserById, getDatabaseUsers, softDeleteUserById } from '../services/user'
44
import {
55
ErrorResponseModel,
66
RankRequestResult,
77
RequestResult,
8+
SoftDeleteResult,
89
User
910
} from '../types'
1011

@@ -58,4 +59,21 @@ export class UserController extends Controller {
5859
return []
5960
}
6061
}
62+
63+
@Response<ErrorResponseModel>('404', 'Not Found', {
64+
statusCode: 404,
65+
message: 'Usuário não encontrado'
66+
})
67+
@Security('api_key')
68+
@Post('/susp/softdelete')
69+
public async softDeleteUser(@Body() body: { userId: string }): Promise<SoftDeleteResult> {
70+
try {
71+
const { userId } = body
72+
const result = await softDeleteUserById(userId)
73+
return result
74+
} catch (error) {
75+
console.log(error)
76+
return { success: false, message: 'An error occurred while soft deleting the user' }
77+
}
78+
}
6179
}

src/models/user.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ const UserSchema = new Schema<User>({
2020
tokens: {
2121
type: Array,
2222
required: true
23+
},
24+
softDeleted: {
25+
type: Boolean,
26+
default: false
2327
}
2428
})
2529

src/routes/user.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,18 @@ router.get(
4747
}
4848
)
4949

50+
router.post(
51+
'/susp/softdelete',
52+
middlewares.authentication,
53+
async (request, response, next) => {
54+
try {
55+
const controller = new UserController()
56+
const result = await controller.softDeleteUser(request.body)
57+
return response.send(result)
58+
} catch (error) {
59+
next(error)
60+
}
61+
}
62+
)
63+
5064
export default router

src/services/claim.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ export default async function claimService(
9898
return parseResponseResult('error', config.claim.disabledMessage, 422)
9999
}
100100

101+
const user = await getDatabaseUserById(userId)
102+
if (!user || user.softDeleted) {
103+
return parseResponseResult('error', 'Usuário não encontrado ou banido', 422)
104+
}
105+
101106
if (!code) {
102107
return parseResponseResult('error', 'Nenhum código foi fornecido', 422)
103108
}

src/services/mongoose.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ export async function getUserFromMongo(
128128
try {
129129
await connectMongoose()
130130
const [user] = await UserModel.find({
131-
$or: [{ userId: userIdOrTag }, { tag: userIdOrTag }]
131+
$or: [{ userId: userIdOrTag }, { tag: userIdOrTag }],
132+
softDeleted: { $ne: true }
132133
}).lean()
133134
if (!user) {
134135
return null
@@ -140,10 +141,10 @@ export async function getUserFromMongo(
140141
}
141142
}
142143

143-
export async function getUsersFromMongo(): Promise<User[]> {
144+
export async function getUsersFromMongo(query = {}): Promise<User[]> {
144145
try {
145146
await connectMongoose()
146-
const users = await UserModel.find({})
147+
const users = await UserModel.find({ ...query, softDeleted: { $ne: true } })
147148
if (!users) {
148149
return []
149150
}
@@ -161,7 +162,7 @@ export async function createOrUpdateUser(
161162
await connectMongoose()
162163
const user = await UserModel.findOneAndUpdate(
163164
{ userId: userId },
164-
userContent,
165+
{ ...userContent, softDeleted: userContent.softDeleted ?? false },
165166
{
166167
new: true,
167168
upsert: true
@@ -173,3 +174,18 @@ export async function createOrUpdateUser(
173174
console.log(`Failed to create or update user on mongo: ${error}`)
174175
}
175176
}
177+
178+
export async function softDeleteUser(userId: string): Promise<User | null> {
179+
try {
180+
await connectMongoose()
181+
const user = await UserModel.findOneAndUpdate(
182+
{ userId: userId },
183+
{ softDeleted: true },
184+
{ new: true }
185+
)
186+
return user
187+
} catch (error) {
188+
console.log(`Failed to soft delete user on mongo: ${error}`)
189+
return null
190+
}
191+
}

src/services/user.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { DateTime } from 'luxon'
2-
import { User } from '../types'
2+
import { SoftDeleteResult, User } from '../types'
33
import {
44
createOrUpdateUser,
55
getUserFromMongo,
6-
getUsersFromMongo
6+
getUsersFromMongo,
7+
softDeleteUser
78
} from './mongoose'
89

9-
1010
export async function getDatabaseUserById(userId: string): Promise<User> {
1111
try {
1212
const user = await getUserFromMongo(userId)
@@ -38,7 +38,7 @@ export async function updateDatabaseUser(user: User): Promise<User | false> {
3838

3939
export async function getDatabaseUsers(): Promise<User[]> {
4040
try {
41-
const users = await getUsersFromMongo()
41+
const users = await getUsersFromMongo({ softDeleted: { $ne: true } })
4242
return users
4343
} catch (error) {
4444
console.log(error)
@@ -47,7 +47,7 @@ export async function getDatabaseUsers(): Promise<User[]> {
4747

4848
export async function checkForSuspiciousActivity(): Promise<any[]> {
4949
try {
50-
const users = await getUsersFromMongo()
50+
const users = await getUsersFromMongo({ softDeleted: { $ne: true } })
5151
const suspiciousUsers = users.filter(user => {
5252
if (user.tokens.length < 10) return false
5353

@@ -94,3 +94,16 @@ export async function checkForSuspiciousActivity(): Promise<any[]> {
9494
return []
9595
}
9696
}
97+
98+
export async function softDeleteUserById(userId: string): Promise<SoftDeleteResult> {
99+
try {
100+
const user = await softDeleteUser(userId)
101+
if (!user) {
102+
return { success: false, message: `User ${userId} not found` }
103+
}
104+
return { success: true, message: `User ${userId} has been soft deleted`, user }
105+
} catch (error) {
106+
console.log(`Error soft deleting user ${userId}:`, error)
107+
return { success: false, message: 'An error occurred while soft deleting the user' }
108+
}
109+
}

src/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@ export type User = {
4040
tag: string
4141
score: number
4242
tokens: UserClaimedToken[]
43+
softDeleted?: boolean
4344
}
4445

4546
export type CompactUser = {
4647
userId: string
4748
score: number
4849
tag: string
4950
claims: number
51+
softDeleted?: boolean
5052
}
5153

5254
export type ClaimRequestResult = {
@@ -107,3 +109,10 @@ export interface ErrorResponseModel {
107109
statusCode: number
108110
message: string
109111
}
112+
113+
// Add a new interface for soft delete operations
114+
export interface SoftDeleteResult {
115+
success: boolean
116+
message: string
117+
user?: User
118+
}

0 commit comments

Comments
 (0)