Skip to content
This repository has been archived by the owner on Oct 4, 2024. It is now read-only.

Commit

Permalink
Add Points for Tasks (#237)
Browse files Browse the repository at this point in the history
* enh: Points are now added to the streak

* re-enable verifier for steps
  • Loading branch information
henrybrink authored Jun 18, 2024
1 parent c9578bf commit a33ad2c
Show file tree
Hide file tree
Showing 11 changed files with 51 additions and 14 deletions.
1 change: 1 addition & 0 deletions backend/src/app/streaks/streak.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ import { StreakController } from './streak.controller';
imports: [PrismaModule],
providers: [StreakService],
controllers: [StreakController],
exports: [StreakService],
})
export class StreakModule {}
4 changes: 3 additions & 1 deletion backend/src/app/streaks/streak.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class StreakService {
points,
streak,
history: isStreak
? streakEntries.map((s) => {
? streakEntries.slice(0, streak + 1).map((s) => {
return {
day: s.day,
points: s.points,
Expand Down Expand Up @@ -70,6 +70,8 @@ export class StreakService {
this.repository.updatePoints(user, today, history[0].points + points);
} else if (history[0].day == yesterday) {
this.repository.createStreak(user, points, history[0].streak);
} else {
this.createStreak(user, points, 0);
}
}

Expand Down
12 changes: 12 additions & 0 deletions backend/src/app/tasks/dto/TaskStartStopDTO.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { IsEnum, IsNotEmpty } from 'class-validator';

export enum TaskAction {
START = 'start',
STOP = 'stop',
}

export class TaskStartStopDTO {
@IsNotEmpty()
@IsEnum(TaskAction)
public action: TaskAction;
}
28 changes: 18 additions & 10 deletions backend/src/app/tasks/task.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ import {
FitnessDataNotAvailable,
TaskAlreadyCompleted,
TaskNotAvailableError,
TaskNotStartedError,
TaskService,
} from './task.service';
import { AutoGuard } from '../../auth/auto.guard';
import { NestRequest } from '../../types/request.type';
import { Response } from 'express';
import { Validate } from 'class-validator';
import { TaskAction, TaskStartStopDTO } from './dto/TaskStartStopDTO';

@Controller('task')
export class TaskController {
Expand All @@ -33,20 +36,17 @@ export class TaskController {

@Put('/:id')
@UseGuards(AutoGuard)
@Validate(TaskStartStopDTO)
public async putTask(
@Req() req: NestRequest,
@Param('id') id: string,
@Body('action') action: string,
@Body() taskAction: TaskStartStopDTO,
@Res() response: Response,
) {
if (action == 'start') {
if (taskAction.action == TaskAction.START) {
return this.startTask(req, id, response);
} else if (action == 'stop') {
} else if (taskAction.action == TaskAction.STOP) {
return this.stopTask(req, id, response);
} else {
response
.status(500)
.json({ error: 'action must be either start or stop' });
}
}

Expand Down Expand Up @@ -80,11 +80,19 @@ export class TaskController {
}

private async stopTask(req: NestRequest, id: string, response: Response) {
await this.taskService.stopTask(req.user.id, id);
try {
await this.taskService.stopTask(req.user.id, id);

const task = await this.taskService.getTask(req.user.id, id);
const task = await this.taskService.getTask(req.user.id, id);

response.status(200).json(task?.getInfo());
response.status(200).json(task?.getInfo());
} catch (e) {
if (e instanceof TaskNotStartedError) {
return response.status(400).json({ error: 'Task not started' });
}

return response.status(500).json({ error: 'Unknown error' });
}
}

@Get('/:id')
Expand Down
3 changes: 2 additions & 1 deletion backend/src/app/tasks/task.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { PrismaModule } from '../../db/prisma.module';
import { TaskService } from './task.service';
import { TaskController } from './task.controller';
import FitnessModule from '../../integration/fitness/fitness.module';
import { StreakModule } from '../streaks/streak.module';

@Module({
imports: [PrismaModule, FitnessModule],
imports: [PrismaModule, FitnessModule, StreakModule],
providers: [TaskService],
controllers: [TaskController],
})
Expand Down
6 changes: 5 additions & 1 deletion backend/src/app/tasks/task.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { FitnessService } from '../../integration/fitness/fitness.service';
import FitnessModule from '../../integration/fitness/fitness.module';
import { TestConstants } from '../../../test/lib/constants';
import { MockProvider } from '../../integration/fitness/providers/mock.provider';
import { StreakModule } from '../streaks/streak.module';
import { StreakService } from '../streaks/streak.service';

describe('task service tests', () => {
let taskService: TaskService;
Expand All @@ -15,13 +17,15 @@ describe('task service tests', () => {

beforeAll(async () => {
const testModule = await Test.createTestingModule({
imports: [PrismaModule, FitnessModule],
imports: [PrismaModule, FitnessModule, StreakModule],
providers: [TaskService],
})
.overrideProvider(TaskRepository)
.useValue(mockDeep<TaskRepository>())
.overrideProvider(FitnessService)
.useValue(mockDeep<FitnessService>())
.overrideProvider(StreakService)
.useValue(mockDeep<StreakService>())
.compile();

taskService = testModule.get(TaskService);
Expand Down
7 changes: 6 additions & 1 deletion backend/src/app/tasks/task.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { TaskLog } from '@prisma/client';
import { FitnessService } from '../../integration/fitness/fitness.service';
import { Task2 } from './tasks/static/task2';
import { Task3 } from './tasks/static/task3';
import { StreakService } from '../streaks/streak.service';

export class ConcurrentTaskError extends Error {}
export class TaskNotAvailableError extends Error {}
Expand All @@ -19,6 +20,7 @@ export class TaskService {
constructor(
private taskRepository: TaskRepository,
private fitnessService: FitnessService,
private streakService: StreakService,
) {}

private availableTasks = {
Expand Down Expand Up @@ -143,7 +145,7 @@ export class TaskService {
// Retrieve the fitness data
const fitnessData = await this.fitnessService.getFitnessDataForUser(user);

// Verify the task#
// Verify the task
const taskValidator = new this.availableTasks[log.task]();
const result = taskValidator.validate(
JSON.parse(log.metadata!),
Expand All @@ -152,6 +154,9 @@ export class TaskService {

console.debug(`Fitness Task verified: ${result}`);

// Increase the points of the user
this.streakService.addPoints(user, taskValidator.getInfo().points);

this.taskRepository.updateTaskLog(user, task, {
status: result ? 'completed' : 'failed',
});
Expand Down
1 change: 1 addition & 0 deletions backend/src/app/tasks/tasks/static/task.1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export class Task1 extends StepTask {
id: '1',
title: 'Ein leichter Start',
description: 'Erreiche mindestens 100 Schritte',
points: 10,
conditions: [],
status: this.userStatus,
start: this.start ? dayjs(this.start).format() : undefined,
Expand Down
1 change: 1 addition & 0 deletions backend/src/app/tasks/tasks/static/task2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export class Task2 extends StepTask {
id: '2',
title: 'Deine Reise beginnt',
description: 'Erreiche mindestens 1.000 Schritte',
points: 10,
conditions: [],
status: this.userStatus,
};
Expand Down
1 change: 1 addition & 0 deletions backend/src/app/tasks/tasks/static/task3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export class Task3 extends StepTask {
id: '3',
title: 'Deine Reise wird fortgesetzt',
description: 'Erreiche mindestens 2.000 Schritte',
points: 10,
conditions: [],
status: this.userStatus,
};
Expand Down
1 change: 1 addition & 0 deletions backend/src/app/tasks/tasks/task.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export type TaskInfo = {
id: string;
title: string;
description: string;
points: number;
conditions: {
name: string;
description: string;
Expand Down

0 comments on commit a33ad2c

Please sign in to comment.