import { Body, Controller, Delete, Get, Headers, Param, Post, Put, } from "@nestjs/common"; import { ChaptersService } from "./chapters.service.js"; import type { ChapterWriteResult } from "./chapters.service.js"; import type { Chapter } from "./chapters.schema.js"; import { Permissions, RequirePermission, } from "../middleware/permission.guard.js"; import { createChapterSchema, updateChapterSchema } from "./chapters.dto.js"; import { extractExpectedVersion } from "../shared/cache/version-header.js"; @Controller("chapters") export class ChaptersController { constructor(private readonly service: ChaptersService) {} @Post() @RequirePermission(Permissions.CONTENT_CHAPTER_CREATE) async create( @Body() body: unknown, ): Promise<{ success: true; data: ChapterWriteResult }> { const input = createChapterSchema.parse(body); const result = await this.service.createChapter(input); return { success: true, data: result }; } @Get("textbook/:textbookId") @RequirePermission(Permissions.CONTENT_CHAPTER_READ) async listByTextbook( @Param("textbookId") textbookId: string, ): Promise<{ success: true; data: Chapter[] }> { const data = await this.service.listChaptersByTextbook(textbookId); return { success: true, data }; } @Get(":id") @RequirePermission(Permissions.CONTENT_CHAPTER_READ) async getById( @Param("id") id: string, ): Promise<{ success: true; data: Chapter }> { const data = await this.service.getChapter(id); return { success: true, data }; } @Put(":id") @RequirePermission(Permissions.CONTENT_CHAPTER_UPDATE) async update( @Param("id") id: string, @Body() body: unknown, @Headers("if-match") ifMatch?: string, @Headers("x-expected-version") xExpectedVersion?: string, ): Promise<{ success: true; data: ChapterWriteResult }> { const input = updateChapterSchema.parse(body); const expectedVersion = extractExpectedVersion(ifMatch, xExpectedVersion); const result = await this.service.updateChapter(id, input, expectedVersion); return { success: true, data: result }; } @Delete(":id") @RequirePermission(Permissions.CONTENT_CHAPTER_DELETE) async remove( @Param("id") id: string, @Headers("if-match") ifMatch?: string, @Headers("x-expected-version") xExpectedVersion?: string, ): Promise<{ success: true; data: { success: true } }> { const expectedVersion = extractExpectedVersion(ifMatch, xExpectedVersion); await this.service.deleteChapter(id, expectedVersion); return { success: true, data: { success: true } }; } }