/** * Knowledge API Client * Handles knowledge entry-related API requests */ import type { KnowledgeEntryWithTags, KnowledgeTag } from "@mosaic/shared"; import { EntryStatus, Visibility } from "@mosaic/shared"; import { apiGet, apiPost, apiPatch, apiDelete, type ApiResponse } from "./client"; export interface EntryFilters { status?: EntryStatus; visibility?: Visibility; tag?: string; tags?: string[]; page?: number; limit?: number; search?: string; sortBy?: "updatedAt" | "createdAt" | "title"; sortOrder?: "asc" | "desc"; } export interface EntriesResponse { data: KnowledgeEntryWithTags[]; meta?: { total?: number; page?: number; limit?: number; }; } export interface CreateEntryData { title: string; content: string; summary?: string; status?: EntryStatus; visibility?: Visibility; tags?: string[]; } export interface UpdateEntryData { title?: string; content?: string; summary?: string; status?: EntryStatus; visibility?: Visibility; tags?: string[]; } /** * Fetch knowledge entries with optional filters */ export async function fetchEntries(filters?: EntryFilters): Promise { const params = new URLSearchParams(); if (filters?.status) { params.append("status", filters.status); } if (filters?.visibility) { params.append("visibility", filters.visibility); } if (filters?.tag) { params.append("tag", filters.tag); } if (filters?.tags && filters.tags.length > 0) { filters.tags.forEach((tag) => params.append("tags", tag)); } if (filters?.page) { params.append("page", filters.page.toString()); } if (filters?.limit) { params.append("limit", filters.limit.toString()); } if (filters?.search) { params.append("search", filters.search); } if (filters?.sortBy) { params.append("sortBy", filters.sortBy); } if (filters?.sortOrder) { params.append("sortOrder", filters.sortOrder); } const queryString = params.toString(); const endpoint = queryString ? `/api/knowledge/entries?${queryString}` : "/api/knowledge/entries"; const response = await apiGet(endpoint); return response; } /** * Fetch a single knowledge entry by slug */ export async function fetchEntry(slug: string): Promise { return apiGet(`/api/knowledge/entries/${slug}`); } /** * Create a new knowledge entry */ export async function createEntry(data: CreateEntryData): Promise { return apiPost("/api/knowledge/entries", data); } /** * Update an existing knowledge entry */ export async function updateEntry( slug: string, data: UpdateEntryData ): Promise { return apiPatch(`/api/knowledge/entries/${slug}`, data); } /** * Delete (archive) a knowledge entry */ export async function deleteEntry(slug: string): Promise { await apiDelete(`/api/knowledge/entries/${slug}`); } /** * Fetch all knowledge tags */ export async function fetchTags(): Promise { const response = await apiGet>("/api/knowledge/tags"); return response.data; } /** * Fetch entry-centered graph view */ export async function fetchEntryGraph(slug: string, depth: number = 1) { const params = new URLSearchParams(); params.append("depth", depth.toString()); return apiGet(`/api/knowledge/entries/${slug}/graph?${params.toString()}`); } /** * Fetch knowledge base statistics */ export async function fetchKnowledgeStats() { return apiGet("/api/knowledge/stats"); } /** * Mock entries for development (until backend endpoints are ready) */ export const mockEntries: KnowledgeEntryWithTags[] = [ { id: "entry-1", workspaceId: "workspace-1", slug: "getting-started", title: "Getting Started with Mosaic Stack", content: "# Getting Started\n\nWelcome to Mosaic Stack...", contentHtml: "

Getting Started

Welcome to Mosaic Stack...

", summary: "A comprehensive guide to getting started with the Mosaic Stack platform.", status: EntryStatus.PUBLISHED, visibility: Visibility.PUBLIC, createdBy: "user-1", updatedBy: "user-1", createdAt: new Date("2026-01-20"), updatedAt: new Date("2026-01-28"), tags: [ { id: "tag-1", workspaceId: "workspace-1", name: "Tutorial", slug: "tutorial", color: "#3B82F6", createdAt: new Date(), updatedAt: new Date(), }, { id: "tag-2", workspaceId: "workspace-1", name: "Onboarding", slug: "onboarding", color: "#10B981", createdAt: new Date(), updatedAt: new Date(), }, ], }, { id: "entry-2", workspaceId: "workspace-1", slug: "architecture-overview", title: "Architecture Overview", content: "# Architecture\n\nThe Mosaic Stack architecture...", contentHtml: "

Architecture

The Mosaic Stack architecture...

", summary: "Overview of the system architecture and design patterns used in Mosaic Stack.", status: EntryStatus.PUBLISHED, visibility: Visibility.WORKSPACE, createdBy: "user-1", updatedBy: "user-1", createdAt: new Date("2026-01-15"), updatedAt: new Date("2026-01-27"), tags: [ { id: "tag-3", workspaceId: "workspace-1", name: "Architecture", slug: "architecture", color: "#8B5CF6", createdAt: new Date(), updatedAt: new Date(), }, { id: "tag-4", workspaceId: "workspace-1", name: "Technical", slug: "technical", color: "#F59E0B", createdAt: new Date(), updatedAt: new Date(), }, ], }, { id: "entry-3", workspaceId: "workspace-1", slug: "api-documentation-draft", title: "API Documentation (Draft)", content: "# API Docs\n\nWork in progress...", contentHtml: "

API Docs

Work in progress...

", summary: "Comprehensive API documentation for developers.", status: EntryStatus.DRAFT, visibility: Visibility.PRIVATE, createdBy: "user-1", updatedBy: "user-1", createdAt: new Date("2026-01-29"), updatedAt: new Date("2026-01-29"), tags: [ { id: "tag-4", workspaceId: "workspace-1", name: "Technical", slug: "technical", color: "#F59E0B", createdAt: new Date(), updatedAt: new Date(), }, { id: "tag-5", workspaceId: "workspace-1", name: "API", slug: "api", color: "#EF4444", createdAt: new Date(), updatedAt: new Date(), }, ], }, { id: "entry-4", workspaceId: "workspace-1", slug: "deployment-guide", title: "Deployment Guide", content: "# Deployment\n\nHow to deploy Mosaic Stack...", contentHtml: "

Deployment

How to deploy Mosaic Stack...

", summary: "Step-by-step guide for deploying Mosaic Stack to production.", status: EntryStatus.PUBLISHED, visibility: Visibility.WORKSPACE, createdBy: "user-1", updatedBy: "user-1", createdAt: new Date("2026-01-18"), updatedAt: new Date("2026-01-25"), tags: [ { id: "tag-6", workspaceId: "workspace-1", name: "DevOps", slug: "devops", color: "#14B8A6", createdAt: new Date(), updatedAt: new Date(), }, { id: "tag-1", workspaceId: "workspace-1", name: "Tutorial", slug: "tutorial", color: "#3B82F6", createdAt: new Date(), updatedAt: new Date(), }, ], }, { id: "entry-5", workspaceId: "workspace-1", slug: "old-meeting-notes", title: "Q4 2025 Meeting Notes", content: "# Meeting Notes\n\nOld archived notes...", contentHtml: "

Meeting Notes

Old archived notes...

", summary: "Meeting notes from Q4 2025 - archived for reference.", status: EntryStatus.ARCHIVED, visibility: Visibility.PRIVATE, createdBy: "user-1", updatedBy: "user-1", createdAt: new Date("2025-12-15"), updatedAt: new Date("2026-01-05"), tags: [ { id: "tag-7", workspaceId: "workspace-1", name: "Meetings", slug: "meetings", color: "#6B7280", createdAt: new Date(), updatedAt: new Date(), }, ], }, ]; export const mockTags: KnowledgeTag[] = [ { id: "tag-1", workspaceId: "workspace-1", name: "Tutorial", slug: "tutorial", color: "#3B82F6", createdAt: new Date(), updatedAt: new Date(), }, { id: "tag-2", workspaceId: "workspace-1", name: "Onboarding", slug: "onboarding", color: "#10B981", createdAt: new Date(), updatedAt: new Date(), }, { id: "tag-3", workspaceId: "workspace-1", name: "Architecture", slug: "architecture", color: "#8B5CF6", createdAt: new Date(), updatedAt: new Date(), }, { id: "tag-4", workspaceId: "workspace-1", name: "Technical", slug: "technical", color: "#F59E0B", createdAt: new Date(), updatedAt: new Date(), }, { id: "tag-5", workspaceId: "workspace-1", name: "API", slug: "api", color: "#EF4444", createdAt: new Date(), updatedAt: new Date(), }, { id: "tag-6", workspaceId: "workspace-1", name: "DevOps", slug: "devops", color: "#14B8A6", createdAt: new Date(), updatedAt: new Date(), }, { id: "tag-7", workspaceId: "workspace-1", name: "Meetings", slug: "meetings", color: "#6B7280", createdAt: new Date(), updatedAt: new Date(), }, ];