Skip to content

Commit 43b4aae

Browse files
Merge pull request #56 from GeneralMagicio/add-user-endpoint
added createuser endpoint
2 parents 411bbf3 + 83d5f7e commit 43b4aae

File tree

6 files changed

+139
-22
lines changed

6 files changed

+139
-22
lines changed

src/poll/Poll.dto.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import {
1212
} from 'class-validator';
1313

1414
export class CreatePollDto {
15+
@IsString()
16+
@IsNotEmpty()
17+
worldID: string;
18+
1519
@IsString()
1620
@IsNotEmpty()
1721
title: string;
@@ -44,6 +48,10 @@ export class CreatePollDto {
4448
}
4549

4650
export class GetPollsDto {
51+
@IsString()
52+
@IsOptional()
53+
worldID?: string;
54+
4755
@IsOptional()
4856
@IsInt()
4957
@Min(1)
@@ -78,3 +86,9 @@ export class GetPollsDto {
7886
@IsEnum(['asc', 'desc'])
7987
sortOrder?: 'asc' | 'desc';
8088
}
89+
90+
export class DeletePollDto {
91+
@IsString()
92+
@IsNotEmpty()
93+
worldID: string;
94+
}

src/poll/poll.controller.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ import {
1010
Delete,
1111
UsePipes,
1212
ValidationPipe,
13+
BadRequestException,
1314
} from '@nestjs/common';
1415
import { Response } from 'express';
1516
import { PollService } from './poll.service';
16-
import { CreatePollDto, GetPollsDto } from './Poll.dto';
17+
import { CreatePollDto, DeletePollDto, GetPollsDto } from './Poll.dto';
1718

1819
@Controller('poll')
1920
export class PollController {
@@ -22,15 +23,24 @@ export class PollController {
2223
@Post()
2324
@UsePipes(ValidationPipe)
2425
create(@Body() createPollDto: CreatePollDto) {
25-
const userId = 1; // need to implement Auth
26-
return this.pollService.createPoll(userId, createPollDto);
26+
return this.pollService.createPoll(createPollDto);
2727
}
2828

2929
@Get()
3030
@UsePipes(ValidationPipe)
31-
getPolls(@Req() req, @Query() query: GetPollsDto) {
32-
const userId = 1;
33-
return this.pollService.getPolls(userId, query);
31+
async getPolls(
32+
@Req() req,
33+
@Query() query: GetPollsDto,
34+
@Res() res: Response,
35+
) {
36+
try {
37+
const polls = await this.pollService.getPolls(query);
38+
return res.status(200).json(polls);
39+
} catch (error: unknown) {
40+
const errorMessage =
41+
error instanceof Error ? error.message : 'An unexpected error occurred';
42+
throw new BadRequestException(errorMessage);
43+
}
3444
}
3545

3646
@Get(':id')
@@ -50,16 +60,19 @@ export class PollController {
5060
}
5161

5262
@Delete(':id')
53-
async deletePoll(@Param('id') id: number, @Res() res: Response) {
54-
const userId = 1; // need to implement Auth
63+
async deletePoll(
64+
@Param('id') id: number,
65+
@Body() query: DeletePollDto,
66+
@Res() res: Response,
67+
) {
5568
try {
56-
const poll = await this.pollService.deletePoll(userId, Number(id));
69+
const poll = await this.pollService.deletePoll(Number(id), query);
5770

5871
return res.status(200).json({ message: 'Poll deleted', poll: poll });
59-
} catch (error) {
60-
return res
61-
.status(500)
62-
.json({ message: 'Internal server error', error: error.message });
72+
} catch (error: unknown) {
73+
const errorMessage =
74+
error instanceof Error ? error.message : 'An unexpected error occurred';
75+
throw new BadRequestException(errorMessage);
6376
}
6477
}
6578
}

src/poll/poll.service.ts

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { BadRequestException, Injectable } from '@nestjs/common';
22
import { ActionType, Prisma } from '@prisma/client';
33
import { DatabaseService } from 'src/database/database.service';
4-
import { CreatePollDto, GetPollsDto } from './Poll.dto';
4+
import { CreatePollDto, DeletePollDto, GetPollsDto } from './Poll.dto';
55

66
@Injectable()
77
export class PollService {
88
constructor(private readonly databaseService: DatabaseService) {}
99

10-
async createPoll(userId: number, createPollDto: CreatePollDto) {
10+
async createPoll(createPollDto: CreatePollDto) {
1111
const user = await this.databaseService.user.findUnique({
12-
where: { id: userId },
12+
where: { worldID: createPollDto.worldID },
1313
});
1414
if (!user) {
1515
throw new BadRequestException('User does not exist');
@@ -30,7 +30,7 @@ export class PollService {
3030
// Create the poll
3131
const newPoll = await tx.poll.create({
3232
data: {
33-
authorUserId: userId,
33+
authorUserId: user.id,
3434
title: createPollDto.title,
3535
description: createPollDto.description,
3636
options: createPollDto.options,
@@ -45,15 +45,15 @@ export class PollService {
4545
// Create user action for CREATED
4646
await tx.userAction.create({
4747
data: {
48-
userId,
48+
userId: user.id,
4949
pollId: newPoll.pollId,
5050
type: ActionType.CREATED,
5151
},
5252
});
5353

5454
// Update user's pollsCreatedCount
5555
await tx.user.update({
56-
where: { id: userId },
56+
where: { worldID: createPollDto.worldID },
5757
data: {
5858
pollsCreatedCount: {
5959
increment: 1,
@@ -65,7 +65,7 @@ export class PollService {
6565
});
6666
}
6767

68-
async getPolls(userId: number, query: GetPollsDto) {
68+
async getPolls(query: GetPollsDto) {
6969
const {
7070
page = 1,
7171
limit = 10,
@@ -78,10 +78,27 @@ export class PollService {
7878
const skip = (page - 1) * limit;
7979
const now = new Date();
8080
const filters: any = {};
81+
let userId: number | undefined;
82+
8183
if (isActive) {
8284
filters.startDate = { lte: now };
8385
filters.endDate = { gt: now };
8486
}
87+
88+
if ((userCreated || userVoted) && query.worldID) {
89+
const user = await this.databaseService.user.findUnique({
90+
where: { worldID: query.worldID },
91+
select: { id: true },
92+
});
93+
94+
if (!user) {
95+
throw new Error('User not found');
96+
}
97+
userId = user.id;
98+
} else if (userCreated || userVoted) {
99+
throw new Error('worldId Not Provided');
100+
}
101+
85102
if (userCreated) {
86103
filters.authorUserId = userId;
87104
}
@@ -135,15 +152,24 @@ export class PollService {
135152
return { user, poll, isActive };
136153
}
137154

138-
async deletePoll(userId: number, pollId: number) {
155+
async deletePoll(pollId: number, query: DeletePollDto) {
156+
const user = await this.databaseService.user.findUnique({
157+
where: { worldID: query.worldID },
158+
select: { id: true },
159+
});
160+
161+
if (!user) {
162+
throw new Error('User not found');
163+
}
164+
139165
const poll = await this.databaseService.poll.findUnique({
140166
where: { pollId },
141167
});
142168

143169
if (!poll) {
144170
throw new Error('Poll not found');
145171
}
146-
if (poll.authorUserId !== userId) {
172+
if (poll.authorUserId !== user.id) {
147173
throw new Error('User Not Authorized');
148174
}
149175

src/user/user.controller.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@ import {
55
Get,
66
Post,
77
Query,
8+
UsePipes,
9+
ValidationPipe,
810
} from '@nestjs/common';
911
import { UserService } from './user.service';
1012
import {
13+
CreateUserDto,
14+
CreateUserResponseDto,
1115
EditVoteDto,
1216
EditVoteResponseDto,
1317
GetUserActivitiesDto,
@@ -84,4 +88,15 @@ export class UserController {
8488
throw new BadRequestException(errorMessage);
8589
}
8690
}
91+
92+
@Post('createUser')
93+
async createUser(@Body() dto: CreateUserDto): Promise<CreateUserResponseDto> {
94+
try {
95+
return await this.userService.createUser(dto);
96+
} catch (error: unknown) {
97+
const errorMessage =
98+
error instanceof Error ? error.message : 'An unexpected error occurred';
99+
throw new BadRequestException(errorMessage);
100+
}
101+
}
87102
}

src/user/user.dto.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
2+
13
export class GetUserDataDto {
24
worldID: string;
35
}
@@ -61,3 +63,21 @@ export class EditVoteDto {
6163
export class EditVoteResponseDto {
6264
actionId: number;
6365
}
66+
67+
export class CreateUserDto {
68+
@IsString()
69+
@IsNotEmpty()
70+
name: string;
71+
72+
@IsString()
73+
@IsNotEmpty()
74+
worldID: string;
75+
76+
@IsString()
77+
@IsOptional()
78+
profilePicture?: string;
79+
}
80+
81+
export class CreateUserResponseDto {
82+
userId: number;
83+
}

src/user/user.service.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
SetVoteResponseDto,
1313
EditVoteDto,
1414
EditVoteResponseDto,
15+
CreateUserDto,
16+
CreateUserResponseDto,
1517
} from './user.dto';
1618
import { ActionType } from '@prisma/client';
1719

@@ -234,4 +236,31 @@ export class UserService {
234236
actionId: userAction.id,
235237
};
236238
}
239+
240+
async createUser(dto: CreateUserDto): Promise<CreateUserResponseDto> {
241+
const existingUser = await this.databaseService.user.findUnique({
242+
where: { worldID: dto.worldID },
243+
});
244+
if (existingUser) {
245+
return {
246+
userId: existingUser?.id,
247+
};
248+
}
249+
250+
const newUser = await this.databaseService.user.create({
251+
data: {
252+
name: dto.name,
253+
worldID: dto.worldID,
254+
profilePicture: dto.profilePicture || null,
255+
},
256+
});
257+
258+
if (!newUser) {
259+
throw new Error('User not created');
260+
}
261+
262+
return {
263+
userId: newUser.id,
264+
};
265+
}
237266
}

0 commit comments

Comments
 (0)