Files
hatchet/prisma/schema.prisma
2024-05-09 18:28:18 -04:00

1494 lines
39 KiB
Plaintext

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator go {
provider = "go run github.com/steebchen/prisma-client-go"
output = "../internal/repository/prisma/db"
}
model User {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the user's email address
email String @unique
// whether the user's email address has been verified
emailVerified Boolean @default(false)
// the user's oauth providers
oauthProviders UserOAuth[]
// The hashed user's password. This is placed in a separate table so that it isn't returned by default.
password UserPassword?
// the user's name
name String?
// the user sessions
sessions UserSession[]
memberships TenantMember[]
githubAppOAuths GithubAppOAuth[]
}
model UserOAuth {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
// the linked user
user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
userId String @unique @db.Uuid
// the oauth provider
provider String
// the oauth provider's user id
providerUserId String
// the oauth provider's access token
accessToken Bytes @db.ByteA
// the oauth provider's refresh token
refreshToken Bytes? @db.ByteA
// the oauth provider's expiry time
expiresAt DateTime?
// oauth should be unique per user id + provider
@@unique([userId, provider])
}
model UserPassword {
hash String
user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
userId String @unique @db.Uuid
}
model UserSession {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
// the linked user. The user can be empty if the session is created but not authenticated.
user User? @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
userId String? @db.Uuid
// arbitrary session data
data Json?
// the expiry time of the session
expiresAt DateTime
}
// Tenant represents a unique tenant in the database. Each tenant-scoped resource should have the tenant as
// an identifier, which makes tenant isolation easier.
model Tenant {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
name String
slug String @unique
// wheather the user has opted out of analytics
analyticsOptOut Boolean @default(false)
events Event[]
workflows Workflow[]
jobs Job[]
steps Step[]
triggers WorkflowTriggers[]
workflowRuns WorkflowRun[]
workflowRunTriggers WorkflowRunTriggeredBy[]
jobRuns JobRun[]
jobRunLookupDatas JobRunLookupData[]
stepRuns StepRun[]
workers Worker[]
members TenantMember[]
workflowTags WorkflowTag[]
actions Action[]
services Service[]
invites TenantInviteLink[]
apiTokens APIToken[]
groupKeyRuns GetGroupKeyRun[]
vcsProviders TenantVcsProvider[]
githubAppInstallations GithubAppInstallation[]
githubPullRequests GithubPullRequest[]
githubPullRequestComments GithubPullRequestComment[]
githubWebhooks GithubWebhook[]
streamEvents StreamEvent[]
logs LogLine[]
snsIntegrations SNSIntegration[]
rateLimits RateLimit[]
stepRateLimits StepRateLimit[]
alertEmailGroups TenantAlertEmailGroup[]
slackWebhooks SlackAppWebhook[]
alertingSettings TenantAlertingSettings?
}
model TenantAlertingSettings {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @unique @db.Uuid
// the maximum alerting frequency
maxFrequency String @default("1h")
lastAlertedAt DateTime?
// the assigned ticker
ticker Ticker? @relation(fields: [tickerId], references: [id])
tickerId String? @db.Uuid
}
enum TenantMemberRole {
OWNER
ADMIN
MEMBER
}
model TenantMember {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the linked user
user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
userId String @db.Uuid
// the member's role
role TenantMemberRole
// members are unique per tenant
@@unique([tenantId, userId])
}
enum InviteLinkStatus {
PENDING
ACCEPTED
REJECTED
}
model TenantInviteLink {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
inviterEmail String
inviteeEmail String
expires DateTime
status InviteLinkStatus @default(PENDING)
role TenantMemberRole @default(OWNER)
}
model APIToken {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
// when it expires
expiresAt DateTime?
// whether the token has been revoked
revoked Boolean @default(false)
// an optional name for the token
name String?
tenant Tenant? @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String? @db.Uuid
}
// Event represents an event in the database.
model Event {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the event key
key String
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the event which was replayed
replayedFrom Event? @relation("EventReplay", fields: [replayedFromId], references: [id])
replayedFromId String? @db.Uuid
// the events which were replayed
replays Event[] @relation("EventReplay")
// data stored in the event
data Json?
// metadata stored in the event
additionalMetadata Json?
// the workflow runs that were triggered by this event
workflowRuns WorkflowRunTriggeredBy[]
}
model WorkflowTag {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
// the parent workflow
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the tag name
name String
// the tag color
color String @default("#93C5FD") // a nice indigo
// the workflows this tag is linked to
workflows Workflow[]
// tags are unique per tenant
@@unique([tenantId, name])
}
model Workflow {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the workflow name
name String
// the workflow description
description String?
// tracked versions of the workflow
versions WorkflowVersion[]
// the tags for this workflow
tags WorkflowTag[]
deploymentConfig WorkflowDeploymentConfig?
// workflow names are unique per tenant
@@unique([tenantId, name])
}
model WorkflowDeploymentConfig {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent workflow
workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade, onUpdate: Cascade)
workflowId String @unique @db.Uuid
gitRepoName String
gitRepoOwner String
gitRepoBranch String
// Github-related deployment config
githubAppInstallation GithubAppInstallation? @relation(fields: [githubAppInstallationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
githubAppInstallationId String? @db.Uuid
}
model WorkflowVersion {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// note that checksums don't need to be unique, as they're computed from the workflow
// declaration, which can be the same for multiple versions (e.g. on revert)
checksum String
version String?
order BigInt @default(autoincrement()) @db.BigInt
// the parent workflow
workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade, onUpdate: Cascade)
workflowId String @db.Uuid
// the declared triggers for the job
triggers WorkflowTriggers?
// concurrency limits for the workflow
concurrency WorkflowConcurrency?
// the declared jobs
jobs Job[]
// a job that runs when the workflow fails
onFailureJob Job? @relation("OnFailureJob", fields: [onFailureJobId], references: [id])
onFailureJobId String? @unique @db.Uuid
// all runs for the workflow
runs WorkflowRun[]
// the scheduled runs for the workflow
scheduled WorkflowTriggerScheduledRef[]
// the default amount of time to wait while scheduling a step run
scheduleTimeout String @default("5m")
}
enum ConcurrencyLimitStrategy {
// Cancel the existing runs and start a new one
CANCEL_IN_PROGRESS
// Don't create a new run if concurrency limit has been reached
DROP_NEWEST
// Queue new runs and start them when falling below the concurrency limit
QUEUE_NEWEST
// Performs round-robin queueing based on the concurrency group. For example, if there
// are 10 workflows queued in concurrency groups A, B and C, and the concurrency limit is 3,
// then 1 workflows from A, B and C will be started.
GROUP_ROUND_ROBIN
}
model WorkflowConcurrency {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
// the parent workflow
workflow WorkflowVersion @relation(fields: [workflowVersionId], references: [id], onDelete: Cascade, onUpdate: Cascade)
workflowVersionId String @unique @db.Uuid
// An action which gets the concurrency group for the WorkflowRun.
getConcurrencyGroup Action? @relation(fields: [getConcurrencyGroupId], references: [id])
getConcurrencyGroupId String? @db.Uuid
// the maximum number of concurrent workflow runs
maxRuns Int @default(1)
// the strategy to use when the concurrency limit is reached
limitStrategy ConcurrencyLimitStrategy @default(CANCEL_IN_PROGRESS)
}
model WorkflowTriggers {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent workflow
workflow WorkflowVersion @relation(fields: [workflowVersionId], references: [id], onDelete: Cascade, onUpdate: Cascade)
workflowVersionId String @unique @db.Uuid
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// events that trigger this workflow
events WorkflowTriggerEventRef[]
crons WorkflowTriggerCronRef[]
}
model WorkflowTriggerEventRef {
// the parent workflow
parent WorkflowTriggers @relation(fields: [parentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
parentId String @db.Uuid
// the event key
eventKey String
// event references must be unique per workflow
@@unique([parentId, eventKey])
}
model WorkflowTriggerCronRef {
// the parent workflow
parent WorkflowTriggers @relation(fields: [parentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
parentId String @db.Uuid
// the cron expression
cron String
// whether this cron is enabled or not
enabled Boolean @default(true)
// the assigned ticker
ticker Ticker? @relation(fields: [tickerId], references: [id])
tickerId String? @db.Uuid
triggered WorkflowRunTriggeredBy[]
// the input parameters to the scheduled workflow
input Json?
// cron references must be unique per workflow
@@unique([parentId, cron])
}
model WorkflowTriggerScheduledRef {
id String @id @unique @default(uuid()) @db.Uuid
// the parent workflow
parent WorkflowVersion @relation(fields: [parentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
parentId String @db.Uuid
// the time that the workflow should be triggered
triggerAt DateTime
// the assigned ticker
ticker Ticker? @relation(fields: [tickerId], references: [id])
tickerId String? @db.Uuid
// the input parameters to the scheduled workflow
input Json?
// that parent that spawned this workflow run
parentWorkflowRun WorkflowRun? @relation(fields: [parentWorkflowRunId], references: [id])
parentWorkflowRunId String? @db.Uuid
parentStepRun StepRun? @relation(fields: [parentStepRunId], references: [id])
parentStepRunId String? @db.Uuid
// if this is a child workflow run, the index of the child
childIndex Int?
// a user-defined key for this workflow run
childKey String?
triggered WorkflowRunTriggeredBy?
@@unique([parentId, parentStepRunId, childKey])
}
enum JobKind {
// DEFAULT job kinds get started immediately when the workflow execution starts
DEFAULT
// ON_FAILURE job kinds get started when the workflow fails
ON_FAILURE
}
model Job {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the parent workflow
workflow WorkflowVersion @relation(fields: [workflowVersionId], references: [id], onDelete: Cascade, onUpdate: Cascade)
workflowVersionId String @db.Uuid
// the job name
name String
// the job description
description String?
// the declared steps
steps Step[]
// a timeout value for the job
timeout String?
// any runs for this job
runs JobRun[]
// the kind of job
kind JobKind @default(DEFAULT)
// a link to workflow
failureRelations WorkflowVersion? @relation("OnFailureJob")
// jobs names are unique per workflow
@@unique([workflowVersionId, name])
}
model Action {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
actionId String
// the action description
description String?
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the action's steps
steps Step[]
// the action's workers
workers Worker[]
// the action's concurrency rules
concurrency WorkflowConcurrency[]
// actions are unique per tenant
@@unique([tenantId, actionId])
}
model Step {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// a readable id for the step
readableId String?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the parent job
job Job @relation(fields: [jobId], references: [id], onDelete: Cascade, onUpdate: Cascade)
jobId String @db.Uuid
// an action id for the step
action Action @relation(fields: [actionId, tenantId], references: [actionId, tenantId])
actionId String
timeout String?
retries Int @default(0)
// customUserData is a JSON object that can be used to store arbitrary data for the step
customUserData Json?
// a list of dependents for this step
children Step[] @relation("StepOrder")
// a list of dependencies for this step
parents Step[] @relation("StepOrder")
// a list of runs for this step
stepRuns StepRun[]
// the default amount of time to wait while scheduling a step run
scheduleTimeout String @default("5m")
rateLimits StepRateLimit[]
// readable ids are unique per job
@@unique([jobId, readableId])
}
model StepRateLimit {
units Int
step Step @relation(fields: [stepId], references: [id], onDelete: Cascade, onUpdate: Cascade)
stepId String @db.Uuid
rateLimit RateLimit @relation(fields: [tenantId, rateLimitKey], references: [tenantId, key])
rateLimitKey String
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
@@unique([stepId, rateLimitKey])
}
model RateLimit {
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the rate limit key
key String
// The max number of requests allowed in the window
limitValue Int
// the current rate limit bucket value
value Int
// the rate limit window
window String
// the time the rate limit was last refilled
lastRefill DateTime @default(now())
stepRunLimits StepRateLimit[]
// rate limits are unique per tenant
@@unique([tenantId, key])
}
enum WorkflowRunStatus {
PENDING
QUEUED
RUNNING
SUCCEEDED
FAILED
}
model WorkflowRun {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
displayName String?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the parent workflow
workflowVersion WorkflowVersion @relation(fields: [workflowVersionId], references: [id], onDelete: Cascade, onUpdate: Cascade)
workflowVersionId String @db.Uuid
concurrencyGroupId String?
getGroupKeyRun GetGroupKeyRun?
status WorkflowRunStatus @default(PENDING)
jobRuns JobRun[]
triggeredBy WorkflowRunTriggeredBy?
// the run error
error String?
// the run started at
startedAt DateTime?
// the run finished at
finishedAt DateTime?
// a list of dependents for this workflow run
children WorkflowRun[] @relation("WorkflowRunChild")
scheduledChildren WorkflowTriggerScheduledRef[]
// that parent that spawned this workflow run
parent WorkflowRun? @relation("WorkflowRunChild", fields: [parentId], references: [id])
parentId String? @db.Uuid
parentStepRun StepRun? @relation(fields: [parentStepRunId], references: [id])
parentStepRunId String? @db.Uuid
// if this is a child workflow run, the index of the child
childIndex Int?
// a user-defined key for this workflow run
childKey String?
// (optional) the branch for the github repo
gitRepoBranch String?
pullRequests GithubPullRequest[]
// (optional) additonal metadata for the workflow run
additionalMetadata Json?
@@unique([parentId, parentStepRunId, childKey])
}
model GetGroupKeyRun {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the parent workflow run
workflowRun WorkflowRun @relation(fields: [workflowRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
workflowRunId String @unique @db.Uuid
// the worker assigned to this group key run
worker Worker? @relation(fields: [workerId], references: [id])
workerId String? @db.Uuid
// the assigned ticker
ticker Ticker? @relation(fields: [tickerId], references: [id])
tickerId String? @db.Uuid
// the run status
status StepRunStatus @default(PENDING)
// the group key run input
input Json?
// the group key as output
output String?
// when the step should be requeued
requeueAfter DateTime?
// when the step run times out due to a scheduling timeout (no workers available)
scheduleTimeoutAt DateTime?
// the run error
error String?
// the run started at
startedAt DateTime?
// the run finished at
finishedAt DateTime?
// the run timeout at
timeoutAt DateTime?
// the run cancelled at
cancelledAt DateTime?
// the reason for why the run was cancelled
cancelledReason String?
// errors while cancelling the run
cancelledError String?
}
model WorkflowRunTriggeredBy {
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the tenant (needed for unique constraint)
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the parent workflow run
parent WorkflowRun @relation(fields: [parentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
parentId String @unique @db.Uuid
// the input if this was triggered manually
input Json?
// the parent event
event Event? @relation(fields: [eventId], references: [id])
eventId String? @db.Uuid
// the cron reference that triggered this workflow
cron WorkflowTriggerCronRef? @relation(fields: [cronParentId, cronSchedule], references: [parentId, cron])
cronParentId String? @db.Uuid
cronSchedule String?
// a specific time that triggered this workflow
scheduled WorkflowTriggerScheduledRef? @relation(fields: [scheduledId], references: [id])
scheduledId String? @unique @db.Uuid
}
enum JobRunStatus {
PENDING
RUNNING
SUCCEEDED
FAILED
CANCELLED
}
model JobRun {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the parent workflow run
workflowRun WorkflowRun @relation(fields: [workflowRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
workflowRunId String @db.Uuid
// the parent job
job Job @relation(fields: [jobId], references: [id], onDelete: Cascade, onUpdate: Cascade)
jobId String @db.Uuid
// the assigned ticker
ticker Ticker? @relation(fields: [tickerId], references: [id])
tickerId String? @db.Uuid
stepRuns StepRun[]
// the run status
status JobRunStatus @default(PENDING)
lookupData JobRunLookupData?
// the run result
result Json?
// the run started at
startedAt DateTime?
// the run finished at
finishedAt DateTime?
// the run timeout at
timeoutAt DateTime?
// the run cancelled at
cancelledAt DateTime?
// the reason for why the run was cancelled
cancelledReason String?
// errors while cancelling the run
cancelledError String?
// index for ResolveWorkflowRunStatus and ListJobRunsForWorkflowRun
@@index([workflowRunId, tenantId])
}
model JobRunLookupData {
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent job run
jobRun JobRun @relation(fields: [jobRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
jobRunId String @unique @db.Uuid
// the tenant id
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
data Json?
// additional field so we can look up by both job run id and tenant id
@@unique([jobRunId, tenantId])
}
enum StepRunStatus {
// pending states
PENDING
PENDING_ASSIGNMENT // A run is in a pending assignment state if it is waiting for a worker to be assigned to it
ASSIGNED
// running states
RUNNING
// final states
SUCCEEDED
FAILED
CANCELLED
}
model StepRun {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the parent job run
jobRun JobRun @relation(fields: [jobRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
jobRunId String @db.Uuid
// the parent step
step Step @relation(fields: [stepId], references: [id], onDelete: Cascade, onUpdate: Cascade)
stepId String @db.Uuid
// a list of dependents for this step
children StepRun[] @relation("StepRunOrder")
// a list of dependencies for this step
parents StepRun[] @relation("StepRunOrder")
order BigInt @default(autoincrement()) @db.BigInt
// the worker assigned to this job
worker Worker? @relation(fields: [workerId], references: [id])
workerId String? @db.Uuid
// the assigned ticker
ticker Ticker? @relation(fields: [tickerId], references: [id])
tickerId String? @db.Uuid
// the run status
status StepRunStatus @default(PENDING)
// the run input
input Json?
// the run output
output Json?
// inputSchema is a JSON object which declares a JSON schema for the input data
inputSchema Json?
// when the step should be requeued
requeueAfter DateTime?
// when the step run times out due to a scheduling timeout (no workers available)
scheduleTimeoutAt DateTime?
// which retry we're on for this step run
retryCount Int @default(0)
// the run error
error String?
// the run started at
startedAt DateTime?
// the run finished at
finishedAt DateTime?
// the run timeout at
timeoutAt DateTime?
// the run cancelled at
cancelledAt DateTime?
// the reason for why the run was cancelled
cancelledReason String?
// errors while cancelling the run
cancelledError String?
// a map of override values to caller files for the step run
callerFiles Json?
// the github branch that this is running on
gitRepoBranch String?
archivedResults StepRunResultArchive[]
streamEvents StreamEvent[]
logs LogLine[]
childWorkflowRuns WorkflowRun[]
childSchedules WorkflowTriggerScheduledRef[]
events StepRunEvent[]
// index for ListStepRunsToRequeue and ListStepRunsToReassign
@@index([tenantId, status, input, requeueAfter, createdAt])
// index for LinkStepRunParents
@@index([stepId])
// index for ListStartableStepRuns
@@index([jobRunId, status])
// index for ResolveLaterStepRuns
@@index([id, tenantId])
// index for ResolveJobRunStatus, ResolveLaterStepRuns, and LinkStepRunParents
@@index([jobRunId, tenantId, order])
}
enum StepRunEventReason {
REQUEUED_NO_WORKER
REQUEUED_RATE_LIMIT
SCHEDULING_TIMED_OUT
ASSIGNED
STARTED
FINISHED
FAILED
RETRYING
CANCELLED
}
enum StepRunEventSeverity {
INFO
WARNING
CRITICAL
}
model StepRunEvent {
id BigInt @unique @default(autoincrement()) @db.BigInt
timeFirstSeen DateTime @default(now())
timeLastSeen DateTime @default(now())
// the parent step run
stepRun StepRun @relation(fields: [stepRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
stepRunId String @db.Uuid
// the event reason
reason StepRunEventReason
// the event severity
severity StepRunEventSeverity
message String
count Int
data Json?
@@index([stepRunId])
}
model StepRunResultArchive {
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent step run
stepRun StepRun @relation(fields: [stepRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
stepRunId String @db.Uuid
order BigInt @default(autoincrement()) @db.BigInt
// the run input
input Json?
// the run output
output Json?
// the run error
error String?
// the run started at
startedAt DateTime?
// the run finished at
finishedAt DateTime?
// the run timeout at
timeoutAt DateTime?
// the run cancelled at
cancelledAt DateTime?
// the reason for why the run was cancelled
cancelledReason String?
// errors while cancelling the run
cancelledError String?
}
model Dispatcher {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the last heartbeat time
lastHeartbeatAt DateTime?
// whether this dispatcher is active or not
isActive Boolean @default(true)
// a list of workers connected to this dispatcher
workers Worker[]
}
model Ticker {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
// the last heartbeat time
lastHeartbeatAt DateTime?
// whether this ticker is active or not
isActive Boolean @default(true)
jobRuns JobRun[]
stepRuns StepRun[]
crons WorkflowTriggerCronRef[]
scheduled WorkflowTriggerScheduledRef[]
groupKeyRuns GetGroupKeyRun[]
tenantAlerts TenantAlertingSettings[]
}
model Worker {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the last heartbeat time
lastHeartbeatAt DateTime?
// the worker name
name String
// the dispatcher the worker is connected to
dispatcher Dispatcher? @relation(fields: [dispatcherId], references: [id], onDelete: SetNull, onUpdate: Cascade)
dispatcherId String? @db.Uuid
maxRuns Int?
services Service[]
// the actions this worker can run
actions Action[]
// the jobs the worker has run
stepRuns StepRun[]
// the runs which retrieve the group keys
groupKeyRuns GetGroupKeyRun[]
semaphore WorkerSemaphore?
}
model WorkerSemaphore {
// the parent worker
worker Worker @relation(fields: [workerId], references: [id], onDelete: Cascade, onUpdate: Cascade)
workerId String @unique @db.Uuid
// keeps track of maxRuns - runningRuns on the worker
slots Int
}
model Service {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the service name
name String
// the service description
description String?
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the service's workers
workers Worker[]
@@unique([tenantId, name])
}
enum VcsProvider {
GITHUB
}
model TenantVcsProvider {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
vcsProvider VcsProvider
// the provider name
ghInstallations GithubAppInstallation[]
// the provider's configuration
config Json?
@@unique([tenantId, vcsProvider])
}
model GithubAppInstallation {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the oauth id for the user that linked this installation
githubAppOAuth GithubAppOAuth @relation(fields: [githubAppOAuthId], references: [id], onDelete: Cascade, onUpdate: Cascade)
githubAppOAuthId String @db.Uuid
// the installation id
installationId Int
accountName String
accountId Int
// optionals
accountAvatarURL String?
installationSettingsURL String?
// the installation's configuration
config Json?
webhooks GithubWebhook[]
deploymentConfigs WorkflowDeploymentConfig[]
Tenant Tenant? @relation(fields: [tenantId], references: [id])
tenantId String? @db.Uuid
TenantVcsProvider TenantVcsProvider? @relation(fields: [tenantVcsProviderId], references: [id])
tenantVcsProviderId String? @db.Uuid
@@unique([installationId, accountId])
}
model TenantAlertEmailGroup {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// a list of comma-separated emails for the group
emails String
}
model SlackAppWebhook {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
teamId String
teamName String
channelId String
channelName String
// encrypted at rest
webhookURL Bytes @db.ByteA
@@unique([tenantId, teamId, channelId])
}
model GithubAppOAuth {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the oauth provider's user id
githubUserID Int @unique
// a list of users this github account is linked to
users User[]
// a list of installations this github account is linked to
installations GithubAppInstallation[]
// the oauth provider's access token
accessToken Bytes @db.ByteA
// the oauth provider's refresh token
refreshToken Bytes? @db.ByteA
// the oauth provider's expiry time
expiresAt DateTime?
}
model GithubPullRequest {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the repository owner
repositoryOwner String
// the repository name
repositoryName String
// the pull request id
pullRequestID Int
// the pull request title
pullRequestTitle String
// the pull request number
pullRequestNumber Int
// the pull request head branch
pullRequestHeadBranch String
// the pull request base branch
pullRequestBaseBranch String
// the pull request state
pullRequestState String
// the pull request comments
pullRequestComments GithubPullRequestComment[]
workflowRuns WorkflowRun[]
@@unique([tenantId, repositoryOwner, repositoryName, pullRequestNumber])
}
model GithubPullRequestComment {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
pullRequest GithubPullRequest @relation(fields: [pullRequestID], references: [id], onDelete: Cascade, onUpdate: Cascade)
pullRequestID String @db.Uuid
// the module id
moduleID String
// the comment id
commentID Int
}
model GithubWebhook {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the repository owner
repositoryOwner String
// the repository name
repositoryName String
// the webhook signing secret
signingSecret Bytes @db.ByteA
// the webhook's installations
installations GithubAppInstallation[]
@@unique([tenantId, repositoryOwner, repositoryName])
}
enum LogLineLevel {
DEBUG
INFO
WARN
ERROR
}
model LogLine {
// base fields
id BigInt @id @default(autoincrement()) @db.BigInt
createdAt DateTime @default(now())
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the step run id this log is associated with
stepRun StepRun? @relation(fields: [stepRunId], references: [id], onDelete: SetNull, onUpdate: Cascade)
stepRunId String? @db.Uuid
// the log line message
message String
// the log line level
level LogLineLevel @default(INFO)
// (optional) the log line metadata
metadata Json?
}
model StreamEvent {
// base fields
id BigInt @id @default(autoincrement()) @db.BigInt
createdAt DateTime @default(now())
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the step run id this stream event is associated with
stepRun StepRun? @relation(fields: [stepRunId], references: [id], onDelete: SetNull, onUpdate: Cascade)
stepRunId String? @db.Uuid
// the stream event bytes
message Bytes
// (optional) the stream event metadata
metadata Json?
}
model SNSIntegration {
// base fields
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
// the parent tenant
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tenantId String @db.Uuid
// the sns topic arn
topicArn String
@@unique([tenantId, topicArn])
}