Files
Eric Allam f9ec66c562 v3: new build system (#1265)
* upgrade @opentelemetry packages to the latest versions

* remove v2 only packages, will be moved to a dedicated repo

* remove more v2 code and run pnpm install

* use the npm yalt package in the webapp

* convert @trigger.dev/core to tshy

* Switch from jest to vitest in @trigger.dev/core

* Fixed core test

* move core-backend code into core subpath export

* convert @trigger.dev/sdk to tshy

* Removed hono

* move core-apps to core/v3/apps, remove core-apps, start converting cli-v3

* Fix up some of the commands

* cli now building and loadable

* using package-json-from-dist to get package version now in core and cli

* dev command WIP

* cleaned up some repetition and structure of the entry point stuff

* bringing back the background worker stuff

* Indexing of the v3 catalog

* getting closer to executing dev runs...

* centralize dev logging using event emitter

* Move indexing to it’s own entry point, simplify code

* dev runs working

* Get instrumentation to work with openai

* debugging achieved internally

* provide worker files as part of the worker creation on the server

* support for cjs and esm javascript

* Fixed timeout

* worker manifest now has the config path

* auto-upgrade config to non-deprecated alternatives

* Adding package preview release

* deployment WIP

* improve the syncEnvVars output and adapt resolveEnvVars

* WIP bun runtime

* WIP bun support

* seed tasks with the machine preset if listed in the config

* deploy run executions WIP, extracted TaskRunProcess into 1 place

* deployed tasks running and executing 🎉

* support for waits and better flushing & process cleanup

* Fixed the heartbeating

* Better warning messages

* Improve and unify the indexing between dev and deploy

* Support for external deps that need node-gyp to build

* build extensions can now install custom packages and run instructions in the image. Also prisma extension now works and also works with multiple schema files

* Add back in the main/types/module to sdk

* dev no longer is Ink/React, grace period for disconnections in dev

* Fix the changeset config

* More changeset fixes

* Remove config packages

* More changeset fixes

* Fixed typescript issues (needed to revert back to zod 3.22.3

* Fix pr_checks workflow

* Remove the prepare script

* Fixed tests and package versions

* Remove cli test script

* Remove packages from tailwind watch paths

* Add repo to public packages

* Just commit the generated files and do the building at dev time

* Try and get pkg.pr.new working

* Try again

* Fix emitDecoratorMetadata importing named export from typescript

* config file backwards compat with export const config

* Fixed issue where import errors weren’t coming through

* p-retry is a prod dep

* typescript needs to be a prod dependency for emitDecoratorMetadata

* Add better debug logging to help track down import-in-the-middle bug

* An external is only considered resolvable if it resolves to the same path as the collected external

* Fix runtime checks to allow >=18.20

* Move extensions to a new build package

* Fixed building packages in dockerfile

* Remove the e2e test from publish workflow for now

* Don’t treat pkg.pr.new versions has needing upgrading

* making sure config handleError works, and discovered path aliases don’t work in config files

* Strip empty string env vars so they accidentally override real values

* Couple of things

* Update version to use preview instead of beta

* Hopefully fix re-attempts with >30s delay

* Match socket emit messages to current latest in main

* Initial guide

* Go back to beta

* Go back to the preview, and update guide to use pr preview tags

* Go back to beta

---------

Co-authored-by: Matt Aitken <matt@mattaitken.com>
2024-08-23 13:10:15 +01:00

2556 lines
68 KiB
Plaintext

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 User {
id String @id @default(cuid())
email String @unique
authenticationMethod AuthenticationMethod
authenticationProfile Json?
authenticationExtraParams Json?
authIdentifier String? @unique
displayName String?
name String?
avatarUrl String?
admin Boolean @default(false)
isOnCloudWaitlist Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
featureCloud Boolean @default(false)
isOnHostedRepoWaitlist Boolean @default(false)
marketingEmails Boolean @default(true)
confirmedBasicDetails Boolean @default(false)
referralSource String?
orgMemberships OrgMember[]
sentInvites OrgMemberInvite[]
apiVotes ApiIntegrationVote[]
invitationCode InvitationCode? @relation(fields: [invitationCodeId], references: [id])
invitationCodeId String?
personalAccessTokens PersonalAccessToken[]
deployments WorkerDeployment[]
}
// @deprecated This model is no longer used as the Cloud is out of private beta
// Leaving it here for now for historical reasons
model InvitationCode {
id String @id @default(cuid())
code String @unique
users User[]
createdAt DateTime @default(now())
}
enum AuthenticationMethod {
GITHUB
MAGIC_LINK
}
/// Used to generate PersonalAccessTokens, they're one-time use
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
}
// Used by User's to perform API actions
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])
userId String
revokedAt DateTime?
lastAccessedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
authorizationCodes AuthorizationCode[]
}
model Organization {
id String @id @default(cuid())
slug String @unique
title String
maximumExecutionTimePerRunInMs Int @default(900000) // 15 minutes
maximumConcurrencyLimit Int @default(10)
/// This is deprecated and will be removed in the future
maximumSchedulesLimit Int @default(5)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
companySize String?
runsEnabled Boolean @default(true)
v3Enabled Boolean @default(false)
v2Enabled Boolean @default(false)
v2MarqsEnabled Boolean @default(false)
hasRequestedV3 Boolean @default(false)
environments RuntimeEnvironment[]
connections IntegrationConnection[]
endpoints Endpoint[]
jobs Job[]
jobVersions JobVersion[]
events EventRecord[]
jobRuns JobRun[]
projects Project[]
members OrgMember[]
invites OrgMemberInvite[]
externalAccounts ExternalAccount[]
integrations Integration[]
sources TriggerSource[]
organizationIntegrations OrganizationIntegration[]
}
model ExternalAccount {
id String @id @default(cuid())
identifier String
metadata Json?
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
connections IntegrationConnection[]
events EventRecord[]
runs JobRun[]
schedules ScheduleSource[]
triggerSources TriggerSource[]
missingConnections MissingConnection[]
EventDispatcher EventDispatcher[]
@@unique([environmentId, identifier])
}
// This is a "global" table that store all the integration methods for all the integrations across all orgs
model IntegrationAuthMethod {
id String @id @default(cuid())
key String
name String
description String
type String
client Json?
config Json?
scopes Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
integrations Integration[]
definition IntegrationDefinition @relation(fields: [definitionId], references: [id], onDelete: Cascade, onUpdate: Cascade)
definitionId String
help Json?
@@unique([definitionId, key])
}
model IntegrationDefinition {
id String @id
name String
instructions String?
description String?
icon String?
packageName String @default("")
authMethods IntegrationAuthMethod[]
Integration Integration[]
}
model Integration {
id String @id @default(cuid())
slug String
title String?
description String?
setupStatus IntegrationSetupStatus @default(COMPLETE)
authSource IntegrationAuthSource @default(HOSTED)
definition IntegrationDefinition @relation(fields: [definitionId], references: [id], onDelete: Cascade, onUpdate: Cascade)
definitionId String
authMethod IntegrationAuthMethod? @relation(fields: [authMethodId], references: [id], onDelete: Cascade, onUpdate: Cascade)
authMethodId String?
connectionType ConnectionType @default(DEVELOPER)
scopes String[]
customClientReference SecretReference? @relation(fields: [customClientReferenceId], references: [id], onDelete: Cascade, onUpdate: Cascade)
customClientReferenceId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
attempts ConnectionAttempt[]
connections IntegrationConnection[]
jobIntegrations JobIntegration[]
sources TriggerSource[]
webhooks Webhook[]
missingConnections MissingConnection[]
RunConnection RunConnection[]
@@unique([organizationId, slug])
}
enum IntegrationAuthSource {
HOSTED
LOCAL
RESOLVER
}
enum IntegrationSetupStatus {
MISSING_FIELDS
COMPLETE
}
model IntegrationConnection {
id String @id @default(cuid())
connectionType ConnectionType @default(DEVELOPER)
expiresAt DateTime?
metadata Json
scopes String[]
dataReference SecretReference @relation(fields: [dataReferenceId], references: [id], onDelete: Cascade, onUpdate: Cascade)
dataReferenceId String
integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
integrationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
externalAccount ExternalAccount? @relation(fields: [externalAccountId], references: [id], onDelete: Cascade, onUpdate: Cascade)
externalAccountId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
/// If enabled is false, OAuth refreshing will not be attempted
enabled Boolean @default(true)
runConnections RunConnection[]
}
enum ConnectionType {
EXTERNAL
DEVELOPER
}
model ConnectionAttempt {
id String @id @default(cuid())
securityCode String?
redirectTo String @default("/")
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
integration Integration @relation(fields: [integrationId], references: [id])
integrationId String
}
model OrgMember {
id String @id @default(cuid())
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
userId String
role OrgMemberRole @default(MEMBER)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
environments RuntimeEnvironment[]
@@unique([organizationId, userId])
}
enum OrgMemberRole {
ADMIN
MEMBER
}
model OrgMemberInvite {
id String @id @default(cuid())
token String @unique @default(cuid())
email String
role OrgMemberRole @default(MEMBER)
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
inviter User @relation(fields: [inviterId], references: [id], onDelete: Cascade, onUpdate: Cascade)
inviterId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([organizationId, email])
}
model RuntimeEnvironment {
id String @id @default(cuid())
slug String
apiKey String @unique
pkApiKey String @unique
type RuntimeEnvironmentType @default(DEVELOPMENT)
///A memorable code for the environment
shortcode String
maximumConcurrencyLimit Int @default(5)
autoEnableInternalSources Boolean @default(true)
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
//when the org member is deleted, it will keep the environment but set it to null
orgMember OrgMember? @relation(fields: [orgMemberId], references: [id], onDelete: SetNull, onUpdate: Cascade)
orgMemberId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tunnelId String?
endpoints Endpoint[]
jobVersions JobVersion[]
events EventRecord[]
jobRuns JobRun[]
requestDeliveries HttpSourceRequestDelivery[]
jobAliases JobAlias[]
JobQueue JobQueue[]
sources TriggerSource[]
eventDispatchers EventDispatcher[]
scheduleSources ScheduleSource[]
ExternalAccount ExternalAccount[]
httpEndpointEnvironments TriggerHttpEndpointEnvironment[]
concurrencyLimitGroups ConcurrencyLimitGroup[]
keyValueItems KeyValueItem[]
webhookEnvironments WebhookEnvironment[]
webhookRequestDeliveries WebhookRequestDelivery[]
backgroundWorkers BackgroundWorker[]
backgroundWorkerTasks BackgroundWorkerTask[]
taskRuns TaskRun[]
taskQueues TaskQueue[]
batchTaskRuns BatchTaskRun[]
environmentVariableValues EnvironmentVariableValue[]
checkpoints Checkpoint[]
workerDeployments WorkerDeployment[]
workerDeploymentPromotions WorkerDeploymentPromotion[]
taskRunAttempts TaskRunAttempt[]
CheckpointRestoreEvent CheckpointRestoreEvent[]
taskScheduleInstances TaskScheduleInstance[]
alerts ProjectAlert[]
sessions RuntimeEnvironmentSession[]
currentSession RuntimeEnvironmentSession? @relation("currentSession", fields: [currentSessionId], references: [id], onDelete: SetNull, onUpdate: Cascade)
currentSessionId String?
taskRunNumberCounter TaskRunNumberCounter[]
@@unique([projectId, slug, orgMemberId])
@@unique([projectId, shortcode])
}
enum RuntimeEnvironmentType {
PRODUCTION
STAGING
DEVELOPMENT
PREVIEW
}
model Project {
id String @id @default(cuid())
slug String @unique
name String
externalRef String @unique
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
version ProjectVersion @default(V2)
environments RuntimeEnvironment[]
endpoints Endpoint[]
jobs Job[]
jobVersion JobVersion[]
events EventRecord[]
runs JobRun[]
sources TriggerSource[]
httpEndpoints TriggerHttpEndpoint[]
webhooks Webhook[]
backgroundWorkers BackgroundWorker[]
backgroundWorkerTasks BackgroundWorkerTask[]
taskRuns TaskRun[]
runTags TaskRunTag[]
taskQueues TaskQueue[]
environmentVariables EnvironmentVariable[]
checkpoints Checkpoint[]
WorkerDeployment WorkerDeployment[]
CheckpointRestoreEvent CheckpointRestoreEvent[]
taskSchedules TaskSchedule[]
alertChannels ProjectAlertChannel[]
alerts ProjectAlert[]
alertStorages ProjectAlertStorage[]
bulkActionGroups BulkActionGroup[]
BackgroundWorkerFile BackgroundWorkerFile[]
}
enum ProjectVersion {
V2
V3
}
model Endpoint {
id String @id @default(cuid())
slug String
url String?
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
indexingHookIdentifier String?
version String @default("unknown")
sdkVersion String @default("unknown")
runChunkExecutionLimit Int @default(60000)
startTaskThreshold Int @default(750)
beforeExecuteTaskThreshold Int @default(1500)
beforeCompleteTaskThreshold Int @default(750)
afterCompleteTaskThreshold Int @default(750)
jobVersions JobVersion[]
jobRuns JobRun[]
httpRequestDeliveries HttpSourceRequestDelivery[]
webhookRequestDeliveries WebhookRequestDelivery[]
dynamictriggers DynamicTrigger[]
sources TriggerSource[]
indexings EndpointIndex[]
httpEndpointEnvironments TriggerHttpEndpointEnvironment[]
webhookEnvironments WebhookEnvironment[]
@@unique([environmentId, slug])
}
model EndpointIndex {
id String @id @default(cuid())
endpoint Endpoint @relation(fields: [endpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
endpointId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
source EndpointIndexSource @default(MANUAL)
sourceData Json?
reason String?
status EndpointIndexStatus @default(PENDING)
data Json?
stats Json?
error Json?
}
enum EndpointIndexSource {
MANUAL
API
INTERNAL
HOOK
}
enum EndpointIndexStatus {
PENDING
STARTED
SUCCESS
FAILURE
}
model Job {
id String @id @default(cuid())
slug String
title String
internal Boolean @default(false)
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
versions JobVersion[]
runs JobRun[]
integrations JobIntegration[]
aliases JobAlias[]
dynamicTriggers DynamicTrigger[]
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
@@unique([projectId, slug])
}
model JobVersion {
id String @id @default(cuid())
version String
eventSpecification Json
properties Json?
triggerLink String?
triggerHelp Json?
job Job @relation(fields: [jobId], references: [id], onDelete: Cascade, onUpdate: Cascade)
jobId String
endpoint Endpoint @relation(fields: [endpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
endpointId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
queue JobQueue? @relation(fields: [queueId], references: [id])
queueId String?
startPosition JobStartPosition @default(INITIAL)
preprocessRuns Boolean @default(false)
concurrencyLimit Int?
concurrencyLimitGroup ConcurrencyLimitGroup? @relation(fields: [concurrencyLimitGroupId], references: [id])
concurrencyLimitGroupId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
runs JobRun[]
integrations JobIntegration[]
aliases JobAlias[]
examples EventExample[]
dynamicTriggers DynamicTrigger[]
triggerSources TriggerSource[]
status JobVersionStatus @default(ACTIVE)
@@unique([jobId, version, environmentId])
}
enum JobVersionStatus {
ACTIVE
DISABLED
}
model EventExample {
id String @id @default(cuid())
slug String
name String
icon String?
payload Json?
jobVersion JobVersion @relation(fields: [jobVersionId], references: [id], onDelete: Cascade, onUpdate: Cascade)
jobVersionId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([slug, jobVersionId])
}
model ConcurrencyLimitGroup {
id String @id @default(cuid())
name String
concurrencyLimit Int
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
jobVersion JobVersion[]
@@unique([environmentId, name])
}
model JobQueue {
id String @id @default(cuid())
name String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
jobCount Int @default(0)
maxJobs Int @default(100)
runs JobRun[]
jobVersion JobVersion[]
@@unique([environmentId, name])
}
model JobAlias {
id String @id @default(cuid())
name String @default("latest")
value String
version JobVersion @relation(fields: [versionId], references: [id], onDelete: Cascade, onUpdate: Cascade)
versionId String
job Job @relation(fields: [jobId], references: [id], onDelete: Cascade, onUpdate: Cascade)
jobId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
@@unique([jobId, environmentId, name])
}
model JobIntegration {
id String @id @default(cuid())
key String
version JobVersion @relation(fields: [versionId], references: [id], onDelete: Cascade, onUpdate: Cascade)
versionId String
job Job @relation(fields: [jobId], references: [id], onDelete: Cascade, onUpdate: Cascade)
jobId String
integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
integrationId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([versionId, key])
}
model RunConnection {
id String @id @default(cuid())
key String
authSource IntegrationAuthSource @default(HOSTED)
run JobRun @relation(fields: [runId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runId String
connection IntegrationConnection? @relation(fields: [connectionId], references: [id], onDelete: Cascade, onUpdate: Cascade)
connectionId String?
integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
integrationId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tasks Task[]
@@unique([runId, key])
}
model DynamicTrigger {
id String @id @default(cuid())
type DynamicTriggerType @default(EVENT)
slug String
endpoint Endpoint @relation(fields: [endpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
endpointId String
jobs Job[]
sources TriggerSource[]
scheduleSources ScheduleSource[]
registrations DynamicTriggerRegistration[]
sourceRegistrationJob JobVersion? @relation(fields: [sourceRegistrationJobId], references: [id], onDelete: Cascade, onUpdate: Cascade)
sourceRegistrationJobId String?
@@unique([endpointId, slug, type])
}
enum DynamicTriggerType {
EVENT
SCHEDULE
}
model EventDispatcher {
id String @id @default(cuid())
event String[]
source String
payloadFilter Json?
contextFilter Json?
manual Boolean @default(false)
dispatchableId String
dispatchable Json
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
enabled Boolean @default(true)
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
registrations DynamicTriggerRegistration[]
scheduleSources ScheduleSource[]
externalAccount ExternalAccount? @relation(fields: [externalAccountId], references: [id], onDelete: Cascade, onUpdate: Cascade)
externalAccountId String?
@@unique([dispatchableId, environmentId])
}
enum JobStartPosition {
INITIAL
LATEST
}
model EventRecord {
id String @id @default(cuid())
eventId String
name String
timestamp DateTime @default(now())
payload Json
payloadType PayloadType @default(JSON)
context Json?
sourceContext Json?
source String @default("trigger.dev")
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
externalAccount ExternalAccount? @relation(fields: [externalAccountId], references: [id], onDelete: Cascade, onUpdate: Cascade)
externalAccountId String?
httpEndpoint TriggerHttpEndpoint? @relation(fields: [httpEndpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
httpEndpointId String?
httpEndpointEnvironment TriggerHttpEndpointEnvironment? @relation(fields: [httpEndpointEnvironmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
httpEndpointEnvironmentId String?
deliverAt DateTime @default(now())
deliveredAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
cancelledAt DateTime?
isTest Boolean @default(false)
internal Boolean @default(false)
runs JobRun[]
@@unique([eventId, environmentId])
}
enum PayloadType {
JSON
REQUEST
}
model JobRun {
id String @id @default(cuid())
number Int?
internal Boolean @default(false)
job Job @relation(fields: [jobId], references: [id], onDelete: Cascade, onUpdate: Cascade)
jobId String
version JobVersion @relation(fields: [versionId], references: [id], onDelete: Cascade, onUpdate: Cascade)
versionId String
event EventRecord @relation(fields: [eventId], references: [id], onDelete: Cascade, onUpdate: Cascade)
eventId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
endpoint Endpoint @relation(fields: [endpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
endpointId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
queue JobQueue? @relation(fields: [queueId], references: [id])
queueId String?
externalAccount ExternalAccount? @relation(fields: [externalAccountId], references: [id], onDelete: Cascade, onUpdate: Cascade)
externalAccountId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
queuedAt DateTime?
startedAt DateTime?
completedAt DateTime?
properties Json?
status JobRunStatus @default(PENDING)
output Json?
timedOutAt DateTime?
timedOutReason String?
executionCount Int @default(0)
executionFailureCount Int @default(0)
executionDuration Int @default(0)
isTest Boolean @default(false)
preprocess Boolean @default(false)
yieldedExecutions String[]
forceYieldImmediately Boolean @default(false)
tasks Task[]
runConnections RunConnection[]
missingConnections MissingConnection[]
executions JobRunExecution[]
statuses JobRunStatusRecord[]
autoYieldExecution JobRunAutoYieldExecution[]
subscriptions JobRunSubscription[]
@@index([jobId, createdAt(sort: Desc)], map: "idx_jobrun_jobId_createdAt")
@@index([organizationId, createdAt], map: "idx_jobrun_organizationId_createdAt")
@@index([versionId], map: "idx_jobrun_versionId")
}
enum JobRunStatus {
PENDING
QUEUED
WAITING_ON_CONNECTIONS
PREPROCESSING
STARTED
EXECUTING
WAITING_TO_CONTINUE
WAITING_TO_EXECUTE
SUCCESS
FAILURE
TIMED_OUT
ABORTED
CANCELED
UNRESOLVED_AUTH
INVALID_PAYLOAD
}
model JobCounter {
jobId String @id
lastNumber Int @default(0)
}
model JobRunAutoYieldExecution {
id String @id @default(cuid())
run JobRun @relation(fields: [runId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runId String
timeRemaining Int
timeElapsed Int
limit Int
location String
createdAt DateTime @default(now())
}
model JobRunSubscription {
id String @id @default(cuid())
run JobRun @relation(fields: [runId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runId String
recipient String
recipientMethod JobRunSubscriptionRecipientMethod @default(WEBHOOK)
event JobRunSubscriptionEvents
status JobRunSubscriptionStatus @default(ACTIVE)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deliveredAt DateTime?
@@unique([runId, recipient, event])
}
enum JobRunSubscriptionRecipientMethod {
WEBHOOK
ENDPOINT
}
enum JobRunSubscriptionStatus {
ACTIVE
INACTIVE
}
enum JobRunSubscriptionEvents {
SUCCESS
FAILURE
}
model JobRunExecution {
id String @id @default(cuid())
run JobRun @relation(fields: [runId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runId String
retryCount Int @default(0)
retryLimit Int @default(0)
retryDelayInMs Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
startedAt DateTime?
completedAt DateTime?
error String?
reason JobRunExecutionReason @default(EXECUTE_JOB)
status JobRunExecutionStatus @default(PENDING)
resumeTask Task? @relation(fields: [resumeTaskId], references: [id], onDelete: SetNull, onUpdate: Cascade)
resumeTaskId String?
graphileJobId String?
isRetry Boolean @default(false)
}
enum JobRunExecutionReason {
PREPROCESS
EXECUTE_JOB
}
enum JobRunExecutionStatus {
PENDING
STARTED
SUCCESS
FAILURE
}
model Task {
id String @id
idempotencyKey String
displayKey String?
name String
icon String?
status TaskStatus @default(PENDING)
delayUntil DateTime?
noop Boolean @default(false)
description String?
properties Json?
outputProperties Json?
params Json?
output Json?
outputIsUndefined Boolean @default(false)
context Json?
error String?
redact Json?
style Json?
operation String?
callbackUrl String?
startedAt DateTime?
completedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
run JobRun @relation(fields: [runId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runId String
parent Task? @relation("TaskParent", fields: [parentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
parentId String?
runConnection RunConnection? @relation(fields: [runConnectionId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runConnectionId String?
children Task[] @relation("TaskParent")
childExecutionMode TaskChildExecutionMode @default(SEQUENTIAL)
executions JobRunExecution[]
attempts TaskAttempt[]
@@unique([runId, idempotencyKey])
@@index([parentId], map: "idx_task_parentId")
}
enum TaskStatus {
PENDING
WAITING
RUNNING
COMPLETED
ERRORED
CANCELED
}
enum TaskChildExecutionMode {
SEQUENTIAL
PARALLEL
}
model TaskAttempt {
id String @id @default(cuid())
number Int
task Task @relation(fields: [taskId], references: [id], onDelete: Cascade, onUpdate: Cascade)
taskId String
status TaskAttemptStatus @default(PENDING)
error String?
runAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([taskId, number])
}
enum TaskAttemptStatus {
PENDING
STARTED
COMPLETED
ERRORED
}
model JobRunStatusRecord {
id String @id @default(cuid())
key String
run JobRun @relation(fields: [runId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runId String
label String
state String?
data Json?
history Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([runId, key])
}
model SecretReference {
id String @id @default(cuid())
key String @unique
provider SecretStoreProvider @default(DATABASE)
connections IntegrationConnection[]
integrations Integration[]
triggerSources TriggerSource[]
httpEndpoints TriggerHttpEndpoint[]
environmentVariableValues EnvironmentVariableValue[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
OrganizationIntegration OrganizationIntegration[]
}
enum SecretStoreProvider {
DATABASE
AWS_PARAM_STORE
}
model SecretStore {
key String @unique
value Json
version String @default("1")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model TriggerSource {
id String @id @default(cuid())
key String
params Json?
channel TriggerChannel @default(HTTP)
channelData Json?
version String @default("1")
options TriggerSourceOption[]
metadata Json?
secretReference SecretReference @relation(fields: [secretReferenceId], references: [id], onDelete: Cascade, onUpdate: Cascade)
secretReferenceId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
endpoint Endpoint @relation(fields: [endpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
endpointId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
integrationId String
dynamicTrigger DynamicTrigger? @relation(fields: [dynamicTriggerId], references: [id], onDelete: Cascade, onUpdate: Cascade)
dynamicTriggerId String?
externalAccount ExternalAccount? @relation(fields: [externalAccountId], references: [id], onDelete: Cascade, onUpdate: Cascade)
externalAccountId String?
sourceRegistrationJob JobVersion? @relation(fields: [sourceRegistrationJobId], references: [id], onDelete: Cascade, onUpdate: Cascade)
sourceRegistrationJobId String?
dynamicSourceId String?
dynamicSourceMetadata Json?
active Boolean @default(false)
interactive Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
httpDeliveries HttpSourceRequestDelivery[]
registrations DynamicTriggerRegistration[]
@@unique([key, environmentId])
}
enum TriggerChannel {
HTTP
SQS
SMTP
}
model TriggerSourceOption {
id String @id @default(cuid())
name String
value String
source TriggerSource @relation(fields: [sourceId], references: [id], onDelete: Cascade, onUpdate: Cascade)
sourceId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
registered Boolean @default(false)
@@unique([name, value, sourceId])
}
model Webhook {
id String @id @default(cuid())
active Boolean @default(false)
key String
params Json?
webhookEnvironments WebhookEnvironment[]
requestDeliveries WebhookRequestDelivery[]
httpEndpoint TriggerHttpEndpoint @relation(fields: [httpEndpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
httpEndpointId String @unique
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
integrationId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([key, projectId])
}
model WebhookEnvironment {
id String @id @default(cuid())
active Boolean @default(false)
config Json?
desiredConfig Json?
requestDeliveries WebhookRequestDelivery[]
endpoint Endpoint @relation(fields: [endpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
endpointId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
webhook Webhook @relation(fields: [webhookId], references: [id], onDelete: Cascade, onUpdate: Cascade)
webhookId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([environmentId, webhookId])
}
model WebhookRequestDelivery {
id String @id @default(cuid())
number Int
url String
method String
headers Json
body Bytes?
verified Boolean @default(false)
error String?
webhook Webhook @relation(fields: [webhookId], references: [id], onDelete: Cascade, onUpdate: Cascade)
webhookId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
webhookEnvironment WebhookEnvironment @relation(fields: [webhookEnvironmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
webhookEnvironmentId String
endpoint Endpoint @relation(fields: [endpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
endpointId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deliveredAt DateTime?
}
model WebhookDeliveryCounter {
webhookId String @id
lastNumber Int @default(0)
}
model DynamicTriggerRegistration {
id String @id @default(cuid())
key String
dynamicTrigger DynamicTrigger @relation(fields: [dynamicTriggerId], references: [id], onDelete: Cascade, onUpdate: Cascade)
dynamicTriggerId String
eventDispatcher EventDispatcher @relation(fields: [eventDispatcherId], references: [id], onDelete: Cascade, onUpdate: Cascade)
eventDispatcherId String
source TriggerSource @relation(fields: [sourceId], references: [id], onDelete: Cascade, onUpdate: Cascade)
sourceId String
metadata Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([key, dynamicTriggerId])
}
model HttpSourceRequestDelivery {
id String @id @default(cuid())
url String
method String
headers Json
body Bytes?
source TriggerSource @relation(fields: [sourceId], references: [id], onDelete: Cascade, onUpdate: Cascade)
sourceId String
endpoint Endpoint @relation(fields: [endpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
endpointId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deliveredAt DateTime?
}
model ScheduleSource {
id String @id @default(cuid())
key String
schedule Json
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
dispatcher EventDispatcher @relation(fields: [dispatcherId], references: [id], onDelete: Cascade, onUpdate: Cascade)
dispatcherId String
lastEventTimestamp DateTime?
nextEventTimestamp DateTime?
workerJobId String?
active Boolean @default(false)
metadata Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
dynamicTrigger DynamicTrigger? @relation(fields: [dynamicTriggerId], references: [id], onDelete: Cascade, onUpdate: Cascade)
dynamicTriggerId String?
externalAccount ExternalAccount? @relation(fields: [externalAccountId], references: [id], onDelete: Cascade, onUpdate: Cascade)
externalAccountId String?
deferredEvent DeferredScheduledEventService?
@@unique([key, environmentId])
}
model TriggerHttpEndpoint {
id String @id @default(cuid())
key String
title String?
icon String?
properties Json?
webhook Webhook?
secretReference SecretReference @relation(fields: [secretReferenceId], references: [id], onDelete: Cascade, onUpdate: Cascade)
secretReferenceId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
httpEndpointEnvironments TriggerHttpEndpointEnvironment[]
eventRecords EventRecord[]
@@unique([key, projectId])
}
model TriggerHttpEndpointEnvironment {
id String @id @default(cuid())
active Boolean @default(false)
/// If this is set, requests will be tested against the filter and we'll call the user's server immediately
immediateResponseFilter Json?
skipTriggeringRuns Boolean @default(false)
source String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
endpoint Endpoint @relation(fields: [endpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
endpointId String
httpEndpoint TriggerHttpEndpoint @relation(fields: [httpEndpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
httpEndpointId String
eventRecords EventRecord[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([environmentId, httpEndpointId])
@@unique([endpointId, httpEndpointId])
}
model KeyValueItem {
id String @id @default(cuid())
key String
value Bytes
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([environmentId, key])
@@index([key], type: Hash)
}
model MissingConnection {
id String @id @default(cuid())
resolved Boolean @default(false)
runs JobRun[]
integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
integrationId String
connectionType ConnectionType @default(DEVELOPER)
externalAccount ExternalAccount? @relation(fields: [externalAccountId], references: [id], onDelete: Cascade, onUpdate: Cascade)
externalAccountId String?
accountIdentifier String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([integrationId, connectionType, externalAccountId])
@@unique([integrationId, connectionType, accountIdentifier])
}
model ApiIntegrationVote {
id String @id @default(cuid())
apiIdentifier String
user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
userId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([apiIdentifier, userId])
}
model DataMigration {
id String @id @default(cuid())
name String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
completedAt DateTime?
}
model DeferredScheduledEventService {
id String @id @default(cuid())
scheduleSource ScheduleSource @relation(fields: [scheduleSourceId], references: [id], onDelete: Cascade, onUpdate: Cascade)
scheduleSourceId String @unique
runAt DateTime
lastTimestamp DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// ====================================================
// v3 Models
// ====================================================
model BackgroundWorker {
id String @id @default(cuid())
friendlyId String @unique
contentHash String
sdkVersion String @default("unknown")
cliVersion String @default("unknown")
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
runtimeEnvironment RuntimeEnvironment @relation(fields: [runtimeEnvironmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runtimeEnvironmentId String
version String
metadata Json
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tasks BackgroundWorkerTask[]
attempts TaskRunAttempt[]
lockedRuns TaskRun[]
files BackgroundWorkerFile[]
deployment WorkerDeployment?
supportsLazyAttempts Boolean @default(false)
@@unique([projectId, runtimeEnvironmentId, version])
}
model BackgroundWorkerFile {
id String @id @default(cuid())
friendlyId String @unique
filePath String
contentHash String
contents Bytes
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
backgroundWorkers BackgroundWorker[]
tasks BackgroundWorkerTask[]
createdAt DateTime @default(now())
@@unique([projectId, contentHash])
}
model BackgroundWorkerTask {
id String @id @default(cuid())
slug String
friendlyId String @unique
filePath String
exportName String
worker BackgroundWorker @relation(fields: [workerId], references: [id], onDelete: Cascade, onUpdate: Cascade)
workerId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
file BackgroundWorkerFile? @relation(fields: [fileId], references: [id], onDelete: Cascade, onUpdate: Cascade)
fileId String?
runtimeEnvironment RuntimeEnvironment @relation(fields: [runtimeEnvironmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runtimeEnvironmentId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
attempts TaskRunAttempt[]
runs TaskRun[]
queueConfig Json?
retryConfig Json?
machineConfig Json?
triggerSource TaskTriggerSource @default(STANDARD)
@@unique([workerId, slug])
// Quick lookup of task identifiers
@@index([projectId, slug])
}
enum TaskTriggerSource {
STANDARD
SCHEDULED
}
model TaskRun {
id String @id @default(cuid())
number Int @default(0)
friendlyId String @unique
status TaskRunStatus @default(PENDING)
idempotencyKey String?
taskIdentifier String
isTest Boolean @default(false)
payload String
payloadType String @default("application/json")
context Json?
traceContext Json?
traceId String
spanId String
runtimeEnvironment RuntimeEnvironment @relation(fields: [runtimeEnvironmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runtimeEnvironmentId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
queue String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
attempts TaskRunAttempt[] @relation("attempts")
tags TaskRunTag[]
checkpoints Checkpoint[]
startedAt DateTime?
completedAt DateTime?
machinePreset String?
usageDurationMs Int @default(0)
costInCents Float @default(0)
baseCostInCents Float @default(0)
lockedAt DateTime?
lockedBy BackgroundWorkerTask? @relation(fields: [lockedById], references: [id])
lockedById String?
lockedToVersion BackgroundWorker? @relation(fields: [lockedToVersionId], references: [id])
lockedToVersionId String?
concurrencyKey String?
delayUntil DateTime?
queuedAt DateTime?
ttl String?
expiredAt DateTime?
maxAttempts Int?
batchItems BatchTaskRunItem[]
dependency TaskRunDependency?
CheckpointRestoreEvent CheckpointRestoreEvent[]
alerts ProjectAlert[]
scheduleInstance TaskScheduleInstance? @relation(fields: [scheduleInstanceId], references: [id], onDelete: SetNull)
scheduleInstanceId String?
schedule TaskSchedule? @relation(fields: [scheduleId], references: [id], onDelete: SetNull)
scheduleId String?
sourceBulkActionItems BulkActionItem[] @relation("SourceActionItemRun")
destinationBulkActionItems BulkActionItem[] @relation("DestinationActionItemRun")
logsDeletedAt DateTime?
@@unique([runtimeEnvironmentId, taskIdentifier, idempotencyKey])
// Task activity graph
@@index([projectId, createdAt, taskIdentifier])
//Runs list
@@index([projectId])
@@index([projectId, taskIdentifier])
@@index([projectId, status])
@@index([projectId, taskIdentifier, status])
//Schedules
@@index([scheduleId])
// Run page inspector
@@index([spanId])
// Finding completed runs
@@index([completedAt])
}
enum TaskRunStatus {
/// Task has been scheduled to run in the future
DELAYED
/// Task is waiting to be executed by a worker
PENDING
/// Task hasn't been deployed yet but is waiting to be executed
WAITING_FOR_DEPLOY
/// Task is currently being executed by a worker
EXECUTING
/// Task has been paused by the system, and will be resumed by the system
WAITING_TO_RESUME
/// Task has failed and is waiting to be retried
RETRYING_AFTER_FAILURE
/// Task has been paused by the user, and can be resumed by the user
PAUSED
/// Task has been canceled by the user
CANCELED
/// Task was interrupted during execution, mostly this happens in development environments
INTERRUPTED
/// Task has been completed successfully
COMPLETED_SUCCESSFULLY
/// Task has been completed with errors
COMPLETED_WITH_ERRORS
/// Task has failed to complete, due to an error in the system
SYSTEM_FAILURE
/// Task has crashed and won't be retried, most likely the worker ran out of resources, e.g. memory or storage
CRASHED
// Task reached the ttl without being executed
EXPIRED
}
model TaskRunTag {
id String @id @default(cuid())
name String
friendlyId String @unique
runs TaskRun[]
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
createdAt DateTime @default(now())
@@unique([projectId, name])
//Makes run filtering by tag faster
@@index([name, id])
}
model TaskRunDependency {
id String @id @default(cuid())
taskRun TaskRun @relation(fields: [taskRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
taskRunId String @unique
checkpointEvent CheckpointRestoreEvent? @relation(fields: [checkpointEventId], references: [id], onDelete: Cascade, onUpdate: Cascade)
checkpointEventId String? @unique
/// An attempt that is dependent on this task run.
dependentAttempt TaskRunAttempt? @relation(fields: [dependentAttemptId], references: [id])
dependentAttemptId String?
/// A batch run that is dependent on this task run
dependentBatchRun BatchTaskRun? @relation("dependentBatchRun", fields: [dependentBatchRunId], references: [id])
dependentBatchRunId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
/// deprecated, we hadn't included the project id in the unique constraint
model TaskRunCounter {
taskIdentifier String @id
lastNumber Int @default(0)
}
/// Used for the TaskRun number (e.g. #1,421)
model TaskRunNumberCounter {
id String @id @default(cuid())
taskIdentifier String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
lastNumber Int @default(0)
@@unique([taskIdentifier, environmentId])
}
model TaskRunAttempt {
id String @id @default(cuid())
number Int @default(0)
friendlyId String @unique
taskRun TaskRun @relation("attempts", fields: [taskRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
taskRunId String
backgroundWorker BackgroundWorker @relation(fields: [backgroundWorkerId], references: [id], onDelete: Cascade, onUpdate: Cascade)
backgroundWorkerId String
backgroundWorkerTask BackgroundWorkerTask @relation(fields: [backgroundWorkerTaskId], references: [id], onDelete: Cascade, onUpdate: Cascade)
backgroundWorkerTaskId String
runtimeEnvironment RuntimeEnvironment @relation(fields: [runtimeEnvironmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runtimeEnvironmentId String
queue TaskQueue @relation(fields: [queueId], references: [id], onDelete: Cascade, onUpdate: Cascade)
queueId String
status TaskRunAttemptStatus @default(PENDING)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
startedAt DateTime?
completedAt DateTime?
usageDurationMs Int @default(0)
error Json?
output String?
outputType String @default("application/json")
dependencies TaskRunDependency[]
batchDependencies BatchTaskRun[]
checkpoints Checkpoint[]
batchTaskRunItems BatchTaskRunItem[]
CheckpointRestoreEvent CheckpointRestoreEvent[]
alerts ProjectAlert[]
@@unique([taskRunId, number])
}
enum TaskRunAttemptStatus {
PENDING
EXECUTING
PAUSED
FAILED
CANCELED
COMPLETED
}
/// This is the unified otel span/log model that will eventually be replaced by clickhouse
model TaskEvent {
id String @id @default(cuid())
/// This matches the span name for a trace event, or the log body for a log event
message String
traceId String
spanId String
parentId String?
tracestate String?
isError Boolean @default(false)
isPartial Boolean @default(false)
isCancelled Boolean @default(false)
serviceName String
serviceNamespace String
level TaskEventLevel @default(TRACE)
kind TaskEventKind @default(INTERNAL)
status TaskEventStatus @default(UNSET)
links Json?
events Json?
/// This is the time the event started in nanoseconds since the epoch
startTime BigInt
/// This is the duration of the event in nanoseconds
duration BigInt @default(0)
attemptId String?
attemptNumber Int?
environmentId String
environmentType RuntimeEnvironmentType
organizationId String
projectId String
projectRef String
runId String
runIsTest Boolean @default(false)
idempotencyKey String?
taskSlug String
taskPath String?
taskExportName String?
workerId String?
workerVersion String?
queueId String?
queueName String?
batchId String?
/// This represents all the span attributes available, like http.status_code, and special attributes like $style.icon, $output, $metadata.payload.userId, as it's used for searching and filtering
properties Json
/// This represents all span attributes in the $metadata namespace, like $metadata.payload
metadata Json?
/// This represents all span attributes in the $style namespace, like $style
style Json?
/// This represents all span attributes in the $output namespace, like $output
output Json?
/// This represents the mimetype of the output, such as application/json or application/super+json
outputType String?
payload Json?
payloadType String?
createdAt DateTime @default(now())
// This represents the amount of "usage time" the event took, e.g. the CPU time
usageDurationMs Int @default(0)
usageCostInCents Float @default(0)
machinePreset String?
machinePresetCpu Float?
machinePresetMemory Float?
machinePresetCentsPerMs Float?
/// Used on the run page
@@index([traceId])
/// Used when looking up span events to complete when a run completes
@@index([spanId])
// Used for getting all logs for a run
@@index([runId])
}
enum TaskEventLevel {
TRACE
DEBUG
LOG
INFO
WARN
ERROR
}
enum TaskEventKind {
UNSPECIFIED
INTERNAL
SERVER
CLIENT
PRODUCER
CONSUMER
UNRECOGNIZED
LOG
}
enum TaskEventStatus {
UNSET
OK
ERROR
UNRECOGNIZED
}
model TaskQueue {
id String @id @default(cuid())
friendlyId String @unique
name String
type TaskQueueType @default(VIRTUAL)
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
runtimeEnvironment RuntimeEnvironment @relation(fields: [runtimeEnvironmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runtimeEnvironmentId String
concurrencyLimit Int?
rateLimit Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
attempts TaskRunAttempt[]
@@unique([runtimeEnvironmentId, name])
}
enum TaskQueueType {
VIRTUAL
NAMED
}
model BatchTaskRun {
id String @id @default(cuid())
friendlyId String @unique
status BatchTaskRunStatus @default(PENDING)
idempotencyKey String?
taskIdentifier String
checkpointEvent CheckpointRestoreEvent? @relation(fields: [checkpointEventId], references: [id], onDelete: Cascade, onUpdate: Cascade)
checkpointEventId String? @unique
runtimeEnvironment RuntimeEnvironment @relation(fields: [runtimeEnvironmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runtimeEnvironmentId String
dependentTaskAttempt TaskRunAttempt? @relation(fields: [dependentTaskAttemptId], references: [id], onDelete: Cascade, onUpdate: Cascade)
dependentTaskAttemptId String?
items BatchTaskRunItem[]
runDependencies TaskRunDependency[] @relation("dependentBatchRun")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([runtimeEnvironmentId, taskIdentifier, idempotencyKey])
}
enum BatchTaskRunStatus {
PENDING
COMPLETED
}
model BatchTaskRunItem {
id String @id @default(cuid())
status BatchTaskRunItemStatus @default(PENDING)
batchTaskRun BatchTaskRun @relation(fields: [batchTaskRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
batchTaskRunId String
taskRun TaskRun @relation(fields: [taskRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
taskRunId String
taskRunAttempt TaskRunAttempt? @relation(fields: [taskRunAttemptId], references: [id], onDelete: SetNull, onUpdate: Cascade)
taskRunAttemptId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([batchTaskRunId, taskRunId])
@@index([taskRunAttemptId], map: "idx_batchtaskrunitem_taskrunattempt")
@@index([taskRunId], map: "idx_batchtaskrunitem_taskrun")
}
enum BatchTaskRunItemStatus {
PENDING
FAILED
CANCELED
COMPLETED
}
model EnvironmentVariable {
id String @id @default(cuid())
friendlyId String @unique
key String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
values EnvironmentVariableValue[]
@@unique([projectId, key])
}
model EnvironmentVariableValue {
id String @id @default(cuid())
valueReference SecretReference? @relation(fields: [valueReferenceId], references: [id], onDelete: SetNull, onUpdate: Cascade)
valueReferenceId String?
variable EnvironmentVariable @relation(fields: [variableId], references: [id], onDelete: Cascade, onUpdate: Cascade)
variableId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([variableId, environmentId])
}
model Checkpoint {
id String @id @default(cuid())
friendlyId String @unique
type CheckpointType
location String
imageRef String
reason String?
metadata String?
events CheckpointRestoreEvent[]
run TaskRun @relation(fields: [runId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runId String
attempt TaskRunAttempt @relation(fields: [attemptId], references: [id], onDelete: Cascade, onUpdate: Cascade)
attemptId String
attemptNumber Int?
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
runtimeEnvironment RuntimeEnvironment @relation(fields: [runtimeEnvironmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runtimeEnvironmentId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum CheckpointType {
DOCKER
KUBERNETES
}
model CheckpointRestoreEvent {
id String @id @default(cuid())
type CheckpointRestoreEventType
reason String?
metadata String?
checkpoint Checkpoint @relation(fields: [checkpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
checkpointId String
run TaskRun @relation(fields: [runId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runId String
attempt TaskRunAttempt @relation(fields: [attemptId], references: [id], onDelete: Cascade, onUpdate: Cascade)
attemptId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
runtimeEnvironment RuntimeEnvironment @relation(fields: [runtimeEnvironmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
runtimeEnvironmentId String
taskRunDependency TaskRunDependency?
batchTaskRunDependency BatchTaskRun?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum CheckpointRestoreEventType {
CHECKPOINT
RESTORE
}
model WorkerDeployment {
id String @id @default(cuid())
contentHash String
friendlyId String @unique
shortCode String
version String
imageReference String?
externalBuildData Json?
status WorkerDeploymentStatus @default(PENDING)
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
worker BackgroundWorker? @relation(fields: [workerId], references: [id], onDelete: Cascade, onUpdate: Cascade)
workerId String? @unique
triggeredBy User? @relation(fields: [triggeredById], references: [id], onDelete: SetNull, onUpdate: Cascade)
triggeredById String?
builtAt DateTime?
deployedAt DateTime?
failedAt DateTime?
errorData Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
promotions WorkerDeploymentPromotion[]
alerts ProjectAlert[]
@@unique([projectId, shortCode])
@@unique([environmentId, version])
}
enum WorkerDeploymentStatus {
PENDING
/// This is the status when the image is being built
BUILDING
/// This is the status when the image is built and we are waiting for the indexing to finish
DEPLOYING
/// This is the status when the image is built and indexed, meaning we have everything we need to deploy
DEPLOYED
FAILED
CANCELED
/// This is the status when the image is built and indexing does not finish in time
TIMED_OUT
}
model WorkerDeploymentPromotion {
id String @id @default(cuid())
/// This is the promotion label, e.g. "current"
label String
deployment WorkerDeployment @relation(fields: [deploymentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
deploymentId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
// Only one promotion per environment can be active at a time
@@unique([environmentId, label])
}
///Schedules can be attached to tasks to trigger them on a schedule
model TaskSchedule {
id String @id @default(cuid())
type ScheduleType @default(IMPERATIVE)
///users see this as `id`. They start with schedule_
friendlyId String @unique
///a reference to a task (not a foreign key because it's across versions)
taskIdentifier String
///can be provided and we won't create another with the same key
deduplicationKey String @default(cuid())
userProvidedDeduplicationKey Boolean @default(false)
///the CRON pattern
generatorExpression String
generatorDescription String @default("")
generatorType ScheduleGeneratorType @default(CRON)
/// These are IANA format string, or the default "UTC". E.g. "America/New_York"
timezone String @default("UTC")
///Can be provided by the user then accessed inside a run
externalId String?
///Instances of the schedule that are active
instances TaskScheduleInstance[]
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
active Boolean @default(true)
runs TaskRun[]
@@unique([projectId, deduplicationKey])
}
enum ScheduleType {
/// defined on your task using the `cron` property
DECLARATIVE
/// explicit calls to the SDK are used to create, or using the dashboard
IMPERATIVE
}
enum ScheduleGeneratorType {
CRON
}
///An instance links a schedule with an environment
model TaskScheduleInstance {
id String @id @default(cuid())
taskSchedule TaskSchedule @relation(fields: [taskScheduleId], references: [id], onDelete: Cascade, onUpdate: Cascade)
taskScheduleId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
active Boolean @default(true)
lastScheduledTimestamp DateTime?
nextScheduledTimestamp DateTime?
runs TaskRun[]
//you can only have a schedule attached to each environment once
@@unique([taskScheduleId, environmentId])
}
model RuntimeEnvironmentSession {
id String @id @default(cuid())
ipAddress String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
disconnectedAt DateTime?
currentEnvironments RuntimeEnvironment[] @relation("currentSession")
}
model ProjectAlertChannel {
id String @id @default(cuid())
friendlyId String @unique
///can be provided and we won't create another with the same key
deduplicationKey String @default(cuid())
userProvidedDeduplicationKey Boolean @default(false)
integration OrganizationIntegration? @relation(fields: [integrationId], references: [id], onDelete: SetNull, onUpdate: Cascade)
integrationId String?
enabled Boolean @default(true)
type ProjectAlertChannelType
name String
properties Json
alertTypes ProjectAlertType[]
environmentTypes RuntimeEnvironmentType[] @default([STAGING, PRODUCTION])
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
alerts ProjectAlert[]
alertStorages ProjectAlertStorage[]
@@unique([projectId, deduplicationKey])
}
enum ProjectAlertChannelType {
EMAIL
SLACK
WEBHOOK
}
model ProjectAlert {
id String @id @default(cuid())
friendlyId String @unique
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
environment RuntimeEnvironment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
environmentId String
channel ProjectAlertChannel @relation(fields: [channelId], references: [id], onDelete: Cascade, onUpdate: Cascade)
channelId String
status ProjectAlertStatus @default(PENDING)
type ProjectAlertType
taskRunAttempt TaskRunAttempt? @relation(fields: [taskRunAttemptId], references: [id], onDelete: Cascade, onUpdate: Cascade)
taskRunAttemptId String?
taskRun TaskRun? @relation(fields: [taskRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
taskRunId String?
workerDeployment WorkerDeployment? @relation(fields: [workerDeploymentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
workerDeploymentId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum ProjectAlertType {
TASK_RUN
/// deprecated, we don't send new alerts for this type
TASK_RUN_ATTEMPT
DEPLOYMENT_FAILURE
DEPLOYMENT_SUCCESS
}
enum ProjectAlertStatus {
PENDING
SENT
FAILED
}
model ProjectAlertStorage {
id String @id @default(cuid())
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
alertChannel ProjectAlertChannel @relation(fields: [alertChannelId], references: [id], onDelete: Cascade, onUpdate: Cascade)
alertChannelId String
alertType ProjectAlertType
storageId String
storageData Json
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model OrganizationIntegration {
id String @id @default(cuid())
friendlyId String @unique
service IntegrationService
integrationData Json
tokenReference SecretReference @relation(fields: [tokenReferenceId], references: [id], onDelete: Cascade, onUpdate: Cascade)
tokenReferenceId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
organizationId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
alertChannels ProjectAlertChannel[]
}
enum IntegrationService {
SLACK
}
/// Bulk actions, like canceling and replaying runs
model BulkActionGroup {
id String @id @default(cuid())
friendlyId String @unique
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
projectId String
type BulkActionType
items BulkActionItem[]
/// When the group is created it's pending. After we've processed all the items it's completed. This does not mean the associated runs are completed.
status BulkActionStatus @default(PENDING)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum BulkActionType {
/// Cancels existing runs. This populates the destination runs.
CANCEL
/// Replays existing runs. The original runs go as source runs, and the new runs go as destination runs.
REPLAY
}
enum BulkActionStatus {
PENDING
COMPLETED
}
model BulkActionItem {
id String @id @default(cuid())
friendlyId String @unique
group BulkActionGroup @relation(fields: [groupId], references: [id], onDelete: Cascade, onUpdate: Cascade)
groupId String
type BulkActionType
/// When the item is created it's pending. After we've processed the item it's completed. This does not mean the associated runs are completed.
status BulkActionItemStatus @default(PENDING)
/// The run that is the source of the action, e.g. when replaying this is the original run
sourceRun TaskRun @relation("SourceActionItemRun", fields: [sourceRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
sourceRunId String
/// The run that's a result of the action, this will be set when the run has been created
destinationRun TaskRun? @relation("DestinationActionItemRun", fields: [destinationRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
destinationRunId String?
error String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum BulkActionItemStatus {
PENDING
COMPLETED
FAILED
}