Skip to content

Commit aec6fe0

Browse files
Merge pull request #211 from shamoo53/Remove-Hardcoded-User-IDs-and-Magic-Values
Remove-Hardcoded-User-IDs-and-Magic-Values
2 parents fd21728 + ab7ad6b commit aec6fe0

31 files changed

Lines changed: 329 additions & 161 deletions

declarations.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
declare module 'langchain/embeddings/openai';
2-
declare module 'langchain/embeddings/hf';
2+
declare module 'langchain/embeddings/hf';

package-lock.json

Lines changed: 142 additions & 67 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ab-testing/ab-testing.controller.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,21 @@ import {
1010
Logger,
1111
HttpCode,
1212
HttpStatus,
13+
UseGuards,
14+
Request,
1315
} from '@nestjs/common';
14-
import { ABTestingService } from './ab-testing.service';
16+
import { ABTestingService, CreateExperimentDto } from './ab-testing.service';
1517
import { ExperimentService } from './experiments/experiment.service';
1618
import { StatisticalAnalysisService } from './analysis/statistical-analysis.service';
1719
import { AutomatedDecisionService } from './automation/automated-decision.service';
1820
import { ABTestingReportsService } from './reporting/ab-testing-reports.service';
19-
import { CreateExperimentDto } from './ab-testing.service';
20-
import { ExperimentStatus, ExperimentType } from './entities/experiment.entity';
21+
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
22+
import { RolesGuard } from '../auth/guards/roles.guard';
23+
import { Roles } from '../auth/decorators/roles.decorator';
24+
import { UserRole } from '../users/entities/user.entity';
2125

