feat: member portal Sprint 10 — Knowledge Base
- KnowledgeBoard + KnowledgeItem models + migration (DRAFT/PUBLISHED/ARCHIVED status, slug per tenant) - KnowledgeModule: admin CRUD for boards + items (auto-slug, status workflow) - Member endpoint GET /my/knowledge?q= — published items grouped by board, optional text search over question/answer - /my/knowledge page: search box + collapsible boards with accordion FAQ items - KnowledgeItem accordion + KnowledgeSearch (debounced URL-driven) client components - Knowledge nav item; register KnowledgeModule Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
CREATE TYPE "KnowledgeItemStatus" AS ENUM ('DRAFT', 'PUBLISHED', 'ARCHIVED');
|
||||
|
||||
CREATE TABLE "KnowledgeBoard" (
|
||||
"id" TEXT NOT NULL,
|
||||
"tenantId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"slug" TEXT NOT NULL,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "KnowledgeBoard_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "KnowledgeItem" (
|
||||
"id" TEXT NOT NULL,
|
||||
"boardId" TEXT NOT NULL,
|
||||
"tenantId" TEXT NOT NULL,
|
||||
"question" TEXT NOT NULL,
|
||||
"answer" TEXT NOT NULL,
|
||||
"tags" TEXT[],
|
||||
"status" "KnowledgeItemStatus" NOT NULL DEFAULT 'DRAFT',
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdBy" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "KnowledgeItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "KnowledgeBoard_tenantId_slug_key" ON "KnowledgeBoard"("tenantId", "slug");
|
||||
CREATE INDEX "KnowledgeBoard_tenantId_idx" ON "KnowledgeBoard"("tenantId");
|
||||
CREATE INDEX "KnowledgeItem_tenantId_status_idx" ON "KnowledgeItem"("tenantId", "status");
|
||||
CREATE INDEX "KnowledgeItem_boardId_status_idx" ON "KnowledgeItem"("boardId", "status");
|
||||
|
||||
ALTER TABLE "KnowledgeBoard" ADD CONSTRAINT "KnowledgeBoard_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE "KnowledgeItem" ADD CONSTRAINT "KnowledgeItem_boardId_fkey" FOREIGN KEY ("boardId") REFERENCES "KnowledgeBoard"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "KnowledgeItem" ADD CONSTRAINT "KnowledgeItem_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -96,6 +96,8 @@ model Tenant {
|
||||
gamificationEvents GamificationEvent[]
|
||||
circles Circle[]
|
||||
askAIQueries AskAIQuery[]
|
||||
knowledgeBoards KnowledgeBoard[]
|
||||
knowledgeItems KnowledgeItem[]
|
||||
}
|
||||
|
||||
enum AdminRole {
|
||||
@@ -751,3 +753,49 @@ model AskAIQuery {
|
||||
@@index([tenantId, createdAt])
|
||||
@@index([userId, createdAt])
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Knowledge Base (admin-curated FAQ boards)
|
||||
// ============================================================================
|
||||
|
||||
enum KnowledgeItemStatus {
|
||||
DRAFT
|
||||
PUBLISHED
|
||||
ARCHIVED
|
||||
}
|
||||
|
||||
model KnowledgeBoard {
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
name String
|
||||
description String?
|
||||
slug String
|
||||
sortOrder Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
items KnowledgeItem[]
|
||||
|
||||
@@unique([tenantId, slug])
|
||||
@@index([tenantId])
|
||||
}
|
||||
|
||||
model KnowledgeItem {
|
||||
id String @id @default(cuid())
|
||||
boardId String
|
||||
board KnowledgeBoard @relation(fields: [boardId], references: [id], onDelete: Cascade)
|
||||
tenantId String
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
question String
|
||||
answer String
|
||||
tags String[]
|
||||
status KnowledgeItemStatus @default(DRAFT)
|
||||
sortOrder Int @default(0)
|
||||
createdBy String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([tenantId, status])
|
||||
@@index([boardId, status])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user