Skip to content

Commit 81e3832

Browse files
committed
fix: upsert user url path
1 parent 6f3ae12 commit 81e3832

File tree

3 files changed

+58
-99
lines changed

3 files changed

+58
-99
lines changed

openapi.json

Lines changed: 11 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"hash": "50b02791c7a6d303f38dd96ffece6974ae0eb8160c754e35f57027533f749d24",
2+
"hash": "c80adbd84331e9f7fe3c09aabc748e951271b91b5a3c134306b310209049b0a9",
33
"openapi": "3.0.0",
44
"paths": {
55
"/hello": {
@@ -4414,19 +4414,10 @@
44144414
]
44154415
}
44164416
},
4417-
"/users/{employeeId}/@upsertUserByEmployeeId": {
4417+
"/users/@upsertUserByEmployeeId": {
44184418
"post": {
44194419
"operationId": "upsertUserByEmployeeId",
4420-
"parameters": [
4421-
{
4422-
"name": "employeeId",
4423-
"required": true,
4424-
"in": "path",
4425-
"schema": {
4426-
"type": "string"
4427-
}
4428-
}
4429-
],
4420+
"parameters": [],
44304421
"requestBody": {
44314422
"required": true,
44324423
"content": {
@@ -4465,19 +4456,10 @@
44654456
]
44664457
}
44674458
},
4468-
"/users/{userId}/@upsertUserById": {
4459+
"/users/@upsertUserById": {
44694460
"post": {
44704461
"operationId": "upsertUserById",
4471-
"parameters": [
4472-
{
4473-
"name": "userId",
4474-
"required": true,
4475-
"in": "path",
4476-
"schema": {
4477-
"type": "string"
4478-
}
4479-
}
4480-
],
4462+
"parameters": [],
44814463
"requestBody": {
44824464
"required": true,
44834465
"content": {
@@ -4516,19 +4498,10 @@
45164498
]
45174499
}
45184500
},
4519-
"/users/{username}/@upsertUserByUsername": {
4501+
"/users/@upsertUserByUsername": {
45204502
"post": {
45214503
"operationId": "upsertUserByUsername",
4522-
"parameters": [
4523-
{
4524-
"name": "username",
4525-
"required": true,
4526-
"in": "path",
4527-
"schema": {
4528-
"type": "string"
4529-
}
4530-
}
4531-
],
4504+
"parameters": [],
45324505
"requestBody": {
45334506
"required": true,
45344507
"content": {
@@ -4567,19 +4540,10 @@
45674540
]
45684541
}
45694542
},
4570-
"/users/{email}/@upsertUserByEmail": {
4543+
"/users/@upsertUserByEmail": {
45714544
"post": {
45724545
"operationId": "upsertUserByEmail",
4573-
"parameters": [
4574-
{
4575-
"name": "email",
4576-
"required": true,
4577-
"in": "path",
4578-
"schema": {
4579-
"type": "string"
4580-
}
4581-
}
4582-
],
4546+
"parameters": [],
45834547
"requestBody": {
45844548
"required": true,
45854549
"content": {
@@ -4618,19 +4582,10 @@
46184582
]
46194583
}
46204584
},
4621-
"/users/{phone}/@upsertUserByPhone": {
4585+
"/users/@upsertUserByPhone": {
46224586
"post": {
46234587
"operationId": "upsertUserByPhone",
4624-
"parameters": [
4625-
{
4626-
"name": "phone",
4627-
"required": true,
4628-
"in": "path",
4629-
"schema": {
4630-
"type": "string"
4631-
}
4632-
}
4633-
],
4588+
"parameters": [],
46344589
"requestBody": {
46354590
"required": true,
46364591
"content": {

src/user/user.controller.ts

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,12 @@ export class UserController {
148148
})
149149
@UseInterceptors(UnsetCacheInterceptor)
150150
@CacheKey('/users/:id')
151-
@Post(':employeeId/@upsertUserByEmployeeId')
152-
async upsertByEmployeeId(
153-
@Param('employeeId') employeeId: string,
154-
@Body() dto: CreateUserDto
155-
): Promise<UserDocument> {
151+
@Post('@upsertUserByEmployeeId')
152+
async upsertByEmployeeId(@Body() dto: CreateUserDto): Promise<UserDocument> {
153+
this.requireUpsertKey(dto.employeeId, 'employeeId', 'upsertByEmployeeId');
156154
await this.ensureNamespaceExists(dto.ns);
157155

158-
return this.userService.upsertByEmployee(employeeId, dto);
156+
return this.userService.upsertByEmployee(dto.employeeId as string, dto);
159157
}
160158

161159
/**
@@ -168,14 +166,12 @@ export class UserController {
168166
})
169167
@UseInterceptors(UnsetCacheInterceptor)
170168
@CacheKey('/users/:id')
171-
@Post(':userId/@upsertUserById')
172-
async upsertById(
173-
@Param('userId') userId: string,
174-
@Body() dto: CreateUserDto
175-
): Promise<UserDocument> {
169+
@Post('@upsertUserById')
170+
async upsertById(@Body() dto: CreateUserDto): Promise<UserDocument> {
171+
this.requireUpsertKey(dto.id, 'id', 'upsertById');
176172
await this.ensureNamespaceExists(dto.ns);
177173

178-
return this.userService.upsertById(userId, { ...dto, id: userId });
174+
return this.userService.upsertById(dto.id as string, dto);
179175
}
180176

181177
/**
@@ -188,14 +184,12 @@ export class UserController {
188184
})
189185
@UseInterceptors(UnsetCacheInterceptor)
190186
@CacheKey('/users/:id')
191-
@Post(':username/@upsertUserByUsername')
192-
async upsertByUsername(
193-
@Param('username') username: string,
194-
@Body() dto: CreateUserDto
195-
): Promise<UserDocument> {
187+
@Post('@upsertUserByUsername')
188+
async upsertByUsername(@Body() dto: CreateUserDto): Promise<UserDocument> {
189+
this.requireUpsertKey(dto.username, 'username', 'upsertByUsername');
196190
await this.ensureNamespaceExists(dto.ns);
197191

198-
return this.userService.upsertByUsername(username, dto);
192+
return this.userService.upsertByUsername(dto.username as string, dto);
199193
}
200194

201195
/**
@@ -208,14 +202,12 @@ export class UserController {
208202
})
209203
@UseInterceptors(UnsetCacheInterceptor)
210204
@CacheKey('/users/:id')
211-
@Post(':email/@upsertUserByEmail')
212-
async upsertByEmail(
213-
@Param('email') email: string,
214-
@Body() dto: CreateUserDto
215-
): Promise<UserDocument> {
205+
@Post('@upsertUserByEmail')
206+
async upsertByEmail(@Body() dto: CreateUserDto): Promise<UserDocument> {
207+
this.requireUpsertKey(dto.email, 'email', 'upsertByEmail');
216208
await this.ensureNamespaceExists(dto.ns);
217209

218-
return this.userService.upsertByEmail(email, dto);
210+
return this.userService.upsertByEmail(dto.email as string, dto);
219211
}
220212

221213
/**
@@ -228,14 +220,26 @@ export class UserController {
228220
})
229221
@UseInterceptors(UnsetCacheInterceptor)
230222
@CacheKey('/users/:id')
231-
@Post(':phone/@upsertUserByPhone')
232-
async upsertByPhone(
233-
@Param('phone') phone: string,
234-
@Body() dto: CreateUserDto
235-
): Promise<UserDocument> {
223+
@Post('@upsertUserByPhone')
224+
async upsertByPhone(@Body() dto: CreateUserDto): Promise<UserDocument> {
225+
this.requireUpsertKey(dto.phone, 'phone', 'upsertByPhone');
236226
await this.ensureNamespaceExists(dto.ns);
237227

238-
return this.userService.upsertByPhone(phone, dto);
228+
return this.userService.upsertByPhone(dto.phone as string, dto);
229+
}
230+
231+
private requireUpsertKey(
232+
value: string | null | undefined,
233+
field: 'employeeId' | 'id' | 'username' | 'email' | 'phone',
234+
operation: string
235+
): asserts value is string {
236+
if (!value) {
237+
throw new BadRequestException({
238+
code: ErrorCodes.VALIDATE_FAILED,
239+
message: `${field} is required for ${operation}.`,
240+
keyValue: { field },
241+
});
242+
}
239243
}
240244

241245
private async ensureNamespaceExists(ns?: string): Promise<void> {

test/user.e2e-spec.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ describe('User crud (e2e)', () => {
6060
});
6161

6262
it(`Create user`, async () => {
63-
const userDoc = mockUser();
63+
const userDoc = { ...mockUser(), ns: `test-ns-${nanoid(8)}` };
6464

6565
// ns 不存在
6666
await request(app.getHttpServer())
@@ -211,8 +211,8 @@ describe('User crud (e2e)', () => {
211211
});
212212

213213
const createResp = await request(app.getHttpServer())
214-
.post(`/users/${userId}/@upsertUserById`)
215-
.send(userDoc)
214+
.post('/users/@upsertUserById')
215+
.send({ ...userDoc, id: userId })
216216
.set('Content-Type', 'application/json')
217217
.set('x-api-key', auth.apiKey)
218218
.set('Accept', 'application/json')
@@ -221,8 +221,8 @@ describe('User crud (e2e)', () => {
221221
expect(createResp.body.id).toBe(userId);
222222

223223
const updateResp = await request(app.getHttpServer())
224-
.post(`/users/${userId}/@upsertUserById`)
225-
.send({ ...userDoc, intro: 'updated by id' })
224+
.post('/users/@upsertUserById')
225+
.send({ ...userDoc, id: userId, intro: 'updated by id' })
226226
.set('Content-Type', 'application/json')
227227
.set('x-api-key', auth.apiKey)
228228
.set('Accept', 'application/json')
@@ -264,8 +264,8 @@ describe('User crud (e2e)', () => {
264264

265265
// upsertByEmail: username conflict
266266
const upsertByEmailConflictResp = await request(app.getHttpServer())
267-
.post(`/users/${encodeURIComponent(userA.email)}/@upsertUserByEmail`)
268-
.send({ ...mockUser(), ns, username: userB.username })
267+
.post('/users/@upsertUserByEmail')
268+
.send({ ...mockUser(), ns, email: userA.email, username: userB.username })
269269
.set('Content-Type', 'application/json')
270270
.set('x-api-key', auth.apiKey)
271271
.set('Accept', 'application/json')
@@ -274,8 +274,8 @@ describe('User crud (e2e)', () => {
274274

275275
// upsertByPhone: email conflict
276276
const upsertByPhoneConflictResp = await request(app.getHttpServer())
277-
.post(`/users/${userA.phone}/@upsertUserByPhone`)
278-
.send({ ...mockUser(), ns, email: userB.email })
277+
.post('/users/@upsertUserByPhone')
278+
.send({ ...mockUser(), ns, phone: userA.phone, email: userB.email })
279279
.set('Content-Type', 'application/json')
280280
.set('x-api-key', auth.apiKey)
281281
.set('Accept', 'application/json')
@@ -284,8 +284,8 @@ describe('User crud (e2e)', () => {
284284

285285
// upsertByEmployeeId: phone conflict
286286
const upsertByEmployeeIdConflictResp = await request(app.getHttpServer())
287-
.post(`/users/${baseA.employeeId}/@upsertUserByEmployeeId`)
288-
.send({ ...mockUser(), ns, phone: userB.phone })
287+
.post('/users/@upsertUserByEmployeeId')
288+
.send({ ...mockUser(), ns, employeeId: baseA.employeeId, phone: userB.phone })
289289
.set('Content-Type', 'application/json')
290290
.set('x-api-key', auth.apiKey)
291291
.set('Accept', 'application/json')
@@ -294,8 +294,8 @@ describe('User crud (e2e)', () => {
294294

295295
// upsertByUsername: employeeId conflict
296296
const upsertByUsernameConflictResp = await request(app.getHttpServer())
297-
.post(`/users/${userA.username}/@upsertUserByUsername`)
298-
.send({ ...mockUser(), ns, employeeId: baseB.employeeId })
297+
.post('/users/@upsertUserByUsername')
298+
.send({ ...mockUser(), ns, username: userA.username, employeeId: baseB.employeeId })
299299
.set('Content-Type', 'application/json')
300300
.set('x-api-key', auth.apiKey)
301301
.set('Accept', 'application/json')

0 commit comments

Comments
 (0)