feat(knowledge): add database schema for Knowledge Module
Implements KNOW-001 - KnowledgeEntry, Version, Link, Tag, Embedding models - Full indexes and constraints - Seed data for testing
This commit is contained in:
@@ -4,6 +4,8 @@ import {
|
||||
TaskPriority,
|
||||
ProjectStatus,
|
||||
WorkspaceMemberRole,
|
||||
EntryStatus,
|
||||
Visibility,
|
||||
} from "@prisma/client";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
@@ -145,6 +147,309 @@ async function main() {
|
||||
});
|
||||
|
||||
console.log("Created sample event");
|
||||
|
||||
// ============================================
|
||||
// KNOWLEDGE MODULE SEED DATA
|
||||
// ============================================
|
||||
|
||||
// Delete existing knowledge data
|
||||
await tx.knowledgeEmbedding.deleteMany({ where: { entry: { workspaceId: workspace.id } } });
|
||||
await tx.knowledgeEntryTag.deleteMany({ where: { entry: { workspaceId: workspace.id } } });
|
||||
await tx.knowledgeLink.deleteMany({ where: { source: { workspaceId: workspace.id } } });
|
||||
await tx.knowledgeEntryVersion.deleteMany({ where: { entry: { workspaceId: workspace.id } } });
|
||||
await tx.knowledgeEntry.deleteMany({ where: { workspaceId: workspace.id } });
|
||||
await tx.knowledgeTag.deleteMany({ where: { workspaceId: workspace.id } });
|
||||
|
||||
// Create knowledge tags
|
||||
const tags = await Promise.all([
|
||||
tx.knowledgeTag.create({
|
||||
data: {
|
||||
workspaceId: workspace.id,
|
||||
name: "Architecture",
|
||||
slug: "architecture",
|
||||
color: "#3B82F6",
|
||||
description: "System architecture and design decisions",
|
||||
},
|
||||
}),
|
||||
tx.knowledgeTag.create({
|
||||
data: {
|
||||
workspaceId: workspace.id,
|
||||
name: "Development",
|
||||
slug: "development",
|
||||
color: "#10B981",
|
||||
description: "Development practices and guidelines",
|
||||
},
|
||||
}),
|
||||
tx.knowledgeTag.create({
|
||||
data: {
|
||||
workspaceId: workspace.id,
|
||||
name: "Getting Started",
|
||||
slug: "getting-started",
|
||||
color: "#F59E0B",
|
||||
description: "Onboarding and setup guides",
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
console.log(`Created ${tags.length} knowledge tags`);
|
||||
|
||||
// Create knowledge entries
|
||||
const entries = [
|
||||
{
|
||||
slug: "welcome",
|
||||
title: "Welcome to Mosaic Stack Knowledge Base",
|
||||
content: `# Welcome to Mosaic Stack
|
||||
|
||||
This is the knowledge base for the Mosaic Stack project. Here you'll find:
|
||||
|
||||
- **[[architecture-overview]]** - High-level system architecture
|
||||
- **[[development-setup]]** - Getting started with development
|
||||
- **[[database-schema]]** - Database design and conventions
|
||||
|
||||
## About This Knowledge Base
|
||||
|
||||
The Knowledge Module provides:
|
||||
- Wiki-style linking between entries
|
||||
- Full-text and semantic search
|
||||
- Version history and change tracking
|
||||
- Tag-based organization
|
||||
|
||||
Start exploring by following the links above!`,
|
||||
summary: "Introduction to the Mosaic Stack knowledge base and navigation guide",
|
||||
status: EntryStatus.PUBLISHED,
|
||||
visibility: Visibility.WORKSPACE,
|
||||
tags: ["getting-started"],
|
||||
},
|
||||
{
|
||||
slug: "architecture-overview",
|
||||
title: "Architecture Overview",
|
||||
content: `# Architecture Overview
|
||||
|
||||
The Mosaic Stack is built on a modern, scalable architecture:
|
||||
|
||||
## Stack Components
|
||||
|
||||
- **Frontend**: Next.js 15+ with React 19
|
||||
- **Backend**: NestJS with Prisma ORM
|
||||
- **Database**: PostgreSQL 17 with pgvector
|
||||
- **Cache**: Valkey (Redis fork)
|
||||
|
||||
## Key Modules
|
||||
|
||||
1. **Task Management** - See [[development-setup]] for local setup
|
||||
2. **Event Calendar** - Integrated scheduling
|
||||
3. **Knowledge Base** - This module! See [[database-schema]]
|
||||
4. **Agent Orchestration** - AI agent coordination
|
||||
|
||||
The database schema is documented in [[database-schema]].`,
|
||||
summary: "High-level overview of Mosaic Stack architecture and components",
|
||||
status: EntryStatus.PUBLISHED,
|
||||
visibility: Visibility.WORKSPACE,
|
||||
tags: ["architecture"],
|
||||
},
|
||||
{
|
||||
slug: "development-setup",
|
||||
title: "Development Setup Guide",
|
||||
content: `# Development Setup Guide
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js 22+
|
||||
- PostgreSQL 17
|
||||
- pnpm 9+
|
||||
|
||||
## Quick Start
|
||||
|
||||
\`\`\`bash
|
||||
# Clone the repository
|
||||
git clone https://git.mosaicstack.dev/mosaic/stack.git
|
||||
|
||||
# Install dependencies
|
||||
pnpm install
|
||||
|
||||
# Set up database
|
||||
cd apps/api
|
||||
pnpm prisma migrate dev
|
||||
pnpm prisma:seed
|
||||
|
||||
# Start development servers
|
||||
pnpm dev
|
||||
\`\`\`
|
||||
|
||||
## Architecture
|
||||
|
||||
Before diving in, review the [[architecture-overview]] to understand the system design.
|
||||
|
||||
## Database
|
||||
|
||||
The database schema is documented in [[database-schema]]. All models use Prisma ORM.
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Read the [[architecture-overview]]
|
||||
2. Explore the codebase
|
||||
3. Check out the [[database-schema]] documentation`,
|
||||
summary: "Step-by-step guide to setting up the Mosaic Stack development environment",
|
||||
status: EntryStatus.PUBLISHED,
|
||||
visibility: Visibility.WORKSPACE,
|
||||
tags: ["development", "getting-started"],
|
||||
},
|
||||
{
|
||||
slug: "database-schema",
|
||||
title: "Database Schema Documentation",
|
||||
content: `# Database Schema Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
Mosaic Stack uses PostgreSQL 17 with Prisma ORM. See [[architecture-overview]] for context.
|
||||
|
||||
## Key Conventions
|
||||
|
||||
- All IDs are UUIDs
|
||||
- Timestamps use \`@db.Timestamptz\` (timezone-aware)
|
||||
- Soft deletes via status fields (e.g., ARCHIVED)
|
||||
- Relations enforce cascade deletes for data integrity
|
||||
|
||||
## Core Models
|
||||
|
||||
### Task Management
|
||||
- \`Task\` - Individual work items
|
||||
- \`Project\` - Task containers
|
||||
- \`Domain\` - High-level categorization
|
||||
|
||||
### Knowledge Module
|
||||
- \`KnowledgeEntry\` - Wiki pages
|
||||
- \`KnowledgeLink\` - Page connections
|
||||
- \`KnowledgeTag\` - Categorization
|
||||
- \`KnowledgeEmbedding\` - Semantic search (pgvector)
|
||||
|
||||
### Agent System
|
||||
- \`Agent\` - AI agent instances
|
||||
- \`AgentSession\` - Conversation sessions
|
||||
|
||||
## Migrations
|
||||
|
||||
Migrations are managed via Prisma:
|
||||
|
||||
\`\`\`bash
|
||||
# Create migration
|
||||
pnpm prisma migrate dev --name my_migration
|
||||
|
||||
# Apply in production
|
||||
pnpm prisma migrate deploy
|
||||
\`\`\`
|
||||
|
||||
For setup instructions, see [[development-setup]].`,
|
||||
summary: "Comprehensive documentation of the Mosaic Stack database schema and Prisma conventions",
|
||||
status: EntryStatus.PUBLISHED,
|
||||
visibility: Visibility.WORKSPACE,
|
||||
tags: ["architecture", "development"],
|
||||
},
|
||||
{
|
||||
slug: "future-ideas",
|
||||
title: "Future Ideas and Roadmap",
|
||||
content: `# Future Ideas and Roadmap
|
||||
|
||||
## Planned Features
|
||||
|
||||
- Real-time collaboration (CRDT)
|
||||
- Advanced graph visualizations
|
||||
- AI-powered summarization
|
||||
- Mobile app
|
||||
|
||||
## Research Areas
|
||||
|
||||
- Vector search optimization
|
||||
- Knowledge graph algorithms
|
||||
- Agent memory systems
|
||||
|
||||
This is a draft document. See [[architecture-overview]] for current state.`,
|
||||
summary: "Brainstorming document for future features and research directions",
|
||||
status: EntryStatus.DRAFT,
|
||||
visibility: Visibility.PRIVATE,
|
||||
tags: [],
|
||||
},
|
||||
];
|
||||
|
||||
// Create entries and track them for linking
|
||||
const createdEntries = new Map<string, any>();
|
||||
|
||||
for (const entryData of entries) {
|
||||
const entry = await tx.knowledgeEntry.create({
|
||||
data: {
|
||||
workspaceId: workspace.id,
|
||||
slug: entryData.slug,
|
||||
title: entryData.title,
|
||||
content: entryData.content,
|
||||
summary: entryData.summary,
|
||||
status: entryData.status,
|
||||
visibility: entryData.visibility,
|
||||
createdBy: user.id,
|
||||
updatedBy: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
createdEntries.set(entryData.slug, entry);
|
||||
|
||||
// Create initial version
|
||||
await tx.knowledgeEntryVersion.create({
|
||||
data: {
|
||||
entryId: entry.id,
|
||||
version: 1,
|
||||
title: entry.title,
|
||||
content: entry.content,
|
||||
summary: entry.summary,
|
||||
createdBy: user.id,
|
||||
changeNote: "Initial version",
|
||||
},
|
||||
});
|
||||
|
||||
// Add tags
|
||||
for (const tagSlug of entryData.tags) {
|
||||
const tag = tags.find(t => t.slug === tagSlug);
|
||||
if (tag) {
|
||||
await tx.knowledgeEntryTag.create({
|
||||
data: {
|
||||
entryId: entry.id,
|
||||
tagId: tag.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Created ${entries.length} knowledge entries`);
|
||||
|
||||
// Create wiki-links between entries
|
||||
const links = [
|
||||
{ source: "welcome", target: "architecture-overview", text: "architecture-overview" },
|
||||
{ source: "welcome", target: "development-setup", text: "development-setup" },
|
||||
{ source: "welcome", target: "database-schema", text: "database-schema" },
|
||||
{ source: "architecture-overview", target: "development-setup", text: "development-setup" },
|
||||
{ source: "architecture-overview", target: "database-schema", text: "database-schema" },
|
||||
{ source: "development-setup", target: "architecture-overview", text: "architecture-overview" },
|
||||
{ source: "development-setup", target: "database-schema", text: "database-schema" },
|
||||
{ source: "database-schema", target: "architecture-overview", text: "architecture-overview" },
|
||||
{ source: "database-schema", target: "development-setup", text: "development-setup" },
|
||||
{ source: "future-ideas", target: "architecture-overview", text: "architecture-overview" },
|
||||
];
|
||||
|
||||
for (const link of links) {
|
||||
const sourceEntry = createdEntries.get(link.source);
|
||||
const targetEntry = createdEntries.get(link.target);
|
||||
|
||||
if (sourceEntry && targetEntry) {
|
||||
await tx.knowledgeLink.create({
|
||||
data: {
|
||||
sourceId: sourceEntry.id,
|
||||
targetId: targetEntry.id,
|
||||
linkText: link.text,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Created ${links.length} knowledge links`);
|
||||
});
|
||||
console.log("Seeding completed successfully!");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user