feat(#37-41): Add domains, ideas, relationships, agents, widgets schema
Schema additions for issues #37-41: New models: - Domain (#37): Life domains (work, marriage, homelab, etc.) - Idea (#38): Brain dumps with pgvector embeddings - Relationship (#39): Generic entity linking (blocks, depends_on) - Agent (#40): ClawdBot agent tracking with metrics - AgentSession (#40): Conversation session tracking - WidgetDefinition (#41): HUD widget registry - UserLayout (#41): Per-user dashboard configuration Updated models: - Task, Event, Project: Added domainId foreign key - User, Workspace: Added new relations New enums: - IdeaStatus: CAPTURED, PROCESSING, ACTIONABLE, ARCHIVED, DISCARDED - RelationshipType: BLOCKS, BLOCKED_BY, DEPENDS_ON, etc. - AgentStatus: IDLE, WORKING, WAITING, ERROR, TERMINATED - EntityType: Added IDEA, DOMAIN Migration: 20260129182803_add_domains_ideas_agents_widgets
This commit is contained in:
@@ -52,6 +52,10 @@ enum ActivityAction {
|
||||
COMPLETED
|
||||
ASSIGNED
|
||||
COMMENTED
|
||||
LOGIN
|
||||
LOGOUT
|
||||
PASSWORD_RESET
|
||||
EMAIL_VERIFIED
|
||||
}
|
||||
|
||||
enum EntityType {
|
||||
@@ -60,6 +64,36 @@ enum EntityType {
|
||||
PROJECT
|
||||
WORKSPACE
|
||||
USER
|
||||
IDEA
|
||||
DOMAIN
|
||||
}
|
||||
|
||||
enum IdeaStatus {
|
||||
CAPTURED
|
||||
PROCESSING
|
||||
ACTIONABLE
|
||||
ARCHIVED
|
||||
DISCARDED
|
||||
}
|
||||
|
||||
enum RelationshipType {
|
||||
BLOCKS
|
||||
BLOCKED_BY
|
||||
DEPENDS_ON
|
||||
PARENT_OF
|
||||
CHILD_OF
|
||||
RELATED_TO
|
||||
DUPLICATE_OF
|
||||
SUPERSEDES
|
||||
PART_OF
|
||||
}
|
||||
|
||||
enum AgentStatus {
|
||||
IDLE
|
||||
WORKING
|
||||
WAITING
|
||||
ERROR
|
||||
TERMINATED
|
||||
}
|
||||
|
||||
// ============================================
|
||||
@@ -78,15 +112,19 @@ model User {
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
|
||||
|
||||
// Relations
|
||||
ownedWorkspaces Workspace[] @relation("WorkspaceOwner")
|
||||
ownedWorkspaces Workspace[] @relation("WorkspaceOwner")
|
||||
workspaceMemberships WorkspaceMember[]
|
||||
assignedTasks Task[] @relation("TaskAssignee")
|
||||
createdTasks Task[] @relation("TaskCreator")
|
||||
createdEvents Event[] @relation("EventCreator")
|
||||
createdProjects Project[] @relation("ProjectCreator")
|
||||
assignedTasks Task[] @relation("TaskAssignee")
|
||||
createdTasks Task[] @relation("TaskCreator")
|
||||
createdEvents Event[] @relation("EventCreator")
|
||||
createdProjects Project[] @relation("ProjectCreator")
|
||||
activityLogs ActivityLog[]
|
||||
sessions Session[]
|
||||
accounts Account[]
|
||||
ideas Idea[] @relation("IdeaCreator")
|
||||
relationships Relationship[] @relation("RelationshipCreator")
|
||||
agentSessions AgentSession[]
|
||||
userLayouts UserLayout[]
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
@@ -107,6 +145,12 @@ model Workspace {
|
||||
projects Project[]
|
||||
activityLogs ActivityLog[]
|
||||
memoryEmbeddings MemoryEmbedding[]
|
||||
domains Domain[]
|
||||
ideas Idea[]
|
||||
relationships Relationship[]
|
||||
agents Agent[]
|
||||
agentSessions AgentSession[]
|
||||
userLayouts UserLayout[]
|
||||
|
||||
@@index([ownerId])
|
||||
@@map("workspaces")
|
||||
@@ -139,6 +183,7 @@ model Task {
|
||||
creatorId String @map("creator_id") @db.Uuid
|
||||
projectId String? @map("project_id") @db.Uuid
|
||||
parentId String? @map("parent_id") @db.Uuid
|
||||
domainId String? @map("domain_id") @db.Uuid
|
||||
sortOrder Int @default(0) @map("sort_order")
|
||||
metadata Json @default("{}")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
@@ -152,6 +197,7 @@ model Task {
|
||||
project Project? @relation(fields: [projectId], references: [id], onDelete: SetNull)
|
||||
parent Task? @relation("TaskSubtasks", fields: [parentId], references: [id], onDelete: Cascade)
|
||||
subtasks Task[] @relation("TaskSubtasks")
|
||||
domain Domain? @relation(fields: [domainId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([workspaceId])
|
||||
@@index([workspaceId, status])
|
||||
@@ -159,6 +205,7 @@ model Task {
|
||||
@@index([assigneeId])
|
||||
@@index([projectId])
|
||||
@@index([parentId])
|
||||
@@index([domainId])
|
||||
@@map("tasks")
|
||||
}
|
||||
|
||||
@@ -174,6 +221,7 @@ model Event {
|
||||
recurrence Json?
|
||||
creatorId String @map("creator_id") @db.Uuid
|
||||
projectId String? @map("project_id") @db.Uuid
|
||||
domainId String? @map("domain_id") @db.Uuid
|
||||
metadata Json @default("{}")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
|
||||
@@ -182,11 +230,13 @@ model Event {
|
||||
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
||||
creator User @relation("EventCreator", fields: [creatorId], references: [id], onDelete: Cascade)
|
||||
project Project? @relation(fields: [projectId], references: [id], onDelete: SetNull)
|
||||
domain Domain? @relation(fields: [domainId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([workspaceId])
|
||||
@@index([workspaceId, startTime])
|
||||
@@index([creatorId])
|
||||
@@index([projectId])
|
||||
@@index([domainId])
|
||||
@@map("events")
|
||||
}
|
||||
|
||||
@@ -199,6 +249,7 @@ model Project {
|
||||
startDate DateTime? @map("start_date") @db.Date
|
||||
endDate DateTime? @map("end_date") @db.Date
|
||||
creatorId String @map("creator_id") @db.Uuid
|
||||
domainId String? @map("domain_id") @db.Uuid
|
||||
color String?
|
||||
metadata Json @default("{}")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
@@ -209,10 +260,13 @@ model Project {
|
||||
creator User @relation("ProjectCreator", fields: [creatorId], references: [id], onDelete: Cascade)
|
||||
tasks Task[]
|
||||
events Event[]
|
||||
domain Domain? @relation(fields: [domainId], references: [id], onDelete: SetNull)
|
||||
ideas Idea[]
|
||||
|
||||
@@index([workspaceId])
|
||||
@@index([workspaceId, status])
|
||||
@@index([creatorId])
|
||||
@@index([domainId])
|
||||
@@map("projects")
|
||||
}
|
||||
|
||||
@@ -224,6 +278,8 @@ model ActivityLog {
|
||||
entityType EntityType @map("entity_type")
|
||||
entityId String @map("entity_id") @db.Uuid
|
||||
details Json @default("{}")
|
||||
ipAddress String? @map("ip_address")
|
||||
userAgent String? @map("user_agent")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
|
||||
// Relations
|
||||
@@ -234,6 +290,7 @@ model ActivityLog {
|
||||
@@index([workspaceId, createdAt])
|
||||
@@index([entityType, entityId])
|
||||
@@index([userId])
|
||||
@@index([action])
|
||||
@@map("activity_logs")
|
||||
}
|
||||
|
||||
@@ -256,6 +313,239 @@ model MemoryEmbedding {
|
||||
@@map("memory_embeddings")
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// NEW MODELS
|
||||
// ============================================
|
||||
|
||||
model Domain {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
workspaceId String @map("workspace_id") @db.Uuid
|
||||
|
||||
name String
|
||||
slug String
|
||||
description String? @db.Text
|
||||
color String?
|
||||
icon String?
|
||||
sortOrder Int @default(0) @map("sort_order")
|
||||
|
||||
metadata Json @default("{}")
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
|
||||
|
||||
// Relations
|
||||
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
||||
tasks Task[]
|
||||
events Event[]
|
||||
projects Project[]
|
||||
ideas Idea[]
|
||||
|
||||
@@unique([workspaceId, slug])
|
||||
@@index([workspaceId])
|
||||
@@map("domains")
|
||||
}
|
||||
|
||||
model Idea {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
workspaceId String @map("workspace_id") @db.Uuid
|
||||
domainId String? @map("domain_id") @db.Uuid
|
||||
projectId String? @map("project_id") @db.Uuid
|
||||
|
||||
// Core fields
|
||||
title String?
|
||||
content String @db.Text
|
||||
|
||||
// Status
|
||||
status IdeaStatus @default(CAPTURED)
|
||||
priority TaskPriority @default(MEDIUM)
|
||||
|
||||
// Categorization
|
||||
category String?
|
||||
tags String[]
|
||||
|
||||
metadata Json @default("{}")
|
||||
|
||||
// Embedding for semantic search (pgvector)
|
||||
embedding Unsupported("vector(1536)")?
|
||||
|
||||
// Audit
|
||||
creatorId String @map("creator_id") @db.Uuid
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
|
||||
|
||||
// Relations
|
||||
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
||||
domain Domain? @relation(fields: [domainId], references: [id], onDelete: SetNull)
|
||||
project Project? @relation(fields: [projectId], references: [id], onDelete: SetNull)
|
||||
creator User @relation("IdeaCreator", fields: [creatorId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([workspaceId])
|
||||
@@index([workspaceId, status])
|
||||
@@index([domainId])
|
||||
@@index([projectId])
|
||||
@@index([creatorId])
|
||||
@@map("ideas")
|
||||
}
|
||||
|
||||
model Relationship {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
workspaceId String @map("workspace_id") @db.Uuid
|
||||
|
||||
// Source entity
|
||||
sourceType EntityType @map("source_type")
|
||||
sourceId String @map("source_id") @db.Uuid
|
||||
|
||||
// Target entity
|
||||
targetType EntityType @map("target_type")
|
||||
targetId String @map("target_id") @db.Uuid
|
||||
|
||||
// Relationship type
|
||||
relationship RelationshipType
|
||||
|
||||
metadata Json @default("{}")
|
||||
notes String? @db.Text
|
||||
|
||||
// Audit
|
||||
creatorId String @map("creator_id") @db.Uuid
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
|
||||
// Relations
|
||||
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
||||
creator User @relation("RelationshipCreator", fields: [creatorId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Prevent duplicate relationships
|
||||
@@unique([workspaceId, sourceType, sourceId, targetType, targetId, relationship])
|
||||
@@index([sourceType, sourceId])
|
||||
@@index([targetType, targetId])
|
||||
@@index([relationship])
|
||||
@@map("relationships")
|
||||
}
|
||||
|
||||
model Agent {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
workspaceId String @map("workspace_id") @db.Uuid
|
||||
|
||||
// Identity
|
||||
agentId String @map("agent_id")
|
||||
name String?
|
||||
model String?
|
||||
role String?
|
||||
|
||||
// Status
|
||||
status AgentStatus @default(IDLE)
|
||||
currentTask String? @map("current_task") @db.Text
|
||||
|
||||
// Performance metrics
|
||||
metrics Json @default("{\"totalTasks\": 0, \"successfulTasks\": 0, \"failedTasks\": 0, \"avgResponseTimeMs\": 0}")
|
||||
|
||||
// Health
|
||||
lastHeartbeat DateTime? @map("last_heartbeat") @db.Timestamptz
|
||||
errorCount Int @default(0) @map("error_count")
|
||||
lastError String? @map("last_error") @db.Text
|
||||
|
||||
// Firing history
|
||||
firedCount Int @default(0) @map("fired_count")
|
||||
fireHistory Json @default("[]") @map("fire_history")
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
|
||||
terminatedAt DateTime? @map("terminated_at") @db.Timestamptz
|
||||
|
||||
// Relations
|
||||
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
||||
sessions AgentSession[]
|
||||
|
||||
@@unique([workspaceId, agentId])
|
||||
@@index([workspaceId])
|
||||
@@index([status])
|
||||
@@map("agents")
|
||||
}
|
||||
|
||||
model AgentSession {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
workspaceId String @map("workspace_id") @db.Uuid
|
||||
userId String @map("user_id") @db.Uuid
|
||||
agentId String? @map("agent_id") @db.Uuid
|
||||
|
||||
// Identity
|
||||
sessionKey String @map("session_key")
|
||||
label String?
|
||||
channel String?
|
||||
|
||||
// Context
|
||||
contextSummary String? @map("context_summary") @db.Text
|
||||
messageCount Int @default(0) @map("message_count")
|
||||
|
||||
// Status
|
||||
isActive Boolean @default(true) @map("is_active")
|
||||
|
||||
startedAt DateTime @default(now()) @map("started_at") @db.Timestamptz
|
||||
lastMessageAt DateTime? @map("last_message_at") @db.Timestamptz
|
||||
endedAt DateTime? @map("ended_at") @db.Timestamptz
|
||||
|
||||
metadata Json @default("{}")
|
||||
|
||||
// Relations
|
||||
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
agent Agent? @relation(fields: [agentId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@unique([workspaceId, sessionKey])
|
||||
@@index([workspaceId])
|
||||
@@index([userId])
|
||||
@@index([agentId])
|
||||
@@index([isActive])
|
||||
@@map("agent_sessions")
|
||||
}
|
||||
|
||||
model WidgetDefinition {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
|
||||
name String @unique
|
||||
displayName String @map("display_name")
|
||||
description String? @db.Text
|
||||
component String
|
||||
|
||||
// Default size (grid units)
|
||||
defaultWidth Int @default(1) @map("default_width")
|
||||
defaultHeight Int @default(1) @map("default_height")
|
||||
minWidth Int @default(1) @map("min_width")
|
||||
minHeight Int @default(1) @map("min_height")
|
||||
maxWidth Int? @map("max_width")
|
||||
maxHeight Int? @map("max_height")
|
||||
|
||||
// Configuration schema (JSON Schema for widget config)
|
||||
configSchema Json @default("{}") @map("config_schema")
|
||||
|
||||
isActive Boolean @default(true) @map("is_active")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
|
||||
@@map("widget_definitions")
|
||||
}
|
||||
|
||||
model UserLayout {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
workspaceId String @map("workspace_id") @db.Uuid
|
||||
userId String @map("user_id") @db.Uuid
|
||||
|
||||
name String
|
||||
isDefault Boolean @default(false) @map("is_default")
|
||||
|
||||
// Layout configuration (array of widget placements)
|
||||
layout Json @default("[]")
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
|
||||
|
||||
// Relations
|
||||
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([workspaceId, userId, name])
|
||||
@@index([userId])
|
||||
@@map("user_layouts")
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// AUTHENTICATION MODELS (BetterAuth)
|
||||
// ============================================
|
||||
|
||||
Reference in New Issue
Block a user