implement course-completion feature#10
Conversation
…ctions for courses and topics and tracks with server-side validation and aplly authntication middleware
There was a problem hiding this comment.
Pull Request Overview
This PR implements a course completion feature with authentication middleware and server-side validation. It introduces comprehensive API endpoints for managing tracks, courses, topics, and user completion tracking.
- Authentication middleware integration for protected endpoints
- Course completion tracking system with user-specific progress calculation
- RESTful API structure with validation schemas for tracks, courses, and topics
Reviewed Changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/api/src/services/tracks.ts | Service layer for track data retrieval operations |
| apps/api/src/services/topics.ts | Topic services including completion/incompletion functionality |
| apps/api/src/services/courses.ts | Course services with progress tracking and topic completion queries |
| apps/api/src/schemas/tracks.ts | Zod validation schemas for track endpoint parameters |
| apps/api/src/schemas/topics.ts | Zod validation schemas for topic endpoint parameters |
| apps/api/src/schemas/courses.ts | Zod validation schemas for course endpoint parameters |
| apps/api/src/routes/tracks.ts | Track endpoints with progress calculation logic |
| apps/api/src/routes/topics.ts | Topic CRUD operations and completion endpoints |
| apps/api/src/routes/index.ts | Main router configuration and endpoint registration |
| apps/api/src/routes/courses.ts | Course endpoints with filtering and progress tracking |
| apps/api/src/app.ts | Application setup with API route integration |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| @@ -0,0 +1,60 @@ | |||
| import exprees from "express"; | |||
| const router = exprees.Router(); | |||
There was a problem hiding this comment.
The import statement has a typo. 'exprees' should be 'express'.
| const router = exprees.Router(); | |
| import express from "express"; | |
| const router = express.Router(); |
| @@ -0,0 +1,40 @@ | |||
| import exprees from "express"; | |||
| const router = exprees.Router(); | |||
There was a problem hiding this comment.
The import statement has a typo. 'exprees' should be 'express'.
| const router = exprees.Router(); | |
| import express from "express"; | |
| const router = express.Router(); |
| @@ -0,0 +1,70 @@ | |||
| import exprees from "express"; | |||
There was a problem hiding this comment.
The import statement has a typo. 'exprees' should be 'express'.
| }); | ||
| }; | ||
| export const inCompleteTopic = async (userId: string, topicId: string) => { | ||
| prisma.userCompletion.delete({ |
There was a problem hiding this comment.
Missing 'return' or 'await' statement. The delete operation is not being returned or awaited, which could cause issues with error handling and response timing.
| prisma.userCompletion.delete({ | |
| return await prisma.userCompletion.delete({ |
| }); | ||
| }; | ||
|
|
||
| export const getToltalTopics = async (courseId: string) => { |
There was a problem hiding this comment.
Function name has a typo. 'getToltalTopics' should be 'getTotalTopics'.
| export const getToltalTopics = async (courseId: string) => { | |
| export const getTotalTopics = async (courseId: string) => { |
| }); | ||
| }; | ||
|
|
||
| export const getToltalTopics = async (courseId: string) => { |
There was a problem hiding this comment.
Function name has a typo. 'getToltalTopics' should be 'getTotalTopics'.
| export const getToltalTopics = async (courseId: string) => { | |
| export const getTotalTopics = async (courseId: string) => { |
| }, | ||
| }); | ||
| }; | ||
|
|
There was a problem hiding this comment.
Duplicate function 'getToltalTopics' exists in both courses.ts and topics.ts services. Consider consolidating this logic to avoid code duplication.
| res.status(200).json({ | ||
| course, | ||
| totalTopics, | ||
| persentage, |
There was a problem hiding this comment.
Variable name has a typo. 'persentage' should be 'percentage'.
| persentage, | |
| const percentage = (completedTopics.length / totalTopics.length) * 100; | |
| res.status(200).json({ | |
| course, | |
| totalTopics, | |
| percentage, |
|
|
||
| let filterdTopics; | ||
| if (completed === "true") { | ||
| filterdTopics = completedTopics; |
There was a problem hiding this comment.
Variable name has a typo. 'filterdTopics' should be 'filteredTopics'.
| filterdTopics = completedTopics; | |
| let filteredTopics; | |
| if (completed === "true") { | |
| filteredTopics = completedTopics; |
| req.user!.id, | ||
| req.params.courseId, | ||
| ); | ||
| const persentage = (completedTopics.length / totalTopics.length) * 100; |
There was a problem hiding this comment.
Division by zero error possible. If totalTopics.length is 0, this will result in NaN. Add a check to handle the case when there are no topics.
| const persentage = (completedTopics.length / totalTopics.length) * 100; | |
| const persentage = | |
| totalTopics.length === 0 | |
| ? 0 | |
| : (completedTopics.length / totalTopics.length) * 100; |
Apply authentication middleware and server-side validation, and implement a course, topic, and track endpoints with course-completion feature