mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-01-10 07:38:04 -05:00
feat(platform): Add target database model to reflect domain (#8375)
This commit is contained in:
628
autogpt_platform/backend/target.prisma
Normal file
628
autogpt_platform/backend/target.prisma
Normal file
@@ -0,0 +1,628 @@
|
||||
// We need to migrate our database schema to support the domain as we understand it now
|
||||
// To do so requires adding a bunch of new tables, but also modiftying old ones and how
|
||||
// they relate to each other. This is a large change, so instead of doing in in one go,
|
||||
// We have created the target schema, and will migrate to it incrementally.
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-py"
|
||||
recursive_type_depth = 5
|
||||
interface = "asyncio"
|
||||
}
|
||||
|
||||
// User model to mirror Auth provider users
|
||||
model User {
|
||||
id String @id @db.Uuid // This should match the Supabase user ID
|
||||
email String @unique
|
||||
name String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
metadata Json? @default("{}")
|
||||
|
||||
// Relations
|
||||
Agents Agent[]
|
||||
AgentExecutions AgentExecution[]
|
||||
AgentExecutionSchedules AgentExecutionSchedule[]
|
||||
AnalyticsDetails AnalyticsDetails[]
|
||||
AnalyticsMetrics AnalyticsMetrics[]
|
||||
UserBlockCredit UserBlockCredit[]
|
||||
AgentPresets AgentPreset[]
|
||||
UserAgents UserAgent[]
|
||||
|
||||
// User Group relations
|
||||
UserGroupMemberships UserGroupMembership[]
|
||||
Profile Profile[]
|
||||
StoreListing StoreListing[]
|
||||
StoreListingSubmission StoreListingSubmission[]
|
||||
StoreListingReview StoreListingReview[]
|
||||
}
|
||||
|
||||
model UserGroup {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
name String
|
||||
description String
|
||||
groupIconUrl String?
|
||||
|
||||
UserGroupMemberships UserGroupMembership[]
|
||||
|
||||
Agents Agent[]
|
||||
Profile Profile[]
|
||||
StoreListing StoreListing[]
|
||||
|
||||
@@index([name])
|
||||
}
|
||||
|
||||
enum UserGroupRole {
|
||||
MEMBER
|
||||
OWNER
|
||||
}
|
||||
|
||||
model UserGroupMembership {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
userId String @db.Uuid
|
||||
User User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
userGroupId String @db.Uuid
|
||||
UserGroup UserGroup @relation(fields: [userGroupId], references: [id], onDelete: Cascade)
|
||||
Role UserGroupRole @default(MEMBER)
|
||||
|
||||
@@unique([userId, userGroupId])
|
||||
@@index([userId])
|
||||
@@index([userGroupId])
|
||||
}
|
||||
|
||||
// This model describes the Agent Graph/Flow (Multi Agent System).
|
||||
model Agent {
|
||||
id String @default(uuid()) @db.Uuid
|
||||
version Int @default(1)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
name String?
|
||||
description String?
|
||||
|
||||
// Link to User model
|
||||
createdByUserId String? @db.Uuid
|
||||
// Do not cascade delete the agent when the user is deleted
|
||||
// This allows us to delete user data with deleting the agent which maybe in use by other users
|
||||
CreatedByUser User? @relation(fields: [createdByUserId], references: [id], onDelete: SetNull)
|
||||
|
||||
groupId String? @db.Uuid
|
||||
// Do not cascade delete the agent when the group is deleted
|
||||
// This allows us to delete user group data with deleting the agent which maybe in use by other users
|
||||
Group UserGroup? @relation(fields: [groupId], references: [id], onDelete: SetNull)
|
||||
|
||||
AgentNodes AgentNode[]
|
||||
AgentExecution AgentExecution[]
|
||||
|
||||
// All sub-graphs are defined within this 1-level depth list (even if it's a nested graph).
|
||||
SubAgents Agent[] @relation("SubAgents")
|
||||
agentParentId String? @db.Uuid
|
||||
agentParentVersion Int?
|
||||
AgentParent Agent? @relation("SubAgents", fields: [agentParentId, agentParentVersion], references: [id, version])
|
||||
|
||||
AgentPresets AgentPreset[]
|
||||
WebhookTrigger WebhookTrigger[]
|
||||
AgentExecutionSchedule AgentExecutionSchedule[]
|
||||
UserAgents UserAgent[]
|
||||
UserBlockCredit UserBlockCredit[]
|
||||
StoreListing StoreListing[]
|
||||
StoreListingVersion StoreListingVersion[]
|
||||
|
||||
@@id(name: "agentVersionId", [id, version])
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
//////////////// USER SPECIFIC DATA ////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// An AgentPrest is an Agent + User Configuration of that agent.
|
||||
// For example, if someone has created a weather agent and they want to set it up to
|
||||
// Inform them of extreme weather warnings in Texas, the agent with the configuration to set it to
|
||||
// monitor texas, along with the cron setup or webhook tiggers, is an AgentPreset
|
||||
model AgentPreset {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
name String
|
||||
description String
|
||||
|
||||
// For agents that can be triggered by webhooks or cronjob
|
||||
// This bool allows us to disable a configured agent without deleting it
|
||||
isActive Boolean @default(true)
|
||||
|
||||
userId String @db.Uuid
|
||||
User User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
agentId String @db.Uuid
|
||||
agentVersion Int
|
||||
Agent Agent @relation(fields: [agentId, agentVersion], references: [id, version], onDelete: Cascade)
|
||||
|
||||
InputPresets AgentNodeExecutionInputOutput[] @relation("AgentPresetsInputData")
|
||||
UserAgents UserAgent[]
|
||||
WebhookTrigger WebhookTrigger[]
|
||||
AgentExecutionSchedule AgentExecutionSchedule[]
|
||||
AgentExecution AgentExecution[]
|
||||
|
||||
@@index([userId])
|
||||
}
|
||||
|
||||
// For the library page
|
||||
// It is a user controlled list of agents, that they will see in there library
|
||||
model UserAgent {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
userId String @db.Uuid
|
||||
User User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
agentId String @db.Uuid
|
||||
agentVersion Int
|
||||
Agent Agent @relation(fields: [agentId, agentVersion], references: [id, version])
|
||||
|
||||
agentPresetId String? @db.Uuid
|
||||
AgentPreset AgentPreset? @relation(fields: [agentPresetId], references: [id])
|
||||
|
||||
isFavorite Boolean @default(false)
|
||||
isCreatedByUser Boolean @default(false)
|
||||
isArchived Boolean @default(false)
|
||||
isDeleted Boolean @default(false)
|
||||
|
||||
@@index([userId])
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
//////// AGENT DEFINITION AND EXECUTION TABLES ////////
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
// This model describes a single node in the Agent Graph/Flow (Multi Agent System).
|
||||
model AgentNode {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
|
||||
agentBlockId String @db.Uuid
|
||||
AgentBlock AgentBlock @relation(fields: [agentBlockId], references: [id], onUpdate: Cascade)
|
||||
|
||||
agentId String @db.Uuid
|
||||
agentVersion Int @default(1)
|
||||
Agent Agent @relation(fields: [agentId, agentVersion], references: [id, version], onDelete: Cascade)
|
||||
|
||||
// List of consumed input, that the parent node should provide.
|
||||
Input AgentNodeLink[] @relation("AgentNodeSink")
|
||||
|
||||
// List of produced output, that the child node should be executed.
|
||||
Output AgentNodeLink[] @relation("AgentNodeSource")
|
||||
|
||||
// JSON serialized dict[str, str] containing predefined input values.
|
||||
constantInput Json @default("{}")
|
||||
|
||||
// JSON serialized dict[str, str] containing the node metadata.
|
||||
metadata Json @default("{}")
|
||||
|
||||
ExecutionHistory AgentNodeExecution[]
|
||||
}
|
||||
|
||||
// This model describes the link between two AgentNodes.
|
||||
model AgentNodeLink {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
|
||||
// Output of a node is connected to the source of the link.
|
||||
agentNodeSourceId String @db.Uuid
|
||||
AgentNodeSource AgentNode @relation("AgentNodeSource", fields: [agentNodeSourceId], references: [id], onDelete: Cascade)
|
||||
sourceName String
|
||||
|
||||
// Input of a node is connected to the sink of the link.
|
||||
agentNodeSinkId String @db.Uuid
|
||||
AgentNodeSink AgentNode @relation("AgentNodeSink", fields: [agentNodeSinkId], references: [id], onDelete: Cascade)
|
||||
sinkName String
|
||||
|
||||
// Default: the data coming from the source can only be consumed by the sink once, Static: input data will be reused.
|
||||
isStatic Boolean @default(false)
|
||||
}
|
||||
|
||||
// This model describes a component that will be executed by the AgentNode.
|
||||
model AgentBlock {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
name String @unique
|
||||
|
||||
// We allow a block to have multiple types of input & output.
|
||||
// Serialized object-typed `jsonschema` with top-level properties as input/output name.
|
||||
inputSchema Json @default("{}")
|
||||
outputSchema Json @default("{}")
|
||||
|
||||
// Prisma requires explicit back-references.
|
||||
ReferencedByAgentNode AgentNode[]
|
||||
UserBlockCredit UserBlockCredit[]
|
||||
}
|
||||
|
||||
// This model describes the status of an AgentExecution or AgentNodeExecution.
|
||||
enum AgentExecutionStatus {
|
||||
INCOMPLETE
|
||||
QUEUED
|
||||
RUNNING
|
||||
COMPLETED
|
||||
FAILED
|
||||
}
|
||||
|
||||
// Enum for execution trigger types
|
||||
enum ExecutionTriggerType {
|
||||
MANUAL
|
||||
SCHEDULE
|
||||
WEBHOOK
|
||||
}
|
||||
|
||||
// This model describes the execution of an AgentGraph.
|
||||
model AgentExecution {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
startedAt DateTime?
|
||||
executionTriggerType ExecutionTriggerType @default(MANUAL)
|
||||
|
||||
executionStatus AgentExecutionStatus @default(COMPLETED)
|
||||
|
||||
agentId String @db.Uuid
|
||||
agentVersion Int @default(1)
|
||||
Agent Agent @relation(fields: [agentId, agentVersion], references: [id, version], onDelete: Cascade)
|
||||
|
||||
// we need to be able to associate an agent execution with an agent preset
|
||||
agentPresetId String? @db.Uuid
|
||||
AgentPreset AgentPreset? @relation(fields: [agentPresetId], references: [id])
|
||||
|
||||
AgentNodeExecutions AgentNodeExecution[]
|
||||
|
||||
// This is so we can track which user executed the agent.
|
||||
executedByUserId String @db.Uuid
|
||||
ExecutedByUser User @relation(fields: [executedByUserId], references: [id], onDelete: Cascade)
|
||||
|
||||
stats Json @default("{}") // JSON serialized object
|
||||
}
|
||||
|
||||
// This model describes the execution of an AgentNode.
|
||||
model AgentNodeExecution {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
|
||||
agentExecutionId String @db.Uuid
|
||||
AgentExecution AgentExecution @relation(fields: [agentExecutionId], references: [id], onDelete: Cascade)
|
||||
|
||||
agentNodeId String @db.Uuid
|
||||
AgentNode AgentNode @relation(fields: [agentNodeId], references: [id], onDelete: Cascade)
|
||||
|
||||
Input AgentNodeExecutionInputOutput[] @relation("AgentNodeExecutionInput")
|
||||
Output AgentNodeExecutionInputOutput[] @relation("AgentNodeExecutionOutput")
|
||||
|
||||
executionStatus AgentExecutionStatus @default(COMPLETED)
|
||||
// Final JSON serialized input data for the node execution.
|
||||
executionData String?
|
||||
addedTime DateTime @default(now())
|
||||
queuedTime DateTime?
|
||||
startedTime DateTime?
|
||||
endedTime DateTime?
|
||||
|
||||
stats Json @default("{}") // JSON serialized object
|
||||
UserBlockCredit UserBlockCredit[]
|
||||
}
|
||||
|
||||
// This model describes the output of an AgentNodeExecution.
|
||||
model AgentNodeExecutionInputOutput {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
|
||||
name String
|
||||
data String
|
||||
time DateTime @default(now())
|
||||
|
||||
// Prisma requires explicit back-references.
|
||||
referencedByInputExecId String? @db.Uuid
|
||||
ReferencedByInputExec AgentNodeExecution? @relation("AgentNodeExecutionInput", fields: [referencedByInputExecId], references: [id], onDelete: Cascade)
|
||||
referencedByOutputExecId String? @db.Uuid
|
||||
ReferencedByOutputExec AgentNodeExecution? @relation("AgentNodeExecutionOutput", fields: [referencedByOutputExecId], references: [id], onDelete: Cascade)
|
||||
|
||||
agentPresetId String? @db.Uuid
|
||||
AgentPreset AgentPreset? @relation("AgentPresetsInputData", fields: [agentPresetId], references: [id])
|
||||
|
||||
// Input and Output pin names are unique for each AgentNodeExecution.
|
||||
@@unique([referencedByInputExecId, referencedByOutputExecId, name])
|
||||
}
|
||||
|
||||
// This model describes the recurring execution schedule of an Agent.
|
||||
model AgentExecutionSchedule {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
agentPresetId String @db.Uuid
|
||||
AgentPreset AgentPreset @relation(fields: [agentPresetId], references: [id], onDelete: Cascade)
|
||||
|
||||
schedule String // cron expression
|
||||
isEnabled Boolean @default(true)
|
||||
|
||||
// Allows triggers to be routed down different execution paths in an agent graph
|
||||
triggerIdentifier String
|
||||
|
||||
// default and set the value on each update, lastUpdated field has no time zone.
|
||||
lastUpdated DateTime @default(now()) @updatedAt
|
||||
|
||||
// Link to User model
|
||||
userId String @db.Uuid
|
||||
User User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
Agent Agent? @relation(fields: [agentId, agentVersion], references: [id, version])
|
||||
agentId String? @db.Uuid
|
||||
agentVersion Int?
|
||||
|
||||
@@index([isEnabled])
|
||||
}
|
||||
|
||||
enum HttpMethod {
|
||||
GET
|
||||
POST
|
||||
PUT
|
||||
DELETE
|
||||
PATCH
|
||||
}
|
||||
|
||||
model WebhookTrigger {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
agentPresetId String @db.Uuid
|
||||
AgentPreset AgentPreset @relation(fields: [agentPresetId], references: [id])
|
||||
|
||||
method HttpMethod
|
||||
urlSlug String
|
||||
|
||||
// Allows triggers to be routed down different execution paths in an agent graph
|
||||
triggerIdentifier String
|
||||
|
||||
isActive Boolean @default(true)
|
||||
lastReceivedDataAt DateTime?
|
||||
isDeleted Boolean @default(false)
|
||||
Agent Agent? @relation(fields: [agentId, agentVersion], references: [id, version])
|
||||
agentId String? @db.Uuid
|
||||
agentVersion Int?
|
||||
|
||||
@@index([agentPresetId])
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////// METRICS TRACKING TABLES ////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
model AnalyticsDetails {
|
||||
// PK uses gen_random_uuid() to allow the db inserts to happen outside of prisma
|
||||
// typical uuid() inserts are handled by prisma
|
||||
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
// Link to User model
|
||||
userId String @db.Uuid
|
||||
User User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Analytics Categorical data used for filtering (indexable w and w/o userId)
|
||||
type String
|
||||
|
||||
// Analytic Specific Data. We should use a union type here, but prisma doesn't support it.
|
||||
data Json @default("{}")
|
||||
|
||||
// Indexable field for any count based analytical measures like page order clicking, tutorial step completion, etc.
|
||||
dataIndex String?
|
||||
|
||||
@@index([userId, type], name: "analyticsDetails")
|
||||
@@index([type])
|
||||
}
|
||||
|
||||
model AnalyticsMetrics {
|
||||
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
// Analytics Categorical data used for filtering (indexable w and w/o userId)
|
||||
analyticMetric String
|
||||
// Any numeric data that should be counted upon, summed, or otherwise aggregated.
|
||||
value Float
|
||||
// Any string data that should be used to identify the metric as distinct.
|
||||
// ex: '/build' vs '/market'
|
||||
dataString String?
|
||||
|
||||
// Link to User model
|
||||
userId String @db.Uuid
|
||||
User User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
//////// ACCOUNTING AND CREDIT SYSTEM TABLES //////////
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
enum UserBlockCreditType {
|
||||
TOP_UP
|
||||
USAGE
|
||||
}
|
||||
|
||||
model UserBlockCredit {
|
||||
transactionKey String @default(uuid())
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
userId String @db.Uuid
|
||||
User User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
blockId String? @db.Uuid
|
||||
Block AgentBlock? @relation(fields: [blockId], references: [id])
|
||||
|
||||
// We need to be able to associate a credit transaction with an agent
|
||||
executedAgentId String? @db.Uuid
|
||||
executedAgentVersion Int?
|
||||
ExecutedAgent Agent? @relation(fields: [executedAgentId, executedAgentVersion], references: [id, version])
|
||||
|
||||
// We need to be able to associate a cost with a specific agent execution
|
||||
agentNodeExecutionId String? @db.Uuid
|
||||
AgentNodeExecution AgentNodeExecution? @relation(fields: [agentNodeExecutionId], references: [id])
|
||||
|
||||
amount Int
|
||||
type UserBlockCreditType
|
||||
|
||||
isActive Boolean @default(true)
|
||||
metadata Json @default("{}")
|
||||
|
||||
@@id(name: "creditTransactionIdentifier", [transactionKey, userId])
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////// Store TABLES ///////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
model Profile {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
// Only 1 of user or group can be set.
|
||||
// The user this profile belongs to, if any.
|
||||
userId String? @db.Uuid
|
||||
User User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
// The group this profile belongs to, if any.
|
||||
groupId String? @db.Uuid
|
||||
Group UserGroup? @relation(fields: [groupId], references: [id])
|
||||
|
||||
username String @unique
|
||||
description String
|
||||
|
||||
links String[]
|
||||
|
||||
avatarUrl String?
|
||||
|
||||
@@index([username])
|
||||
}
|
||||
|
||||
model StoreListing {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
isDeleted Boolean @default(false)
|
||||
// Not needed but makes lookups faster
|
||||
isApproved Boolean @default(false)
|
||||
|
||||
// The agent link here is only so we can do lookup on agentId, for the listing the StoreListingVersion is used.
|
||||
agentId String @db.Uuid
|
||||
agentVersion Int
|
||||
Agent Agent @relation(fields: [agentId, agentVersion], references: [id, version], onDelete: Cascade)
|
||||
|
||||
owningUserId String @db.Uuid
|
||||
OwningUser User @relation(fields: [owningUserId], references: [id])
|
||||
|
||||
isGroupListing Boolean @default(false)
|
||||
owningGroupId String? @db.Uuid
|
||||
OwningGroup UserGroup? @relation(fields: [owningGroupId], references: [id])
|
||||
|
||||
StoreListingVersions StoreListingVersion[]
|
||||
StoreListingSubmission StoreListingSubmission[]
|
||||
|
||||
@@index([isApproved])
|
||||
@@index([agentId])
|
||||
@@index([owningUserId])
|
||||
@@index([owningGroupId])
|
||||
}
|
||||
|
||||
model StoreListingVersion {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
version Int @default(1)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
// The agent and version to be listed on the store
|
||||
agentId String @db.Uuid
|
||||
agentVersion Int
|
||||
Agent Agent @relation(fields: [agentId, agentVersion], references: [id, version])
|
||||
|
||||
// The detials for this version of the agent, this allows the author to update the details of the agent,
|
||||
// But still allow using old versions of the agent with there original details.
|
||||
// TODO: Create a database view that shows only the latest version of each store listing.
|
||||
slug String
|
||||
name String
|
||||
videoUrl String?
|
||||
imageUrls String[]
|
||||
description String
|
||||
categories String[]
|
||||
|
||||
isFeatured Boolean @default(false)
|
||||
|
||||
isDeleted Boolean @default(false)
|
||||
// Old versions can be made unavailable by the author if desired
|
||||
isAvailable Boolean @default(true)
|
||||
// Not needed but makes lookups faster
|
||||
isApproved Boolean @default(false)
|
||||
StoreListing StoreListing? @relation(fields: [storeListingId], references: [id], onDelete: Cascade)
|
||||
storeListingId String? @db.Uuid
|
||||
StoreListingSubmission StoreListingSubmission[]
|
||||
|
||||
// Reviews are on a specific version, but then aggregated up to the listing.
|
||||
// This allows us to provide a review filter to current version of the agent.
|
||||
StoreListingReview StoreListingReview[]
|
||||
|
||||
@@unique([agentId, agentVersion])
|
||||
@@index([agentId, agentVersion, isApproved])
|
||||
}
|
||||
|
||||
model StoreListingReview {
|
||||
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
storeListingVersionId String @db.Uuid
|
||||
StoreListingVersion StoreListingVersion @relation(fields: [storeListingVersionId], references: [id], onDelete: Cascade)
|
||||
|
||||
reviewByUserId String @db.Uuid
|
||||
ReviewByUser User @relation(fields: [reviewByUserId], references: [id])
|
||||
|
||||
score Int
|
||||
comments String?
|
||||
}
|
||||
|
||||
enum SubmissionStatus {
|
||||
DAFT
|
||||
PENDING
|
||||
APPROVED
|
||||
REJECTED
|
||||
}
|
||||
|
||||
model StoreListingSubmission {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
storeListingId String @db.Uuid
|
||||
StoreListing StoreListing @relation(fields: [storeListingId], references: [id], onDelete: Cascade)
|
||||
|
||||
storeListingVersionId String @db.Uuid
|
||||
StoreListingVersion StoreListingVersion @relation(fields: [storeListingVersionId], references: [id], onDelete: Cascade)
|
||||
|
||||
reviewerId String @db.Uuid
|
||||
Reviewer User @relation(fields: [reviewerId], references: [id])
|
||||
|
||||
Status SubmissionStatus @default(PENDING)
|
||||
reviewComments String?
|
||||
|
||||
@@index([storeListingId])
|
||||
@@index([Status])
|
||||
}
|
||||
Reference in New Issue
Block a user