11import { BadRequestException , Injectable } from '@nestjs/common' ;
2- import { ActionType , Prisma } from '@prisma/client' ;
2+ import { ActionType } from '@prisma/client' ;
33import { DatabaseService } from 'src/database/database.service' ;
4+ import {
5+ PollNotFoundException ,
6+ UnauthorizedActionException ,
7+ UserNotFoundException ,
8+ } from '../common/exceptions' ;
49import { CreatePollDto , DeletePollDto , GetPollsDto } from './Poll.dto' ;
510
611@Injectable ( )
@@ -12,22 +17,18 @@ export class PollService {
1217 where : { worldID : createPollDto . worldID } ,
1318 } ) ;
1419 if ( ! user ) {
15- throw new BadRequestException ( 'User does not exist' ) ;
20+ throw new UserNotFoundException ( ) ;
1621 }
1722 const startDate = new Date ( createPollDto . startDate ) ;
1823 const endDate = new Date ( createPollDto . endDate ) ;
1924 const now = new Date ( ) ;
20-
2125 if ( startDate < now ) {
2226 throw new BadRequestException ( 'Start date cannot be in the past' ) ;
2327 }
24-
2528 if ( endDate <= startDate ) {
2629 throw new BadRequestException ( 'End date must be after start date' ) ;
2730 }
28-
2931 return this . databaseService . $transaction ( async ( tx ) => {
30- // Create the poll
3132 const newPoll = await tx . poll . create ( {
3233 data : {
3334 authorUserId : user . id ,
@@ -38,29 +39,28 @@ export class PollService {
3839 endDate,
3940 tags : createPollDto . tags || [ ] ,
4041 isAnonymous : createPollDto . isAnonymous || false ,
41- voteResults : { } , // Initialize empty vote results
42+ voteResults : { } ,
4243 } ,
4344 } ) ;
44-
45- // Create user action for CREATED
4645 await tx . userAction . create ( {
4746 data : {
4847 userId : user . id ,
4948 pollId : newPoll . pollId ,
5049 type : ActionType . CREATED ,
5150 } ,
5251 } ) ;
53-
54- // Update user's pollsCreatedCount
52+ const pollsCreatedCount = await tx . userAction . count ( {
53+ where : {
54+ userId : user . id ,
55+ type : ActionType . CREATED ,
56+ } ,
57+ } ) ;
5558 await tx . user . update ( {
5659 where : { worldID : createPollDto . worldID } ,
5760 data : {
58- pollsCreatedCount : {
59- increment : 1 ,
60- } ,
61+ pollsCreatedCount,
6162 } ,
6263 } ) ;
63-
6464 return newPoll ;
6565 } ) ;
6666 }
@@ -95,7 +95,7 @@ export class PollService {
9595 } ) ;
9696
9797 if ( ! user ) {
98- throw new Error ( 'User not found' ) ;
98+ throw new UserNotFoundException ( ) ;
9999 }
100100 userId = user . id ;
101101 } else if ( userCreated || userVoted ) {
@@ -154,48 +154,46 @@ export class PollService {
154154 async getPollDetails ( id : number ) {
155155 const poll = await this . databaseService . poll . findUnique ( {
156156 where : { pollId : id } ,
157+ include : {
158+ author : true ,
159+ } ,
157160 } ) ;
158161 if ( ! poll ) {
159- throw new Error ( 'Poll Id not found' ) ;
162+ throw new PollNotFoundException ( ) ;
160163 }
161- const user = await this . databaseService . user . findUnique ( {
162- where : { id : poll ?. authorUserId } ,
163- } ) ;
164164 const now = new Date ( ) ;
165165 const isActive = now >= poll . startDate && now <= poll . endDate ;
166-
167- return { user, poll, isActive } ;
166+ const optionsTotalVotes = await this . getPollQuadraticResults ( id ) ;
167+ const totalVotes = Object . values ( optionsTotalVotes ) . reduce (
168+ ( acc , votes ) => acc + votes ,
169+ 0 ,
170+ ) ;
171+ return { poll, isActive, optionsTotalVotes, totalVotes } ;
168172 }
169173
170174 async deletePoll ( pollId : number , query : DeletePollDto ) {
171175 const user = await this . databaseService . user . findUnique ( {
172176 where : { worldID : query . worldID } ,
173177 select : { id : true } ,
174178 } ) ;
175-
176179 if ( ! user ) {
177- throw new Error ( 'User not found' ) ;
180+ throw new UserNotFoundException ( ) ;
178181 }
179-
180182 const poll = await this . databaseService . poll . findUnique ( {
181183 where : { pollId } ,
182184 } ) ;
183-
184185 if ( ! poll ) {
185- throw new Error ( 'Poll not found' ) ;
186+ throw new PollNotFoundException ( ) ;
186187 }
187188 if ( poll . authorUserId !== user . id ) {
188- throw new Error ( 'User Not Authorized' ) ;
189+ throw new UnauthorizedActionException ( ) ;
189190 }
190-
191191 return this . databaseService . $transaction ( async ( tx ) => {
192192 const deleted = await tx . poll . delete ( {
193193 where : {
194194 pollId,
195195 } ,
196196 } ) ;
197-
198- // Update user's pollsCreatedCount
199197 await tx . user . update ( {
200198 where : { id : deleted . authorUserId } ,
201199 data : {
@@ -204,8 +202,40 @@ export class PollService {
204202 } ,
205203 } ,
206204 } ) ;
207-
208205 return deleted ;
209206 } ) ;
210207 }
208+
209+ async getPollQuadraticResults (
210+ pollId : number ,
211+ ) : Promise < Record < string , number > > {
212+ const poll = await this . databaseService . poll . findUnique ( {
213+ where : { pollId } ,
214+ select : { options : true } ,
215+ } ) ;
216+ if ( ! poll ) {
217+ throw new PollNotFoundException ( ) ;
218+ }
219+ const votes = await this . databaseService . vote . findMany ( {
220+ where : { pollId } ,
221+ select : { quadraticWeights : true } ,
222+ } ) ;
223+ const result : Record < string , number > = poll . options . reduce (
224+ ( acc , option ) => {
225+ acc [ option ] = 0 ;
226+ return acc ;
227+ } ,
228+ { } as Record < string , number > ,
229+ ) ;
230+ votes . forEach ( ( vote ) => {
231+ if ( vote . quadraticWeights ) {
232+ Object . entries ( vote . quadraticWeights as Record < string , number > ) . forEach (
233+ ( [ option , weight ] ) => {
234+ result [ option ] = ( result [ option ] || 0 ) + weight ;
235+ } ,
236+ ) ;
237+ }
238+ } ) ;
239+ return result ;
240+ }
211241}
0 commit comments