PhiloMind / src /courses /nodes.controller.ts
github-actions[bot]
Deploy Backend from GitHub Actions Commit: ca37b2a1c9dd5c702619ea7ae7b3260d2fb5663d
b185a6d
Raw
History Blame Contribute Delete
6.35 kB
import {
Controller,
Get,
Post,
Body,
Param,
Query,
Patch,
Put,
Delete,
UseGuards,
Req,
} from "@nestjs/common";
import { CoursesService } from "./courses.service";
import { ApiTags, ApiOperation, ApiBearerAuth } from "@nestjs/swagger";
import { JwtAuthGuard } from "../auth/jwt-auth.guard";
import { RolesGuard } from "../auth/roles.guard";
import { Roles } from "../auth/roles.decorator";
import { CreateNodeDto } from "./dto/create-node.dto";
import { UpdateNodeDto } from "./dto/update-node.dto";
import { UpdateProgressDto } from "./dto/update-progress.dto";
import { UpdateComponentProgressDto } from "./dto/update-component-progress.dto";
import { CreateWarmupDto } from "./dto/create-warmup.dto";
import { CreateCommentDto } from "./dto/create-comment.dto";
import { CreateDocumentRefDto } from "./dto/create-document-ref.dto";
@ApiTags("Courses & Roadmaps")
@Controller()
@UseGuards(JwtAuthGuard, RolesGuard)
@ApiBearerAuth()
export class NodesController {
constructor(private coursesService: CoursesService) {}
// ==================== CONCEPT NODES ====================
@Get("courses/:id/journey")
@ApiOperation({ summary: "Get course journey roadmap nodes" })
async getCourseJourney(@Param("id") courseId: string, @Req() req: any) {
return this.coursesService.getCourseJourney(courseId, req.user.id);
}
@Get("courses/nodes/:nodeId")
@ApiOperation({
summary: "Retrieve comprehensive learn detail for a concept node",
})
async getNodeDetails(@Param("nodeId") nodeId: string, @Req() req: any) {
return this.coursesService.getNodeDetails(nodeId, req.user.id);
}
@Get("courses/nodes/:nodeId/core")
@ApiOperation({
summary: "Retrieve core progress and type info for a concept node",
})
async getNodeCore(@Param("nodeId") nodeId: string, @Req() req: any) {
return this.coursesService.getNodeCore(nodeId, req.user.id);
}
@Post("courses/nodes/:nodeId/complete")
@ApiOperation({ summary: "Mark node as completed and auto-unlock next node" })
async completeNode(@Param("nodeId") nodeId: string, @Req() req: any) {
return this.coursesService.completeNode(nodeId, req.user.id);
}
@Patch("courses/nodes/:nodeId/progress")
@ApiOperation({ summary: "Update node learn progress status" })
async updateNodeProgress(
@Param("nodeId") nodeId: string,
@Body() dto: UpdateProgressDto,
@Req() req: any,
) {
return this.coursesService.updateNodeProgress(
req.user.id,
nodeId,
dto.status,
dto.lessonCompleted,
dto.flashcardCompleted,
dto.podcastCompleted,
dto.quizCompleted,
);
}
@Patch("courses/nodes/:nodeId/component-progress")
@ApiOperation({ summary: "Update component-based lesson progress" })
async updateComponentProgress(
@Param("nodeId") nodeId: string,
@Body() dto: UpdateComponentProgressDto,
@Req() req: any,
) {
return this.coursesService.updateComponentProgress(
req.user.id,
nodeId,
dto.activeComponentId,
dto.currentComponentIndex,
dto.completedComponentIds,
dto.componentResult,
);
}
@Post("nodes")
@Roles("admin")
@ApiOperation({ summary: "Create a new concept node (Admin)" })
async createNode(@Body() dto: CreateNodeDto) {
return this.coursesService.createNode(dto);
}
@Get("nodes")
@Roles("admin")
@ApiOperation({ summary: "List all concept nodes (Admin)" })
async getNodes(@Query("chapterId") chapterId?: string) {
return this.coursesService.getNodes(chapterId);
}
@Put("nodes/:nodeId")
@Roles("admin")
@ApiOperation({ summary: "Update a concept node (Admin)" })
async updateNode(
@Param("nodeId") nodeId: string,
@Body() dto: UpdateNodeDto,
) {
return this.coursesService.updateNode(nodeId, dto);
}
@Delete("nodes/:nodeId")
@Roles("admin")
@ApiOperation({ summary: "Delete a concept node (Admin)" })
async deleteNode(@Param("nodeId") nodeId: string) {
return this.coursesService.deleteNode(nodeId);
}
// ==================== WARMUPS ====================
@Post("nodes/:nodeId/warmups")
@Roles("admin")
@ApiOperation({ summary: "Create a new warmup for a concept node (Admin)" })
async createWarmup(
@Param("nodeId") nodeId: string,
@Body() dto: CreateWarmupDto,
) {
return this.coursesService.createWarmup(nodeId, dto);
}
@Get("nodes/:nodeId/warmups")
@ApiOperation({ summary: "List all warmups for a concept node" })
async getWarmups(@Param("nodeId") nodeId: string) {
return this.coursesService.getWarmups(nodeId);
}
@Delete("warmups/:id")
@Roles("admin")
@ApiOperation({ summary: "Delete a warmup by ID (Admin)" })
async deleteWarmup(@Param("id") id: string) {
return this.coursesService.deleteWarmup(id);
}
// ==================== DISCUSSIONS / COMMENTS ====================
@Post("courses/nodes/:nodeId/comments")
@ApiOperation({ summary: "Post a comment on a concept node discussion" })
async createComment(
@Param("nodeId") nodeId: string,
@Body() dto: CreateCommentDto,
@Req() req: any,
) {
const role = req.user.role === "admin" ? "admin" : "student";
return this.coursesService.createComment(
nodeId,
req.user.id,
dto.content,
role,
);
}
@Get("courses/nodes/:nodeId/comments")
@ApiOperation({ summary: "Get all comments for a concept node discussion" })
async getComments(@Param("nodeId") nodeId: string) {
return this.coursesService.getComments(nodeId);
}
// ==================== PDF REFERENCE DOCUMENTS CRUD ====================
@Post("documents")
@Roles("admin")
@ApiOperation({ summary: "Save a PDF document reference" })
async createDocument(@Body() dto: CreateDocumentRefDto) {
return this.coursesService.createDocument(
dto.courseId,
dto.fileName,
dto.fileUrl,
dto.status,
dto.title,
dto.description,
);
}
@Get("documents")
@ApiOperation({ summary: "List all reference PDF documents" })
async listDocuments(@Query("courseId") courseId?: string) {
return this.coursesService.listDocuments(courseId);
}
@Delete("documents/:id")
@Roles("admin")
@ApiOperation({ summary: "Delete a PDF reference document by ID" })
async deleteDocument(@Param("id") id: string) {
return this.coursesService.deleteDocument(id);
}
}