7
7
ForbiddenException ,
8
8
} from '@nestjs/common' ;
9
9
import { InjectRepository } from '@nestjs/typeorm' ;
10
- import { In , Not , Repository } from 'typeorm' ;
10
+ import { Between , In , Not , Repository } from 'typeorm' ;
11
11
import { Project } from './project.model' ;
12
12
import { ProjectPackages } from './project-packages.model' ;
13
13
import {
@@ -26,6 +26,11 @@ import { BuilderContext } from 'src/build-system/context';
26
26
import { ChatService } from 'src/chat/chat.service' ;
27
27
import { Chat } from 'src/chat/chat.model' ;
28
28
import { v4 as uuidv4 } from 'uuid' ;
29
+ import {
30
+ PROJECT_DAILY_LIMIT ,
31
+ ProjectRateLimitException ,
32
+ } from './project-limits' ;
33
+
29
34
@Injectable ( )
30
35
export class ProjectService {
31
36
private readonly model : OpenAIModelProvider =
@@ -119,12 +124,41 @@ export class ProjectService {
119
124
}
120
125
}
121
126
127
+ /**
128
+ * Checks if a user has exceeded their daily project creation limit
129
+ * @param userId The user ID to check
130
+ * @returns A boolean indicating whether the user can create more projects today
131
+ */
132
+ async canCreateProject ( userId : string ) : Promise < boolean > {
133
+ const today = new Date ( ) ;
134
+ today . setHours ( 0 , 0 , 0 , 0 ) ; // Start of today
135
+
136
+ const tomorrow = new Date ( today ) ;
137
+ tomorrow . setDate ( tomorrow . getDate ( ) + 1 ) ; // Start of tomorrow
138
+
139
+ // Count projects created by user today
140
+ const todayProjectCount = await this . projectsRepository . count ( {
141
+ where : {
142
+ userId : userId ,
143
+ createdAt : Between ( today , tomorrow ) ,
144
+ } ,
145
+ } ) ;
146
+
147
+ return todayProjectCount < PROJECT_DAILY_LIMIT ;
148
+ }
149
+
122
150
async createProject (
123
151
input : CreateProjectInput ,
124
152
userId : string ,
125
153
) : Promise < Chat > {
126
154
try {
127
- // First, handle project name generation if needed (this is the only sync operation we need)
155
+ //First check if user have reach the create project limit
156
+ const canCreate = await this . canCreateProject ( userId ) ;
157
+ if ( ! canCreate ) {
158
+ throw new ProjectRateLimitException ( PROJECT_DAILY_LIMIT ) ;
159
+ }
160
+
161
+ // handle project name generation if needed (this is the only sync operation we need)
128
162
let projectName = input . projectName ;
129
163
if ( ! projectName || projectName === '' ) {
130
164
this . logger . debug (
@@ -164,6 +198,10 @@ export class ProjectService {
164
198
// Return chat immediately so user can start interacting
165
199
return defaultChat ;
166
200
} catch ( error ) {
201
+ if ( error instanceof ProjectRateLimitException ) {
202
+ throw error . getGraphQLError ( ) ; // Throw as a GraphQL error for the client
203
+ }
204
+
167
205
this . logger . error (
168
206
`Error in createProject: ${ error . message } ` ,
169
207
error . stack ,
@@ -602,4 +640,27 @@ export class ProjectService {
602
640
603
641
return [ ] ;
604
642
}
643
+
644
+ /**
645
+ * Gets the number of projects a user can still create today
646
+ * @param userId The user ID to check
647
+ * @returns The number of remaining projects the user can create today
648
+ */
649
+ async getRemainingProjectLimit ( userId : string ) : Promise < number > {
650
+ const today = new Date ( ) ;
651
+ today . setHours ( 0 , 0 , 0 , 0 ) ; // Start of today
652
+
653
+ const tomorrow = new Date ( today ) ;
654
+ tomorrow . setDate ( tomorrow . getDate ( ) + 1 ) ; // Start of tomorrow
655
+
656
+ // Count projects created by this user today
657
+ const todayProjectCount = await this . projectsRepository . count ( {
658
+ where : {
659
+ userId : userId ,
660
+ createdAt : Between ( today , tomorrow ) ,
661
+ } ,
662
+ } ) ;
663
+
664
+ return Math . max ( 0 , PROJECT_DAILY_LIMIT - todayProjectCount ) ;
665
+ }
605
666
}
0 commit comments