datasource db { provider = "postgresql" url = env("DATABASE_URL") directUrl = env("DIRECT_URL") } generator client { provider = "prisma-client-js" binaryTargets = ["native", "debian-openssl-1.1.x"] previewFeatures = ["tracing"] } model Activity { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deleted DateTime? text String // Used to link the task or activity to external apps sourceURL String? integrationAccount IntegrationAccount? @relation(fields: [integrationAccountId], references: [id], onDelete: Cascade) integrationAccountId String? rejectionReason String? workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) workspaceId String WebhookDeliveryLog WebhookDeliveryLog[] ConversationHistory ConversationHistory[] IngestionQueue IngestionQueue[] } model AuthorizationCode { id String @id @default(cuid()) code String @unique personalAccessToken PersonalAccessToken? @relation(fields: [personalAccessTokenId], references: [id], onDelete: Cascade, onUpdate: Cascade) personalAccessTokenId String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Conversation { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deleted DateTime? unread Boolean @default(false) title String? user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String workspace Workspace? @relation(fields: [workspaceId], references: [id], onDelete: Cascade) workspaceId String? status String @default("pending") // Can be "pending", "running", "completed", "failed", "need_attention" ConversationHistory ConversationHistory[] RecallLog RecallLog[] } model ConversationExecutionStep { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deleted DateTime? thought String message String actionId String? actionOutput String? actionInput String? actionStatus String? metadata Json? @default("{}") conversationHistory ConversationHistory @relation(fields: [conversationHistoryId], references: [id], onDelete: Cascade) conversationHistoryId String } model ConversationHistory { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deleted DateTime? message String userType UserType activity Activity? @relation(fields: [activityId], references: [id], onDelete: Cascade) activityId String? context Json? thoughts Json? user User? @relation(fields: [userId], references: [id], onDelete: Cascade) userId String? conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade) conversationId String ConversationExecutionStep ConversationExecutionStep[] } model IngestionQueue { id String @id @default(cuid()) // Queue metadata data Json // The actual data to be processed output Json? // The processed output data status IngestionStatus priority Int @default(0) type String? workspaceId String workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) activity Activity? @relation(fields: [activityId], references: [id], onDelete: Cascade) activityId String? // Error handling error String? retryCount Int @default(0) // Timestamps createdAt DateTime @default(now()) updatedAt DateTime @updatedAt processedAt DateTime? } model IngestionRule { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deleted DateTime? name String? // Optional human-readable rule name text String // Free-flowing text rule description (mandatory) source String // Source/integration this rule applies to (mandatory) isActive Boolean @default(true) // Enable/disable rule (mandatory) workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) workspaceId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String } model IntegrationAccount { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deleted DateTime? integrationConfiguration Json accountId String? settings Json? isActive Boolean @default(true) integratedBy User @relation(references: [id], fields: [integratedById], onDelete: Cascade) integratedById String integrationDefinition IntegrationDefinitionV2 @relation(references: [id], fields: [integrationDefinitionId], onDelete: Cascade) integrationDefinitionId String workspace Workspace @relation(references: [id], fields: [workspaceId], onDelete: Cascade) workspaceId String Activity Activity[] oauthIntegrationGrants OAuthIntegrationGrant[] @@unique([accountId, integrationDefinitionId, workspaceId]) } model IntegrationDefinitionV2 { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deleted DateTime? name String @unique slug String description String icon String config Json? spec Json @default("{}") version String? url String? workspace Workspace? @relation(references: [id], fields: [workspaceId], onDelete: Cascade) workspaceId String? IntegrationAccount IntegrationAccount[] } model InvitationCode { id String @id @default(cuid()) code String @unique users User[] createdAt DateTime @default(now()) } model MCPSession { id String @id @default(cuid()) source String integrations String[] workspace Workspace? @relation(references: [id], fields: [workspaceId], onDelete: Cascade) workspaceId String? createdAt DateTime @default(now()) deleted DateTime? } model OAuthAuthorizationCode { id String @id @default(cuid()) code String @unique // OAuth2 specific fields clientId String userId String redirectUri String scope String? state String? codeChallenge String? codeChallengeMethod String? expiresAt DateTime used Boolean @default(false) // Relations client OAuthClient @relation(fields: [clientId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) workspaceId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model OAuthAccessToken { id String @id @default(cuid()) token String @unique clientId String userId String scope String? expiresAt DateTime revoked Boolean @default(false) // Relations client OAuthClient @relation(fields: [clientId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) workspaceId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model OAuthClient { id String @id @default(cuid()) clientId String @unique clientSecret String name String description String? // Redirect URIs (comma-separated for simplicity) redirectUris String // Allowed scopes (comma-separated) allowedScopes String @default("read") // Grant types allowed grantTypes String @default("authorization_code") // PKCE support requirePkce Boolean @default(false) clientType String @default("regular") // Client metadata logoUrl String? homepageUrl String? // Integration hub webhook support webhookUrl String? webhookSecret String? // GitHub-style features isActive Boolean @default(true) // Workspace relationship (like GitHub orgs) workspace Workspace? @relation(fields: [workspaceId], references: [id], onDelete: Cascade) workspaceId String? // Created by user (for audit trail) createdBy User? @relation(fields: [createdById], references: [id], onDelete: Cascade) createdById String? // Relations oauthAuthorizationCodes OAuthAuthorizationCode[] accessTokens OAuthAccessToken[] refreshTokens OAuthRefreshToken[] integrationGrants OAuthIntegrationGrant[] oAuthClientInstallation OAuthClientInstallation[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model OAuthClientInstallation { id String @id @default(cuid()) // The OAuth client being installed oauthClient OAuthClient @relation(fields: [oauthClientId], references: [id], onDelete: Cascade) oauthClientId String // The workspace where it's installed workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) workspaceId String // Installation metadata installedBy User @relation(fields: [installedById], references: [id], onDelete: Cascade) installedById String installedAt DateTime @default(now()) uninstalledAt DateTime? // Installation status isActive Boolean @default(true) // Installation-specific settings settings Json? grantedScopes String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@unique([oauthClientId, workspaceId]) } model OAuthRefreshToken { id String @id @default(cuid()) token String @unique clientId String userId String scope String? expiresAt DateTime revoked Boolean @default(false) // Relations client OAuthClient @relation(fields: [clientId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) workspaceId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model OAuthIntegrationGrant { id String @id @default(cuid()) // OAuth client that has access client OAuthClient @relation(fields: [clientId], references: [id], onDelete: Cascade) clientId String // User who granted access user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String // Integration account that was granted integrationAccount IntegrationAccount @relation(fields: [integrationAccountId], references: [id], onDelete: Cascade) integrationAccountId String // When access was granted/revoked grantedAt DateTime @default(now()) revokedAt DateTime? isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@unique([clientId, userId, integrationAccountId]) } model PersonalAccessToken { id String @id @default(cuid()) /// If generated by the CLI this will be "cli", otherwise user-provided name String /// This is the token encrypted using the ENCRYPTION_KEY encryptedToken Json /// This is shown in the UI, with ******** obfuscatedToken String /// This is used to find the token in the database hashedToken String @unique user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String revokedAt DateTime? lastAccessedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt authorizationCodes AuthorizationCode[] } model RecallLog { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deleted DateTime? // Access details accessType String // "search", "recall", "direct_access" query String? // Search query (null for direct access) // Target information targetType String? // "episode", "statement", "entity", "mixed_results" targetId String? // UUID of specific target (null for search with multiple results) // Search/access parameters searchMethod String? // "semantic", "keyword", "hybrid", "contextual", "graph_traversal" minSimilarity Float? // Minimum similarity threshold used maxResults Int? // Maximum results requested // Results and interaction resultCount Int @default(0) // Number of results returned similarityScore Float? // Similarity score (for single result access) // Context and source context String? // Additional context source String? // Source of the access (e.g., "chat", "api", "integration") sessionId String? // Session identifier // Performance metrics responseTimeMs Int? // Response time in milliseconds // Relations user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String workspace Workspace? @relation(fields: [workspaceId], references: [id], onDelete: Cascade) workspaceId String? conversation Conversation? @relation(fields: [conversationId], references: [id], onDelete: Cascade) conversationId String? // Metadata for additional tracking data metadata Json? @default("{}") } model Space { id String @id @default(cuid()) name String description String? autoMode Boolean @default(false) summary String? themes String[] contextCount Int? // Count of context items in this space (episodes, statements, etc.) status String? icon String? lastPatternTrigger DateTime? summaryGeneratedAt DateTime? contextCountAtLastTrigger Int? // Context count when pattern was last triggered // Relations workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) workspaceId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt SpacePattern SpacePattern[] } model SpacePattern { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deleted DateTime? name String source String type String summary String editedSummary String? evidence String[] confidence Float userConfirmed String @default("pending") // Relations space Space @relation(fields: [spaceId], references: [id], onDelete: Cascade) spaceId String @@index([spaceId, source]) } model User { id String @id @default(cuid()) email String @unique authenticationMethod AuthenticationMethod authenticationProfile Json? authenticationExtraParams Json? authIdentifier String? @unique displayName String? name String? avatarUrl String? memoryFilter String? // Adding memory filter instructions admin Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt marketingEmails Boolean @default(true) confirmedBasicDetails Boolean @default(false) onboardingComplete Boolean @default(false) referralSource String? metadata Json @default("{}") personalAccessTokens PersonalAccessToken[] InvitationCode InvitationCode? @relation(fields: [invitationCodeId], references: [id], onDelete: Cascade) invitationCodeId String? Workspace Workspace? IntegrationAccount IntegrationAccount[] WebhookConfiguration WebhookConfiguration[] Conversation Conversation[] ConversationHistory ConversationHistory[] IngestionRule IngestionRule[] // OAuth2 relations oauthAuthorizationCodes OAuthAuthorizationCode[] oauthAccessTokens OAuthAccessToken[] oauthRefreshTokens OAuthRefreshToken[] oauthClientsCreated OAuthClient[] oauthIntegrationGrants OAuthIntegrationGrant[] oAuthClientInstallation OAuthClientInstallation[] UserUsage UserUsage? RecallLog RecallLog[] } model UserUsage { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deleted DateTime? // Current period tracking availableCredits Int @default(0) usedCredits Int @default(0) overageCredits Int @default(0) // Credits used beyond monthly allocation // Last reset tracking lastResetAt DateTime @default(now()) nextResetAt DateTime? // Usage breakdown (optional analytics) episodeCreditsUsed Int @default(0) searchCreditsUsed Int @default(0) chatCreditsUsed Int @default(0) user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String @unique } model WebhookConfiguration { id String @id @default(cuid()) url String secret String? isActive Boolean @default(true) eventTypes String[] // List of event types this webhook is interested in, e.g. ["activity.created"] user User? @relation(fields: [userId], references: [id], onDelete: Cascade) userId String? workspace Workspace? @relation(fields: [workspaceId], references: [id], onDelete: Cascade) workspaceId String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt WebhookDeliveryLog WebhookDeliveryLog[] } model WebhookDeliveryLog { id String @id @default(cuid()) webhookConfiguration WebhookConfiguration @relation(fields: [webhookConfigurationId], references: [id], onDelete: Cascade) webhookConfigurationId String activity Activity? @relation(fields: [activityId], references: [id], onDelete: Cascade) activityId String? status WebhookDeliveryStatus responseStatusCode Int? responseBody String? error String? deliveredAt DateTime @default(now()) createdAt DateTime @default(now()) } model Subscription { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Stripe integration stripeCustomerId String? @unique stripeSubscriptionId String? @unique stripePriceId String? stripeCurrentPeriodEnd DateTime? // Plan details planType PlanType @default(FREE) status SubscriptionStatus @default(ACTIVE) // Monthly credits allocation monthlyCredits Int @default(0) // Billing cycle tracking currentPeriodStart DateTime @default(now()) currentPeriodEnd DateTime // Usage-based pricing (for PRO plan) enableUsageBilling Boolean @default(false) usagePricePerCredit Float? // Price per credit after monthly quota // Overage tracking overageCreditsUsed Int @default(0) overageAmount Float @default(0) // Relations workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) workspaceId String @unique BillingHistory BillingHistory[] } model BillingHistory { id String @id @default(uuid()) createdAt DateTime @default(now()) // Billing period periodStart DateTime periodEnd DateTime // Credits tracking monthlyCreditsAllocated Int creditsUsed Int overageCreditsUsed Int // Charges subscriptionAmount Float usageAmount Float // Overage charges totalAmount Float // Stripe integration stripeInvoiceId String? @unique stripePaymentStatus String? // Relations subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade) subscriptionId String } model Workspace { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deleted DateTime? name String slug String @unique icon String? metadata Json @default("{}") integrations String[] userId String? @unique user User? @relation(fields: [userId], references: [id], onDelete: Cascade) IngestionQueue IngestionQueue[] IntegrationAccount IntegrationAccount[] IntegrationDefinitionV2 IntegrationDefinitionV2[] Activity Activity[] WebhookConfiguration WebhookConfiguration[] Conversation Conversation[] IngestionRule IngestionRule[] OAuthClient OAuthClient[] OAuthClientInstallation OAuthClientInstallation[] OAuthAuthorizationCode OAuthAuthorizationCode[] OAuthAccessToken OAuthAccessToken[] OAuthRefreshToken OAuthRefreshToken[] RecallLog RecallLog[] Space Space[] MCPSession MCPSession[] Subscription Subscription? } enum PlanType { FREE PRO MAX } enum SubscriptionStatus { ACTIVE CANCELED PAST_DUE TRIALING PAUSED } enum AuthenticationMethod { GOOGLE MAGIC_LINK } enum IngestionStatus { PENDING PROCESSING COMPLETED FAILED CANCELLED NO_CREDITS } enum UserType { Agent User System } enum WebhookDeliveryStatus { SUCCESS FAILED }