mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-22 12:31:57 +02:00
Two tables behind running a catalog workflow on your own schedule. They are split because the keys differ: consent is one grant per (workflow, person), while one person may want several schedules for the same workflow. The subscription hangs off the grant by composite foreign key, so withdrawing consent takes the schedules with it. The scheduler side needed widening to hold them. A job was identified by `(workflowId, nodeId)`, which is what provisioning diffs and deprovisioning deletes by, and a per-person schedule has no node — several people hold their own schedules for the same workflow. `scheduled_job` gains a nullable, opaque `ownerId` that the scheduler only ever pairs with `taskType` and never interprets, so a feature can own jobs without the scheduler learning about the feature. An owner-scoped job deliberately records no `workflowId`: that column is a foreign key onto `workflow_published_version`, so it means "belongs to a published trigger", which these do not. The type makes passing one impossible. It also means nothing in the database removes these jobs when their owner goes, so callers must deprovision explicitly. The column is added with a raw `ALTER TABLE`: on SQLite the schema builder rebuilds the table, and `scheduled_task` cascades from it, so the rebuild would delete every queued occurrence on the instance. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4.1 KiB
4.1 KiB
workflow_credential_binding
Description
Table Definition
CREATE TABLE "workflow_credential_binding" ("workflowId" varchar(36) NOT NULL, "userId" varchar NOT NULL, "status" varchar(16) NOT NULL DEFAULT ('active'), "consentAt" datetime(3) NOT NULL, "createdAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "updatedAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), CONSTRAINT "CHK_workflow_credential_binding_status" CHECK ("status" IN ('active', 'revoked')), CONSTRAINT "FK_e537568aefaad06f226e06cffdd" FOREIGN KEY ("workflowId") REFERENCES "workflow_entity" ("id") ON DELETE CASCADE, CONSTRAINT "FK_cbd29dd8d24dbb7cce9e4abf1ee" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE, PRIMARY KEY ("workflowId", "userId"))
Columns
| Name | Type | Default | Nullable | Children | Parents | Comment |
|---|---|---|---|---|---|---|
| consentAt | datetime(3) | false | ||||
| createdAt | datetime(3) | STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW') | false | |||
| status | varchar(16) | 'active' | false | |||
| updatedAt | datetime(3) | STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW') | false | |||
| userId | varchar | false | workflow_subscription | user | ||
| workflowId | varchar(36) | false | workflow_subscription | workflow_entity |
Constraints
| Name | Type | Definition |
|---|---|---|
| - | CHECK | CHECK ("status" IN ('active', 'revoked')) |
| - (Foreign key ID: 0) | FOREIGN KEY | FOREIGN KEY (userId) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE |
| - (Foreign key ID: 1) | FOREIGN KEY | FOREIGN KEY (workflowId) REFERENCES workflow_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE |
| sqlite_autoindex_workflow_credential_binding_1 | PRIMARY KEY | PRIMARY KEY (workflowId, userId) |
| userId | PRIMARY KEY | PRIMARY KEY (userId) |
| workflowId | PRIMARY KEY | PRIMARY KEY (workflowId) |
Indexes
| Name | Definition |
|---|---|
| IDX_cbd29dd8d24dbb7cce9e4abf1e | CREATE INDEX "IDX_cbd29dd8d24dbb7cce9e4abf1e" ON "workflow_credential_binding" ("userId") |
| sqlite_autoindex_workflow_credential_binding_1 | PRIMARY KEY (workflowId, userId) |
Relations
erDiagram
"workflow_credential_binding" |o--|| "user" : "FOREIGN KEY (userId) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"workflow_subscription" }o--|| "workflow_credential_binding" : "FOREIGN KEY (workflowId, userId) REFERENCES workflow_credential_binding (workflowId, userId) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"workflow_credential_binding" |o--|| "workflow_entity" : "FOREIGN KEY (workflowId) REFERENCES workflow_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"workflow_credential_binding" {
datetime_3_ consentAt
datetime_3_ createdAt
varchar_16_ status
datetime_3_ updatedAt
varchar userId PK
varchar_36_ workflowId PK
}
"user" {
datetime_3_ createdAt
boolean disabled
varchar_255_ email
varchar_32_ firstName
varchar id PK
date lastActiveAt
varchar_32_ lastName
boolean mfaEnabled
TEXT mfaRecoveryCodes
TEXT mfaSecret
varchar password
TEXT personalizationAnswers
varchar_128_ roleSlug FK
TEXT settings
datetime_3_ updatedAt
}
"workflow_subscription" {
datetime_3_ createdAt
varchar_255_ cronExpression
boolean enabled
varchar_36_ id PK
TEXT inputs
varchar_255_ timezone
datetime_3_ updatedAt
varchar userId FK
varchar_36_ workflowId FK
}
"workflow_entity" {
boolean active
varchar_36_ activeVersionId FK
TEXT connections
datetime_3_ createdAt
TEXT description
varchar_36_ id PK
boolean isArchived
TEXT meta
varchar_128_ name
TEXT nodeGroups
TEXT nodes
varchar_36_ parentFolderId FK
TEXT pinData
TEXT settings
varchar sourceWorkflowId
TEXT staticData
INTEGER triggerCount
datetime_3_ updatedAt
INTEGER versionCounter
varchar_36_ versionId
}
Generated by tbls