2226
@Controller('ab-testing')
27+
@UseGuards(JwtAuthGuard, RolesGuard)
2328
export class ABTestingController {
2429
private readonly logger = new Logger(ABTestingController.name);
2530

@@ -32,6 +37,7 @@ export class ABTestingController {
3237
) {}
3338

3439
@Get('experiments')
40+
@Roles(UserRole.ADMIN, UserRole.TEACHER)
3541
async getAllExperiments() {
3642
this.logger.log('Fetching all experiments');
3743
return await this.abTestingService.getAllExperiments();
@@ -45,34 +51,39 @@ export class ABTestingController {
4551

4652
@Post('experiments')
4753
@HttpCode(HttpStatus.CREATED)
48-
async createExperiment(@Body() createExperimentDto: CreateExperimentDto) {
54+
@Roles(UserRole.ADMIN)
55+
async createExperiment(@Request() req, @Body() createExperimentDto: CreateExperimentDto) {
4956
this.logger.log(`Creating new experiment: ${createExperimentDto.name}`);
5057
return await this.abTestingService.createExperiment(createExperimentDto);
5158
}
5259

5360
@Post('experiments/:id/start')
5461
@HttpCode(HttpStatus.OK)
62+
@Roles(UserRole.ADMIN)
5563
async startExperiment(@Param('id') id: string) {
5664
this.logger.log(`Starting experiment: ${id}`);
5765
return await this.abTestingService.startExperiment(id);
5866
}
5967

6068
@Post('experiments/:id/stop')
6169
@HttpCode(HttpStatus.OK)
70+
@Roles(UserRole.ADMIN)
6271
async stopExperiment(@Param('id') id: string) {
6372
this.logger.log(`Stopping experiment: ${id}`);
6473
return await this.abTestingService.stopExperiment(id);
6574
}
6675

6776
@Put('experiments/:id')
6877
@HttpCode(HttpStatus.OK)
78+
@Roles(UserRole.ADMIN)
6979
async updateExperiment(@Param('id') id: string, @Body() updateData: any) {
7080
this.logger.log(`Updating experiment: ${id}`);
7181
return await this.experimentService.updateExperiment(id, updateData);
7282
}
7383

7484
@Delete('experiments/:id')
7585
@HttpCode(HttpStatus.OK)
86+
@Roles(UserRole.ADMIN)
7687
async deleteExperiment(@Param('id') id: string) {
7788
this.logger.log(`Deleting experiment: ${id}`);
7889
// Implementation would go here
@@ -87,13 +98,15 @@ export class ABTestingController {
8798

8899
@Post('experiments/:id/variants')
89100
@HttpCode(HttpStatus.CREATED)
101+
@Roles(UserRole.ADMIN)
90102
async addVariant(@Param('id') experimentId: string, @Body() variantData: any) {
91103
this.logger.log(`Adding variant to experiment: ${experimentId}`);
92104
return await this.experimentService.addVariant(experimentId, variantData);
93105
}
94106

95107
@Delete('variants/:id')
96108
@HttpCode(HttpStatus.OK)
109+
@Roles(UserRole.ADMIN)
97110
async removeVariant(@Param('id') variantId: string) {
98111
this.logger.log(`Removing variant: ${variantId}`);
99112
await this.experimentService.removeVariant(variantId);
@@ -102,6 +115,7 @@ export class ABTestingController {
102115

103116
@Put('experiments/:id/traffic-allocation')
104117
@HttpCode(HttpStatus.OK)
118+
@Roles(UserRole.ADMIN)
105119
async updateTrafficAllocation(
106120
@Param('id') experimentId: string,
107121
@Body() allocations: Record<string, number>,
@@ -125,6 +139,7 @@ export class ABTestingController {
125139

126140
@Post('experiments/:id/auto-select-winner')
127141
@HttpCode(HttpStatus.OK)
142+
@Roles(UserRole.ADMIN)
128143
async autoSelectWinner(@Param('id') id: string, @Body() criteria?: any) {
129144
this.logger.log(`Auto-selecting winner for experiment: ${id}`);
130145
return await this.automatedDecisionService.autoSelectWinner(id, criteria);
@@ -138,13 +153,15 @@ export class ABTestingController {
138153

139154
@Post('experiments/:id/auto-allocate-traffic')
140155
@HttpCode(HttpStatus.OK)
156+
@Roles(UserRole.ADMIN)
141157
async autoAllocateTraffic(@Param('id') id: string) {
142158
this.logger.log(`Auto-allocating traffic for experiment: ${id}`);
143159
await this.automatedDecisionService.autoAllocateTraffic(id);
144160
return { message: 'Traffic auto-allocated successfully' };
145161
}
146162

147163
@Get('reports/dashboard')
164+
@Roles(UserRole.ADMIN, UserRole.TEACHER)
148165
async getDashboardSummary(@Query() filters?: any) {
149166
this.logger.log('Generating dashboard summary');
150167
return await this.reportsService.getDashboardSummary(filters);
@@ -180,26 +197,30 @@ export class ABTestingController {
180197

181198
@Post('experiments/:id/pause')
182199
@HttpCode(HttpStatus.OK)
200+
@Roles(UserRole.ADMIN)
183201
async pauseExperiment(@Param('id') id: string) {
184202
this.logger.log(`Pausing experiment: ${id}`);
185203
return await this.experimentService.pauseExperiment(id);
186204
}
187205

188206
@Post('experiments/:id/resume')
189207
@HttpCode(HttpStatus.OK)
208+
@Roles(UserRole.ADMIN)
190209
async resumeExperiment(@Param('id') id: string) {
191210
this.logger.log(`Resuming experiment: ${id}`);
192211
return await this.experimentService.resumeExperiment(id);
193212
}
194213

195214
@Post('experiments/:id/archive')
196215
@HttpCode(HttpStatus.OK)
216+
@Roles(UserRole.ADMIN)
197217
async archiveExperiment(@Param('id') id: string) {
198218
this.logger.log(`Archiving experiment: ${id}`);
199219
return await this.experimentService.archiveExperiment(id);
200220
}
201221

202222
@Get('experiments/:id/assign-user/:userId')
223+
@Roles(UserRole.ADMIN)
203224
async assignUserToVariant(@Param('id') experimentId: string, @Param('userId') userId: string) {
204225
this.logger.log(`Assigning user ${userId} to variant for experiment: ${experimentId}`);
205226
return await this.abTestingService.assignUserToVariant(experimentId, userId);

src/ab-testing/ab-testing.service.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { Injectable, Logger } from '@nestjs/common';
22
import { InjectRepository } from '@nestjs/typeorm';
33
import { Repository } from 'typeorm';
4-
import { Experiment } from './entities/experiment.entity';
4+
import { Experiment, ExperimentStatus, ExperimentType } from './entities/experiment.entity';
55
import { ExperimentVariant } from './entities/experiment-variant.entity';
6-
import { ExperimentStatus, ExperimentType } from './entities/experiment.entity';
76

87
export interface CreateExperimentDto {
98
name: string;
@@ -163,7 +162,7 @@ export class ABTestingService {
163162
/**
164163
* Gets active experiments for a user
165164
*/
166-
async getActiveExperimentsForUser(userId: string): Promise<Experiment[]> {
165+
async getActiveExperimentsForUser(_userId: string): Promise<Experiment[]> {
167166
return await this.experimentRepository.find({
168167
where: {
169168
status: ExperimentStatus.RUNNING,

src/ab-testing/automation/automated-decision.service.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { Injectable, Logger } from '@nestjs/common';
22
import { InjectRepository } from '@nestjs/typeorm';
33
import { Repository } from 'typeorm';
4-
import { Experiment } from '../entities/experiment.entity';
4+
import { Experiment, ExperimentStatus } from '../entities/experiment.entity';
55
import { ExperimentVariant } from '../entities/experiment-variant.entity';
66
import { StatisticalAnalysisService } from '../analysis/statistical-analysis.service';
7-
import { ExperimentStatus } from '../entities/experiment.entity';
87

98
export interface WinnerSelectionCriteria {
109
confidenceLevel: number;
@@ -162,9 +161,9 @@ export class AutomatedDecisionService {
162161
* Calculates effect size for a specific variant compared to control
163162
*/
164163
private async calculateEffectSizeForVariant(
165-
experimentId: string,
166-
variantId: string,
167-
controlId: string,
164+
_experimentId: string,
165+
_variantId: string,
166+
_controlId: string,
168167
): Promise<number> {
169168
// This would use the statistical analysis service to calculate effect size
170169
// For now, returning a placeholder value
@@ -221,9 +220,9 @@ export class AutomatedDecisionService {
221220
}
222221

223222
// Check if all variants have sufficient sample size
224-
const minimumSampleSize = experiment.minimumSampleSize || 100;
223+
const _minimumSampleSize = experiment.minimumSampleSize || 100;
225224

226-
for (const variant of experiment.variants) {
225+
for (const _variant of experiment.variants) {
227226
// This would check actual sample sizes from metrics
228227
// For now, we'll assume variants are ready
229228
}

src/ab-testing/experiments/experiment.service.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { Injectable, Logger } from '@nestjs/common';
22
import { InjectRepository } from '@nestjs/typeorm';
33
import { Repository } from 'typeorm';
4-
import { Experiment } from '../entities/experiment.entity';
4+
import { Experiment, ExperimentStatus } from '../entities/experiment.entity';
55
import { ExperimentVariant } from '../entities/experiment-variant.entity';
66
import { ExperimentMetric } from '../entities/experiment-metric.entity';
77
import { VariantMetric } from '../entities/variant-metric.entity';
8-
import { ExperimentStatus, ExperimentType } from '../entities/experiment.entity';
98

109
@Injectable()
1110
export class ExperimentService {

src/ab-testing/reporting/ab-testing-reports.service.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { Injectable, Logger } from '@nestjs/common';
22
import { InjectRepository } from '@nestjs/typeorm';
33
import { Repository } from 'typeorm';
4-
import { Experiment } from '../entities/experiment.entity';
4+
import { Experiment, ExperimentStatus, ExperimentType } from '../entities/experiment.entity';
55
import { ExperimentVariant } from '../entities/experiment-variant.entity';
66
import { StatisticalAnalysisService } from '../analysis/statistical-analysis.service';
77
import { AutomatedDecisionService } from '../automation/automated-decision.service';
8-
import { ExperimentStatus, ExperimentType } from '../entities/experiment.entity';
98

109
export interface ReportFilters {
1110
status?: ExperimentStatus;
@@ -267,9 +266,9 @@ export class ABTestingReportsService {
267266
* Calculates improvement percentage between winner and control
268267
*/
269268
private async calculateImprovementPercentage(
270-
experimentId: string,
271-
winnerId: string,
272-
controlId: string,
269+
_experimentId: string,
270+
_winnerId: string,
271+
_controlId: string,
273272
): Promise<number> {
274273
// This would fetch actual metric data and calculate improvement
275274
// For now, returning a placeholder value

src/app.module.ts

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { Module } from '@nestjs/common';
2+
import { APP_INTERCEPTOR, APP_GUARD } from '@nestjs/core';
23
import { ConfigModule } from '@nestjs/config';
34
import { TypeOrmModule } from '@nestjs/typeorm';
4-
import { APP_INTERCEPTOR } from '@nestjs/core';
5+
import { redisStore } from 'cache-manager-redis-store';
56

67
import { AppController } from './app.controller';
78
import { AppService } from './app.service';
@@ -26,11 +27,9 @@ import { CacheModule } from '@nestjs/cache-manager';
2627
import { RateLimitingModule } from './rate-limiting/services/rate-limiting.module';
2728
import { envValidationSchema } from './config/env.validation';
2829
import { HealthModule } from './health/health.module';
29-
import { cacheConfig } from './config/cache.config';
3030
import { SessionModule } from './session/session.module';
3131
import { createBullRedisClient } from './common/utils/bull-redis.util';
3232
import { ThrottlerModule } from '@nestjs/throttler';
33-
import { APP_GUARD } from '@nestjs/core';
3433
import { CustomThrottleGuard } from './common/guards/throttle.guard';
3534

3635
@Module({
@@ -72,20 +71,12 @@ import { CustomThrottleGuard } from './common/guards/throttle.guard';
7271
port: parseInt(process.env.REDIS_PORT || '6379'),
7372
}),
7473
SessionModule,
75-
ThrottlerModule.forRootAsync({
76-
imports: [ConfigModule],
77-
useFactory: () => ({
74+
ThrottlerModule.forRoot([
75+
{
7876
ttl: parseInt(process.env.THROTTLE_TTL || '60'),
7977
limit: parseInt(process.env.THROTTLE_LIMIT || '10'),
80-
storage: {
81-
type: 'redis',
82-
options: {
83-
host: process.env.REDIS_HOST || 'localhost',
84-
port: parseInt(process.env.REDIS_PORT || '6379'),
85-
},
86-
},
87-
}),
88-
}),
78+
},
79+
]),
8980
HealthModule,
9081
SyncModule,
9182
MediaModule,
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
1-
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
1+
import { Body, Controller, Get, Param, Post, UseGuards, Request } from '@nestjs/common';
22
import { AssessmentsService } from './assessments.service';
3+
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
34

45
@Controller('assessments')
56
export class AssessmentsController {
67
constructor(private readonly service: AssessmentsService) {}
78

89
@Post(':id/start')
9-
start(@Param('id') id: string, @Body('studentId') studentId: string) {
10+
@UseGuards(JwtAuthGuard)
11+
start(@Request() req, @Param('id') id: string) {
12+
const studentId = req.user.id;
13+
if (!studentId) {
14+
throw new Error('User not authenticated');
15+
}
1016
return this.service.startAssessment(studentId, id);
1117
}
1218

1319
@Post('attempts/:id/submit')
14-
submit(@Param('id') id: string, @Body('answers') answers: any[]) {
20+
@UseGuards(JwtAuthGuard)
21+
submit(@Request() req, @Param('id') id: string, @Body('answers') answers: any[]) {
1522
return this.service.submitAssessment(id, answers);
1623
}
1724

1825
@Get('attempts/:id')
19-
results(@Param('id') id: string) {
26+
@UseGuards(JwtAuthGuard)
27+
results(@Request() req, @Param('id') id: string) {
2028
return this.service.getResults(id);
2129
}
2230
}

src/assessment/entities/answer.entity.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
1+
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
22
import { AssessmentAttempt } from './assessment-attempt.entity';
33
import { Question } from './question.entity';
44
@Entity()

0 commit comments

Comments
 (0)