import { Controller, Get, Post, Put, Delete, Body, Param, Query, UseGuards, ParseIntPipe, DefaultValuePipe, } from "@nestjs/common"; import type { AuthUser } from "@mosaic/shared"; import { KnowledgeService } from "./knowledge.service"; import { CreateEntryDto, UpdateEntryDto, EntryQueryDto, RestoreVersionDto } from "./dto"; import { AuthGuard } from "../auth/guards/auth.guard"; import { WorkspaceGuard, PermissionGuard } from "../common/guards"; import { Workspace, Permission, RequirePermission } from "../common/decorators"; import { CurrentUser } from "../auth/decorators/current-user.decorator"; import { LinkSyncService } from "./services/link-sync.service"; /** * Controller for knowledge entry endpoints * All endpoints require authentication and workspace context * Uses the new guard-based permission system */ @Controller("knowledge/entries") @UseGuards(AuthGuard, WorkspaceGuard, PermissionGuard) export class KnowledgeController { constructor( private readonly knowledgeService: KnowledgeService, private readonly linkSync: LinkSyncService ) {} /** * GET /api/knowledge/entries * List all entries in the workspace with pagination and filtering * Requires: Any workspace member */ @Get() @RequirePermission(Permission.WORKSPACE_ANY) async findAll( @Workspace() workspaceId: string, @Query() query: EntryQueryDto ) { return this.knowledgeService.findAll(workspaceId, query); } /** * GET /api/knowledge/entries/:slug * Get a single entry by slug * Requires: Any workspace member */ @Get(":slug") @RequirePermission(Permission.WORKSPACE_ANY) async findOne( @Workspace() workspaceId: string, @Param("slug") slug: string ) { return this.knowledgeService.findOne(workspaceId, slug); } /** * POST /api/knowledge/entries * Create a new knowledge entry * Requires: MEMBER role or higher */ @Post() @RequirePermission(Permission.WORKSPACE_MEMBER) async create( @Workspace() workspaceId: string, @CurrentUser() user: AuthUser, @Body() createDto: CreateEntryDto ) { return this.knowledgeService.create(workspaceId, user.id, createDto); } /** * PUT /api/knowledge/entries/:slug * Update an existing entry * Requires: MEMBER role or higher */ @Put(":slug") @RequirePermission(Permission.WORKSPACE_MEMBER) async update( @Workspace() workspaceId: string, @Param("slug") slug: string, @CurrentUser() user: AuthUser, @Body() updateDto: UpdateEntryDto ) { return this.knowledgeService.update(workspaceId, slug, user.id, updateDto); } /** * DELETE /api/knowledge/entries/:slug * Soft delete an entry (sets status to ARCHIVED) * Requires: ADMIN role or higher */ @Delete(":slug") @RequirePermission(Permission.WORKSPACE_ADMIN) async remove( @Workspace() workspaceId: string, @Param("slug") slug: string, @CurrentUser() user: AuthUser ) { await this.knowledgeService.remove(workspaceId, slug, user.id); return { message: "Entry archived successfully" }; } /** * GET /api/knowledge/entries/:slug/backlinks * Get all backlinks for an entry * Requires: Any workspace member */ @Get(":slug/backlinks") @RequirePermission(Permission.WORKSPACE_ANY) async getBacklinks( @Workspace() workspaceId: string, @Param("slug") slug: string ) { // First find the entry to get its ID const entry = await this.knowledgeService.findOne(workspaceId, slug); // Get backlinks const backlinks = await this.linkSync.getBacklinks(entry.id); return { entry: { id: entry.id, slug: entry.slug, title: entry.title, }, backlinks, count: backlinks.length, }; } /** * GET /api/knowledge/entries/:slug/versions * List all versions for an entry with pagination * Requires: Any workspace member */ @Get(":slug/versions") @RequirePermission(Permission.WORKSPACE_ANY) async getVersions( @Workspace() workspaceId: string, @Param("slug") slug: string, @Query("page", new DefaultValuePipe(1), ParseIntPipe) page: number, @Query("limit", new DefaultValuePipe(20), ParseIntPipe) limit: number ) { return this.knowledgeService.findVersions(workspaceId, slug, page, limit); } /** * GET /api/knowledge/entries/:slug/versions/:version * Get a specific version of an entry * Requires: Any workspace member */ @Get(":slug/versions/:version") @RequirePermission(Permission.WORKSPACE_ANY) async getVersion( @Workspace() workspaceId: string, @Param("slug") slug: string, @Param("version", ParseIntPipe) version: number ) { return this.knowledgeService.findVersion(workspaceId, slug, version); } /** * POST /api/knowledge/entries/:slug/restore/:version * Restore a previous version of an entry * Requires: MEMBER role or higher */ @Post(":slug/restore/:version") @RequirePermission(Permission.WORKSPACE_MEMBER) async restoreVersion( @Workspace() workspaceId: string, @Param("slug") slug: string, @Param("version", ParseIntPipe) version: number, @CurrentUser() user: AuthUser, @Body() restoreDto: RestoreVersionDto ) { return this.knowledgeService.restoreVersion( workspaceId, slug, version, user.id, restoreDto.changeNote ); } }