Compare commits

..

No commits in common. "master" and "n8n@2.43.0" have entirely different histories.

6117 changed files with 70775 additions and 348565 deletions

View File

@ -14,8 +14,7 @@ Flag a diff that **adds** entries to any of these, and ask for the fix instead:
| `.code-health-baseline.json` | `@n8n/code-health` violations |
| `.boundaries-baseline.json` | `turbo boundaries` issue count |
| `packages/quality/testing/playwright/.janitor-baseline.json` | Playwright janitor findings |
| `.code-health-baseline.json` | the `typeorm-persistence-boundary` baseline, which only shrinks as business logic moves queries into repositories |
| `packages/cli/eslint.config.mjs` | the public-API allowlists captioned "NEVER add to this list" |
| `packages/cli/eslint.config.mjs` | the `misplaced-n8n-typeorm-import` and public-API allowlists, each captioned "NEVER add to this list" |
| `.code-health-baseline.json` (`lint-config-layering`) | package-wide rule downgrades left in package ESLint configs |
Removals are the healthy direction and need no comment.

View File

@ -659,12 +659,6 @@ nodes get LLM-generated pin data). So:
otherwise
accept the static-data red as a harness limit and carry the logic in
`outcomeExpectations`. Note the agent may *choose* static-data dedup on its own.
- **Message an Agent runs the called Agent with its real model.** The harness
mocks the Agent's tools, MCP servers and web search, and records those calls
under the calling node. It turns off the Agent's memory, vector stores and chat
integrations. Only OpenAI models are supported today, and only when
`EVAL_OPENAI_API_KEY` is set (CI sets it): put the Agent on an `openai/*` model
and declare an `openAiApi` credential.
- Don't assert exact counts that depend on mock generation ("exactly 7 posts").
Say "fewer than the original 10".

View File

@ -78,24 +78,11 @@ Creates GitHub PRs with titles that pass n8n's `check-pr-title` CI validation.
body structure, then populate each section with actual content before
creating the PR:
- **Summary**: describe what the PR does
- **Why**: explain why the change is needed (see Why below)
- **How to test**: describe how to test the changes. Include an example workflow if appropriate
- **Related tickets**: add the Linear ticket URL (`https://linear.app/n8n/issue/[TICKET-ID]`) and any GitHub issue links
- **Checklist**: keep as-is from the template
- Add a "🤖 PR Summary generated by AI" at the end of the body
Before you create the PR, proofread the body with these checks. Rewrite
each sentence that fails a check:
1. The Summary and the Why together are under the word budget. If not,
first remove the details that the reviewer reads in the diff, then
shorten the Why.
2. Each sentence names who does what: a component, a process, or a person
as the subject, with a plain technical verb.
3. Each domain term has a plain definition where it first appears.
4. Each sentence is true for the diff.
When a later commit changes a fact in the body, update the body.
```bash
gh pr create --draft --title "<type>(<scope>): <summary>" --body "$(cat <<'EOF'
<populated body based on pull_request_template.md>
@ -107,43 +94,12 @@ Creates GitHub PRs with titles that pass n8n's `check-pr-title` CI validation.
Based on `.github/pull_request_template.md`:
Write for a reviewer who does not know this area of the code. The reviewer
must understand the change before they open the diff. Use ASD-STE100
Simplified Technical English: short sentences, active voice.
1. Keep the Summary and the Why together under about 200 words. A small PR
needs much less.
2. Define each domain term in plain words where it first appears. Do not use
a ticket ID or an internal name as an explanation.
3. Leave out details that the reviewer reads in the diff: error cases, status
codes, renamed fields, the order of calls, file lists, test names. Mention
one only when it changes behaviour that a reviewer could miss. Also leave
out what reviewers already know (framework behaviour).
4. Use plain technical verbs, not metaphors ("passes the value", not
"hands the value" or "lets the value through").
Write the PR body in ASD-STE100 Simplified Technical English: use short
sentences, the active voice, and one instruction for each sentence.
### Summary: what the PR does
1. Start with one to three sentences of background for a reader who is new to
the area. Then state what the PR does.
2. Write **prose** about behaviour, not a list of code edits. Name a class or
a function when it represents an essential/core concept and it helps
the reader to navigate the change.
3. If the PR changes no product code, say so in the first sentence
(for example: "This PR only adds tests.").
4. Do not justify the change here. The justification goes in the Why.
5. Include screenshots or videos for UI changes.
### Why: the reasoning
Always fill the `## Why` section. The Summary and the core of the
Why are what the reviewer needs most. Keep the core short:
1. Do not repeat the Summary.
2. State the problem or the constraint that makes the pre-existing code unfit.
3. If there are accepted gaps, or changes for existing code paths, state them
in a separate short paragraph.
Add rejected alternatives only when a reviewer would otherwise ask about them,
if any. Use one or two sentences for each alternative: state the concrete
reason it fails. Write an alternative that was never built in the conditional.
Together, the alternatives must be shorter than the core Why section.
### Summary Section
- Describe what the PR does
- Include screenshots/videos for UI changes
### How to test Section
- Explain how to test the changes

View File

@ -110,7 +110,6 @@ Run through this before requesting review. Each item is a real, recurring review
- [ ] Identifiers go through **`escape.tableName(...)` / `escape.columnName(...)`**. Never hand-write `n8n_table` prefixes. — [Always escape identifiers](#always-escape-identifiers)
- [ ] **Match column type to value semantics.** Native `uuid` for UUIDs, `timestampTimezone()` for timestamps, a numeric type for numbers, `bool` for booleans, `json` for structured data. Never `varchar` as a catch-all. — [Column types](#column-types)
- [ ] **Pick the narrowest sane type within that category:** `int`/`smallint` not `bigint` when range allows; `text` not `varchar(255)` for unbounded strings; never `double` for version numbers. — [Column types](#column-types)
- [ ] **A generated `id` key is an integer** (`int.primary.autoGenerate2`). A UUID key is a UUIDv7. For a UUID or string key, write the reason in the PR description. A join table uses its foreign-key columns as the key, not an `id` column. — [Primary Keys](#primary-keys)
- [ ] **Default `notNull`**, relax only when justified. PK is implicitly NOT NULL. Migration's `notNull` matches the entity's nullability. — [NOT NULL and entity parity](#not-null-and-entity-parity)
- [ ] **Enum-like columns** carry `.withEnumCheck([...])` AND `.comment('explains values')`. Opaque IDs / unix timestamps / JSON shapes also get `.comment()`. — [Constrain enum-like strings](#constrain-enum-like-strings), [Add comments on columns](#add-comments-on-columns)
- [ ] **Every reference column has an explicit FK** with deliberate `onDelete`. Name FKs explicitly when SQLite recreate cycles risk duplicating them. Avoid polymorphic `(typeCol, idCol)` patterns. — [Foreign Key Constraints](#foreign-key-constraints), [General Design Guidance](#general-design-guidance)
@ -440,32 +439,11 @@ Don't set the default of a `status` column to a terminal value — `"running"` m
### Primary Keys
Every table needs a primary key. **Use an integer key by default.** Read the options below in order. Use the first option that fits. Do not skip an option only because you like a later one better.
Every table needs a primary key. Choose the type in this order:
1. **Integer (default)** — `column('id').int.primary.autoGenerate2`. Use this for every new table. Use a different option only when one of its conditions is true. Integer keys are small and make joins fast. `autoGenerate2` uses Postgres `IDENTITY`. Do not use `autoGenerate`. It uses `serial`, which is deprecated.
2. **UUID** — `column('id').uuid.primary`. Use this only when one of these conditions is true:
- The application must know the ID before the insert. For example, the client makes the ID.
- The ID is in a URL or a public API. Users must not see how many rows exist or guess other IDs.
**You must use UUIDv7.** Make the ID in application code with the `uuid` package: `import { v7 as uuidv7 } from 'uuid'`.
Why: a UUIDv7 starts with a timestamp. Thus, new rows go near the end of the index. A UUIDv4 is random, for example `randomUUID()` from `node:crypto`. New rows go to random positions in the index. This splits index pages and makes the index larger.
A UUIDv7 does not give an exact creation order. Two IDs made in the same millisecond can sort in the wrong order. Clock differences between hosts can also cause this. If you need the exact order, sort by a timestamp column.
Do **not** chain `.autoGenerate2` on `.uuid`. The DSL throws an error. The database default makes a UUIDv4. Also, `uuid_generate_v4()` needs the `uuid-ossp` extension. Some managed Postgres services, such as Supabase, do not have it. Use `.uuid`, not `.varchar(36)`.
3. **String** — `column('id').varchar(36).primary`. Use this only when one of these conditions is true:
- The entity already uses IDs in a format that is not a UUID. For example, the public API or the UI already shows nanoid IDs for this entity.
- The UI shows the ID to users. A UUID is too long to read, copy, or type.
Entity IDs are usually nanoids with 16 characters.
**Give a reason for every key that is not an integer.** Write the reason in the PR description. Reviewers will ask for it. These reasons are not sufficient:
- "Other tables use string IDs."
- "This module already does it this way."
- "We might need it later."
**These options apply to a generated `id` column only.** A join table that only links other tables does not need an `id` column. Use its foreign-key columns as a composite key (see below). A foreign-key column always has the same type as the key that it refers to.
1. **Integer** — `column('id').int.primary.autoGenerate2`. Preferred for new tables: compact, fast joins, no ordering surprises. `autoGenerate2` uses Postgres `IDENTITY` (preferred over the deprecated `serial`-based `autoGenerate`).
2. **UUID** — `column('id').uuid.primary`. Use when IDs are generated client-side, exposed in URLs, or need to be unguessable. Generate UUIDs in application code via `randomUUID()` from `node:crypto`; do **not** chain `.autoGenerate2` on `.uuid` (the DSL throws — `DEFAULT uuid_generate_v4()` fails on managed Postgres like Supabase because it needs the `uuid-ossp` extension in `public`). Use `.uuid` instead of `.varchar(36)`.
3. **String** — `column('id').varchar(36).primary` for IDs whose format isn't a UUID (e.g. nanoid-style IDs). Convention: nanoid length 16 for entity IDs.
**Keep ID-column types consistent across related tables.** Mixing `uuid` and `varchar(36)` for what is "the same kind of ID" creates JOIN footguns.
@ -718,7 +696,7 @@ If only Postgres needs the change, just put the file in `postgresdb/`; don't wri
### Postgres-version-aware UUID generation
`gen_random_uuid()` requires Postgres ≥ 13. n8n dropped Postgres 12 — prefer it over `uuid_generate_v4()` (which needs the `uuid-ossp` extension and breaks on managed services like Supabase). For UUID PKs, make a UUIDv7 in application code — see [Primary Keys](#primary-keys).
`gen_random_uuid()` requires Postgres ≥ 13. n8n dropped Postgres 12 — prefer it over `uuid_generate_v4()` (which needs the `uuid-ossp` extension and breaks on managed services like Supabase). For UUID PKs, generate at the application level with `randomUUID()` — see [Primary Keys](#primary-keys).
### SQLite doesn't enforce `varchar(N)` length

View File

@ -1,158 +0,0 @@
---
name: n8n:env-var-docs
description: >-
Writes and reviews the JSDoc on `@Env(...)` config properties. The docs team
extracts these comments from source into the public environment variable
reference, so they are user documentation, not code comments. Use when adding
or changing an `@Env` property, a config class, or reviewing a PR that touches
one.
---
# Environment variable docs
The JSDoc above every `@Env('...')` property is exported almost verbatim into
the [environment variables reference](https://docs.n8n.io/deploy/host-n8n/configure-n8n/basic-configuration/use-environment-variables)
on docs.n8n.io. The generated table has four columns: variable name,
description, data type, default. Your JSDoc is the description column. The
reader is a self-hosting operator, not an n8n developer.
Follow the [n8n docs style guide](https://docs.n8n.io/contribute/contribution-guide-for-n8n-docs/style-guide-for-n8n-docs)
for these comments. It overrides the ASD-STE100 rule in `AGENTS.md` for this
one case. The rules below are the parts of that guide that matter for a
one-paragraph description.
## Rules
- **Every `@Env` property has a JSDoc.** No exceptions. A missing comment
ships as an empty description cell.
- **Write for the operator.** Say what the setting does, when to change it,
and what happens when it's unset or wrong. Don't explain why the code is
written the way it is.
- **No code references.** No file names, class names, function names,
constants, license keys, or other internals the reader can't open. Values
the operator types into the variable are fine and often needed, for example
a credential type ID like `googleOAuth2Api` or a mode like `postgresdb`.
The test: would the operator paste this into a config file, or would they
need the source to know what it means? Details for developers go in a
regular `//` comment on the implementation, not in the JSDoc.
- **No attack scenarios.** Say what the setting protects, not how an
attacker would exploit it. This is a public page.
- **Don't repeat the default.** The default renders in its own column. Don't
write "Defaults to true" or "Default: 1 hour". Do say what the unset state
means when it's not obvious, for example "When unset, n8n uses the Redis
host".
- **State units and formats.** Say "in milliseconds", "in bytes", "a
comma-separated list", "a JSON object". The data type column only says
`Number` or `String`.
- **Use allowed values when the set is small.** "One of `sqlite`,
`postgresdb`." For a list, show one inline example in the sentence.
- **No JSDoc tags.** No `@example`, `@default`, `@see`, `@deprecated`. The
exporter copies the tag name into the docs. Put the example or the
deprecation notice in a sentence instead.
- **Product names:** "Gateway credits", not "n8n Connect" or "AI Gateway".
"Publish a workflow", not "activate". `n8n` is always lowercase.
- **Style:** present tense, active voice, second person. Use contractions.
No em dashes, use a comma or a new sentence. No "e.g." or "i.e.", write
"for example" and "that is". Spell out zero to nine, numerals from 10.
Values the operator types stay numerals, for example "Set to 0".
Sentence case. One idea per sentence. End every sentence with a period.
- **Plain words:** "use" not "utilize", "lets you" not "allows you to", cut
"powerful", "seamless", "simply", "it's important to note".
- **Length:** one to three sentences. If the setting needs more, the extra
belongs in a docs page the comment can't link to yet; keep the comment to
what fits a table cell.
## Examples
Bad, as found in the generated docs:
```ts
/**
* Instance-level enablement for n8n Connect (AI Gateway). Licensed instances
* are enabled by default; false opts out. Budget / free allowance still comes
* from the license (`quota:aiGatewayBudget`).
*/
```
Wrong product name, a restated default, and an internal license key. Good:
```ts
/**
* Whether Gateway credits are available on this instance. Set to false to
* turn them off on a licensed instance. The credit allowance comes from your
* license.
*/
```
Bad:
```ts
/**
* Time to live in milliseconds for Redis cache entries. Set to 0 to disable
* expiry. Default: 1 hour.
*/
```
The default is already in the table. Good:
```ts
/**
* Time to live in milliseconds for Redis cache entries. Set to 0 to keep
* entries until Redis evicts them.
*/
```
Bad:
```ts
/**
* Comma-separated list of credential types for which overwrites are skipped
* when the credential has been customized.
* @example `N8N_SKIP_CREDENTIAL_OVERWRITE=zohoOAuth2Api,salesforceOAuth2Api`
*/
```
The `@example` tag lands in the description as literal text. Good:
```ts
/**
* Comma-separated list of credential types to skip when applying credential
* overwrites, for example `zohoOAuth2Api,salesforceOAuth2Api`. n8n skips an
* overwrite only when a user has already changed one of its fields.
*/
```
Bad:
```ts
/**
* Bind OAuth credential callbacks to the browser that initiated the flow.
* When enabled, a session-scoped `n8n-oauth-binding` cookie is set on flow
* initiation and verified on callback. Defeats phishing attacks where an
* attacker injects an OAuth authorize URL into a victim's browser to land
* tokens on the attacker's credential.
*/
```
Attack narrative and an internal cookie name on a public page. Good:
```ts
/**
* Whether an OAuth credential connection must finish in the same browser
* that started it. When enabled, n8n rejects the callback if it arrives
* from a different browser.
*/
```
## Review checklist
When you review a PR that adds or changes an `@Env` property, check each
comment against this list and quote the fix in the review:
1. JSDoc present.
2. No code identifiers, file names, or internal keys.
3. No default restated.
4. Units, format, or allowed values stated.
5. No JSDoc tags.
6. No em dashes, Latin abbreviations, or filler words.
7. Reads correctly as a sentence in a table cell with no surrounding context.

View File

@ -21,7 +21,8 @@ check the code, not license to drop a team default.
## Non-negotiable rules
- New endpoints are `@PublicApiController` classes under `v1/controllers/`, one
`*.public.controller.ts` per feature.
`*.public.controller.ts` per feature. A controller is a class — never
`export =` (the legacy tuple style; `require-public-api-controller` flags it).
- Public API and internal REST are separate HTTP surfaces. A public controller
never calls an internal controller/endpoint; both reuse the same service.
- Controllers and handlers delegate to a service — never import a repository or
@ -30,6 +31,7 @@ check the code, not license to drop a team default.
`@ApiResponse(Dto)`.
- Register each controller via a side-effect import in `v1/controllers/index.ts`
(`public-api-controllers.test.ts` fails otherwise).
- Don't add business logic to legacy `express-openapi-validator` (EOV) handlers.
- Migrating a legacy endpoint must not change its public contract.
These are `n8n-local-rules` ESLint rules (see `packages/cli/eslint.config.mjs`)
@ -107,7 +109,7 @@ model; reuse only what applies. Decorators, all from `@n8n/decorators`:
| `@Get/@Post/@Put/@Patch/@Delete('/path')` | Route method. |
| `@ApiKeyScope('res:action')` | API-key grant check. |
| `@ProjectScope/@GlobalScope('res:action')` | User RBAC check. |
| `@ApiResponse(status)` / `@ApiResponse(status, Dto)` | Success status + (optional) output DTO; registry `.parse()`s + strips the return value. Exactly one per route — a second `@ApiResponse` throws. `204` can't carry a DTO or a binary body — throws. For a binary response body (returned as `{ body, headers? }`), use `@ApiResponse(status, { mediaType, description?, headers? })` — see [Binary response bodies](reference.md#binary-response-bodies). |
| `@ApiResponse(status)` / `@ApiResponse(status, Dto)` | Success status + (optional) output DTO; registry `.parse()`s + strips the return value. Exactly one per route — a second `@ApiResponse` throws. `204` can't carry a DTO — throws. |
| `@ApiErrorResponse(status)` | Declares an additional documented non-2xx status (e.g. `404`, `409`). Stack multiple for more than one. `400`/`401`/`403` are added automatically (body/query present, always, and `@ApiKeyScope` present, respectively) — don't declare those yourself. |
| `@ApiSummary(text)` / `@ApiDescription(text)` / `@ApiTags([...])` | OpenAPI summary/description/tags. `@ApiTags` sorts alphabetically regardless of the order you pass. All optional but expected on every real route. |
| `@Query` / `@Body` / `@Param('name')` | Bind + validate via a `Z.class` DTO / path param. `@Body` is JSON by default; `@Body({ mediaType: 'multipart/form-data', uploadLimits })` takes a `multipart/form-data` body instead — see [Request body media types](reference.md#request-body-media-types). |
@ -198,5 +200,6 @@ existing tests.
- [Test-before-save endpoints](reference.md#test-before-save-endpoints)
- [Errors](reference.md#errors)
- [Testing matrix](reference.md#testing-matrix)
- [Migrating legacy EOV endpoints](reference.md#migrating-legacy-eov-endpoints)
- [Verifying a migration](reference.md#verifying-a-migration)
- [CI and merging](reference.md#ci-and-merging)

View File

@ -122,10 +122,11 @@ app-wide `bodyParser` before the registry sees it. Declaring
- An unknown field (one the DTO doesn't declare, on a `{ strict: true }` DTO)
fails with `Unexpected form field "<name>"` — not the default "unrecognized
keys" wording.
- Multer parsing errors map to these statuses: `413` for a size or count limit,
`500` for `LIMIT_UNEXPECTED_FILE`, `400` for any other multer error, and `500`
for anything else (a malformed body). The `500` is not masked, because it is a
`ResponseError`. A missing boundary gives `400` with `multipart file(s) required`.
- Multer's own parsing errors map to the same statuses express-openapi-validator
used: `413` for a size/count limit, `400` for any other multer error, `500`
— unmasked, since this is a `ResponseError` — for anything else (a
malformed body; a missing boundary gives `400` with `multipart file(s)
required`).
- The body is parsed **after** every auth/scope/license/quota gate and
**before** controller/route middlewares — a caller those gates would reject
never has their (possibly huge) body read off the socket, and a middleware
@ -145,34 +146,57 @@ handler per media type (`REQUEST_BODY_HANDLERS` in
`REQUEST_BODY_HANDLERS` — the registry, resolver, generator and `/discover`
need no change, since they all read the handler, not the media type.
## Binary response bodies
## Migrating legacy EOV endpoints
`@ApiResponse(status, { mediaType, description?, headers? })` declares a
success body that the controller method returns as `{ body, headers? }`, for
example an `application/gzip` stream. The framework treats options whose
`mediaType` is in `BINARY_RESPONSE_MEDIA_TYPES` as a binary response.
`mediaType` accepts only those types.
Legacy `express-openapi-validator` endpoints live under
`v1/handlers/`, wired through `openapi.yml` with `x-eov-operation-*` and request
types in `packages/cli/src/public-api/types.ts`. Treat these as migration targets,
not templates.
- `body` is a `Buffer` or a `Readable`. The method returns the result and never
writes to `res`.
- `headers` holds the response headers. Every header declared in `headers` must
be in the result. A missing header fails the request with a `500`. Matching is
case-insensitive.
- The registry checks the headers, then sets the declared status, the headers,
and `Content-Type: <mediaType>`. A header in the result cannot replace the
`Content-Type`.
- A stream's first chunk is read before any header is set. So a stream that
fails before its first chunk gives the normal JSON error response, with no
binary `Content-Type`. A method that throws before it returns does the same.
- After the first chunk is sent, an error ends the response. A client that
disconnects is not an error, and the framework destroys the stream.
- A method that returns no binary body fails with a `500`.
- The generator documents the body as `{ type: string, format: binary }`
under the `mediaType` content key, with the description and headers.
The description defaults to `Operation successful.`.
The runtime part is `sendBinaryResponse` in
`packages/cli/src/public-api/media-types/binary-response.ts`.
- Prefer migrating to `@PublicApiController` over extending the handler.
- Preserve the public contract: path, method, scopes, status codes, response
shape, and pagination.
- Move HTTP concerns into the controller and business orchestration into the
shared service; keep the controller a thin HTTP boundary. If the legacy
handler was itself already just a thin wrapper around an internal
`@RestController` (calling its methods directly, e.g.
`Container.get(SomeController).createThing(req, res, payload)`), the new
public controller can call that same internal controller directly — no need
to duplicate its validation/business logic.
- A route must be served by either the EOV handler or a controller, not both —
the build's `mergeDecoratorDocument` (`v1/openapi-gen/generate.ts`) throws on
a path+method declared by both sides. Remove the legacy wiring (its path's
`$ref` entry in `openapi.yml`, the `x-eov-operation-*` handler, and its
`handler.ts`) only after the new controller is registered, `pnpm build`
regenerates the spec cleanly, and tests are updated.
- Fully delete the migrated legacy files: the handler's `.ts`, its
`spec/paths/*.yml` and `spec/schemas/*.yml`, and any now-dead request type
in `packages/cli/src/public-api/types.ts`. Then check
`v1/shared/spec/schemas/_index.yml` and `v1/shared/spec/parameters/_index.yml`
for entries that `$ref` one of the deleted schema/parameter files — those are
separate from the path's own `$ref` in `openapi.yml` and are easy to miss;
left dangling, the next bundle fails on a broken `$ref`.
- If the legacy handler gated on a license (`isLicensed('feat:x')` middleware),
`@Licensed('feat:x')` now replicates that for a controller route (see the
decorator table in [SKILL.md](SKILL.md#declaring-a-controller)) — but only for
a single feature. If the legacy check was an any-of/all-of over several flags
(e.g. `LicenseState.isProvisioningLicensed()`), `@Licensed` can't express
that; replicate it manually in the controller instead, don't drop it - this
is exactly what the internal `provisioning.controller.ee.ts` and
`role-mapping-rule.controller.ee.ts` already do, since neither uses
`@Licensed` for that reason.
- As a legacy file drops repository access / the `export =` tuple, remove its
entry from the `off` allowlists for `no-repository-in-public-api-handler` and
`require-public-api-controller` in `packages/cli/eslint.config.mjs` (shrink-only
— never extend them).
- A `multipart/form-data` legacy endpoint migrates onto `@Body({ mediaType:
'multipart/form-data', uploadLimits })` — see
[Request body media types](#request-body-media-types). For any other
non-standard endpoint, study the nearest existing handler first.
- Keep each field in its original position when you extract a request shape shared
by two routes, and destructure out the ones a route doesn't take. The generator
emits properties in shape order, so a moved field rewrites the `*.generated.yml`
of a route the PR wasn't changing.
## Verifying a migration

View File

@ -1 +0,0 @@
../../../../.agents/skills/env-var-docs

View File

@ -989,6 +989,14 @@
"hash": "26b2999a3856"
}
],
"packages/extensions/insights/oxlint.config.mts": [
{
"rule": "lint-config-layering",
"line": 9,
"message": "packages/extensions/insights turns 'typescript/no-deprecated' down to 'off' for the whole package.",
"hash": "f936bed8fa8d"
}
],
"packages/frontend/editor-ui/eslint.config.mjs": [
{
"rule": "lint-config-layering",
@ -1404,650 +1412,6 @@
"message": "Override \"langsmith\" duplicates a catalog entry for langsmith — set the override to \"catalog:\" or remove it",
"hash": "9ac3dbae3d22"
}
],
"packages/cli/src/binary-data/database.manager.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 2,
"message": "packages/cli imports the TypeORM re-export `In` from @n8n/db.",
"hash": "a4aeaccef8b6"
}
],
"packages/cli/src/credentials/credential-connection-status-provider.interface.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 1,
"message": "Business logic imports TypeORM directly.",
"hash": "4d287b55d52a"
}
],
"packages/cli/src/credentials/credential-connection-status-proxy.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 2,
"message": "Business logic imports TypeORM directly.",
"hash": "f425e2b10e7f"
}
],
"packages/cli/src/credentials/credential-dependency.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 8,
"message": "Business logic imports TypeORM directly.",
"hash": "abdb9e128ab8"
}
],
"packages/cli/src/credentials/credentials.controller.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 32,
"message": "Business logic imports TypeORM directly.",
"hash": "510cfb224f30"
}
],
"packages/cli/src/credentials/credentials.service.ee.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 12,
"message": "Business logic imports TypeORM directly.",
"hash": "f759a907bfa6"
}
],
"packages/cli/src/credentials/credentials.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 32,
"message": "Business logic imports TypeORM directly.",
"hash": "7f1b3146a6a5"
}
],
"packages/cli/src/executions/execution-persistence.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 7,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "9c7a73941bb9"
},
{
"rule": "typeorm-persistence-boundary",
"line": 10,
"message": "packages/cli imports the TypeORM re-export `FindManyOptions` from @n8n/db.",
"hash": "2beb2d36dbee"
},
{
"rule": "typeorm-persistence-boundary",
"line": 11,
"message": "packages/cli imports the TypeORM re-export `FindOptionsWhere` from @n8n/db.",
"hash": "ef8617dcfa5a"
},
{
"rule": "typeorm-persistence-boundary",
"line": 18,
"message": "packages/cli imports the TypeORM re-export `In` from @n8n/db.",
"hash": "be7b5858aa7c"
},
{
"rule": "typeorm-persistence-boundary",
"line": 18,
"message": "packages/cli imports the TypeORM re-export `Not` from @n8n/db.",
"hash": "5faea85ebf23"
}
],
"packages/cli/src/permissions.ee/check-access.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 2,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "ffa998a4f0e7"
}
],
"packages/cli/src/scheduling/durable-job-provisioner.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 5,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "7341e70aa4d7"
},
{
"rule": "typeorm-persistence-boundary",
"line": 10,
"message": "packages/cli imports the TypeORM re-export `DataSource` from @n8n/db.",
"hash": "64f5ed0abb25"
}
],
"packages/cli/src/scheduling/durable-scheduler.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 4,
"message": "packages/cli imports the TypeORM re-export `DataSource` from @n8n/db.",
"hash": "aac4ac3f74d8"
}
],
"packages/cli/src/services/export.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 4,
"message": "Business logic imports TypeORM directly.",
"hash": "079882e3843e"
}
],
"packages/cli/src/services/folder.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 10,
"message": "Business logic imports TypeORM directly.",
"hash": "b71b84bbde01"
}
],
"packages/cli/src/services/hooks.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 15,
"message": "Business logic imports TypeORM directly.",
"hash": "112edc87061f"
}
],
"packages/cli/src/services/import.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 17,
"message": "Business logic imports TypeORM directly.",
"hash": "5f09782b0c0a"
}
],
"packages/cli/src/services/project.service.ee.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 33,
"message": "Business logic imports TypeORM directly.",
"hash": "5f5086c28a45"
}
],
"packages/cli/src/services/public-api-key.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 15,
"message": "Business logic imports TypeORM directly.",
"hash": "848bd2e47604"
}
],
"packages/cli/src/services/user.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 15,
"message": "packages/cli imports the TypeORM re-export `Not` from @n8n/db.",
"hash": "afb93b8300ff"
},
{
"rule": "typeorm-persistence-boundary",
"line": 16,
"message": "packages/cli imports the TypeORM re-export `In` from @n8n/db.",
"hash": "2fd9c6af03c1"
}
],
"packages/cli/src/workflows/workflow-creation.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 5,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "db8f5c7d285b"
}
],
"packages/cli/src/workflows/workflow-finder.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 11,
"message": "Business logic imports TypeORM directly.",
"hash": "81b365efba5a"
}
],
"packages/cli/src/workflows/workflow-validation.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 4,
"message": "Business logic imports TypeORM directly.",
"hash": "fce2fb07a423"
}
],
"packages/cli/src/workflows/workflow.service.ee.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 22,
"message": "Business logic imports TypeORM directly.",
"hash": "1e39cc245dd5"
}
],
"packages/cli/src/workflows/workflow.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 23,
"message": "Business logic imports TypeORM directly.",
"hash": "ba3b76242d76"
}
],
"packages/cli/src/workflows/workflows.controller.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 39,
"message": "Business logic imports TypeORM directly.",
"hash": "63742f55819c"
}
],
"packages/cli/src/commands/import/credentials.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 19,
"message": "Business logic imports TypeORM directly.",
"hash": "a5cc02a1d765"
}
],
"packages/cli/src/evaluation.ee/test-runner/test-runner.service.ee.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 17,
"message": "Business logic imports TypeORM directly.",
"hash": "d34dbe0bf9e7"
}
],
"packages/cli/src/events/relays/telemetry.event-relay.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 8,
"message": "packages/cli imports the TypeORM re-export `In` from @n8n/db.",
"hash": "d8a744f2e2b8"
}
],
"packages/cli/src/executions/execution-data/db-store.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 1,
"message": "packages/cli imports the TypeORM re-export `In` from @n8n/db.",
"hash": "c19615f89980"
},
{
"rule": "typeorm-persistence-boundary",
"line": 2,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "47398e9fd892"
}
],
"packages/cli/src/instance-settings-loader/loaders/log-streaming.instance-settings-loader.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 3,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "b6baaab2dc92"
}
],
"packages/cli/src/modules/agents/agent-publish.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 15,
"message": "Business logic imports TypeORM directly.",
"hash": "9857b27c5bb1"
}
],
"packages/cli/src/modules/agents/agent-task.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 8,
"message": "Business logic imports TypeORM directly.",
"hash": "1799d75327d9"
}
],
"packages/cli/src/modules/agents/agents.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 18,
"message": "packages/cli imports the TypeORM re-export `In` from @n8n/db.",
"hash": "e893390cf6b7"
}
],
"packages/cli/src/modules/agents/instance-ai-builder-delegate.adapter.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 13,
"message": "Business logic imports TypeORM directly.",
"hash": "a2f27310e801"
}
],
"packages/cli/src/modules/breaking-changes/breaking-changes.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 12,
"message": "Business logic imports TypeORM directly.",
"hash": "680ac8daac26"
}
],
"packages/cli/src/modules/chat-hub/chat-hub-agent.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 10,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "0aef6c89993c"
}
],
"packages/cli/src/modules/chat-hub/chat-hub-credentials.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 8,
"message": "Business logic imports TypeORM directly.",
"hash": "6125ed3d7f9b"
}
],
"packages/cli/src/modules/chat-hub/chat-hub-title.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 11,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "57eab6d29eed"
}
],
"packages/cli/src/modules/chat-hub/chat-hub-tool.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 7,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "7069ba20f7cd"
}
],
"packages/cli/src/modules/chat-hub/chat-hub-workflow.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 25,
"message": "Business logic imports TypeORM directly.",
"hash": "7305b701b234"
}
],
"packages/cli/src/modules/chat-hub/chat-hub.attachment.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 3,
"message": "Business logic imports TypeORM directly.",
"hash": "07380799ff46"
}
],
"packages/cli/src/modules/chat-hub/chat-hub.models.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 10,
"message": "packages/cli imports the TypeORM re-export `In` from @n8n/db.",
"hash": "830f87d4b9eb"
}
],
"packages/cli/src/modules/chat-hub/chat-hub.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 17,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "55126ad50e59"
}
],
"packages/cli/src/modules/chat-hub/chat-hub.settings.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 11,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "ee4b7ca996c4"
}
],
"packages/cli/src/modules/data-table/data-table-ddl.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 3,
"message": "Business logic imports TypeORM directly.",
"hash": "9d6b2c45c02a"
}
],
"packages/cli/src/modules/data-table/data-table.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 18,
"message": "Business logic imports TypeORM directly.",
"hash": "b1aa220b40ab"
}
],
"packages/cli/src/modules/external-secrets.ee/secrets-providers-connections.service.ee.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 20,
"message": "Business logic imports TypeORM directly.",
"hash": "45167590d2e2"
}
],
"packages/cli/src/modules/favorites/favorites.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 12,
"message": "Business logic imports TypeORM directly.",
"hash": "03cdaa860f2a"
}
],
"packages/cli/src/modules/instance-ai/instance-ai.adapter.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 117,
"message": "Business logic imports TypeORM directly.",
"hash": "afbc7f6b5ec7"
}
],
"packages/cli/src/modules/instance-ai/suspended-thread-persistence.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 3,
"message": "Business logic imports TypeORM directly.",
"hash": "5f8f9db2966f"
}
],
"packages/cli/src/modules/log-streaming.ee/log-streaming-destination.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 5,
"message": "Business logic imports TypeORM directly.",
"hash": "f31366dabfeb"
}
],
"packages/cli/src/modules/mcp/mcp-api-key.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 3,
"message": "Business logic imports TypeORM directly.",
"hash": "c2cbaae08659"
}
],
"packages/cli/src/modules/mcp/mcp.settings.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 8,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "6ff9d5453466"
},
{
"rule": "typeorm-persistence-boundary",
"line": 11,
"message": "Business logic imports TypeORM directly.",
"hash": "4c5e31384fc0"
}
],
"packages/cli/src/modules/provisioning.ee/provisioning.service.ee.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 23,
"message": "Business logic imports TypeORM directly.",
"hash": "fd2fa9036a75"
}
],
"packages/cli/src/modules/provisioning.ee/role-mapping-rule.service.ee.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 16,
"message": "Business logic imports TypeORM directly.",
"hash": "d060301c09ad"
}
],
"packages/cli/src/modules/provisioning.ee/role-resolver.service.ee.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 4,
"message": "Business logic imports TypeORM directly.",
"hash": "15464f0f7a2a"
}
],
"packages/cli/src/modules/source-control.ee/source-control-context.factory.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 5,
"message": "Business logic imports TypeORM directly.",
"hash": "cbc873aadc22"
}
],
"packages/cli/src/modules/source-control.ee/source-control-export.service.ee.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 15,
"message": "Business logic imports TypeORM directly.",
"hash": "8e15c3127f0d"
}
],
"packages/cli/src/modules/source-control.ee/source-control-import.service.ee.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 4,
"message": "packages/cli imports the TypeORM re-export `FindOptionsWhere` from @n8n/db.",
"hash": "2ca6a59e5a14"
},
{
"rule": "typeorm-persistence-boundary",
"line": 29,
"message": "Business logic imports TypeORM directly.",
"hash": "e472973ab769"
}
],
"packages/cli/src/modules/source-control.ee/source-control-scoped.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 12,
"message": "Business logic imports TypeORM directly.",
"hash": "12e1f73d1d57"
}
],
"packages/cli/src/modules/source-control.ee/source-control-status.service.ee.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 7,
"message": "Business logic imports TypeORM directly.",
"hash": "627dc538505e"
}
],
"packages/cli/src/modules/workflow-index/workflow-dependency-query.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 17,
"message": "Business logic imports TypeORM directly.",
"hash": "27681e00a358"
}
],
"packages/cli/src/scheduling/poll-trigger-node/poll-trigger-job-registrar.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 4,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "faaf4ec6e197"
}
],
"packages/cli/src/scheduling/schedule-trigger-node/schedule-trigger-job-registrar.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 4,
"message": "packages/cli imports the TypeORM re-export `EntityManager` from @n8n/db.",
"hash": "795cfafd58f5"
}
],
"packages/cli/src/workflows/workflow-history/workflow-history.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 12,
"message": "Business logic imports TypeORM directly.",
"hash": "4405da700deb"
}
],
"packages/cli/src/modules/agents/integrations/n8n-memory.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 45,
"message": "Business logic imports TypeORM directly.",
"hash": "3f27e7921159"
}
],
"packages/cli/src/modules/data-table/utils/sql-utils.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 10,
"message": "Business logic imports TypeORM directly.",
"hash": "9780aefcf874"
}
],
"packages/cli/src/modules/dynamic-credentials.ee/services/credential-connection-status.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 4,
"message": "packages/cli imports the TypeORM re-export `In` from @n8n/db.",
"hash": "00c000824ff4"
},
{
"rule": "typeorm-persistence-boundary",
"line": 13,
"message": "Business logic imports TypeORM directly.",
"hash": "15940453447b"
}
],
"packages/cli/src/modules/dynamic-credentials.ee/services/credential-resolver-workflow.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 1,
"message": "packages/cli imports the TypeORM re-export `In` from @n8n/db.",
"hash": "e867f51e2b7c"
}
],
"packages/cli/src/modules/dynamic-credentials.ee/services/credential-resolver.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 10,
"message": "Business logic imports TypeORM directly.",
"hash": "9b6ffe4b90ce"
}
],
"packages/cli/src/modules/instance-ai/storage/typeorm-agent-checkpoint-store.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 3,
"message": "Business logic imports TypeORM directly.",
"hash": "5cac6e5f7c07"
}
],
"packages/cli/src/modules/instance-ai/storage/typeorm-agent-memory.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 30,
"message": "Business logic imports TypeORM directly.",
"hash": "eb011718641f"
}
],
"packages/cli/src/modules/instance-ai/storage/typeorm-observation-log-store.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 20,
"message": "Business logic imports TypeORM directly.",
"hash": "e45963a37c9c"
}
],
"packages/cli/src/modules/token-exchange/services/trusted-key.service.ts": [
{
"rule": "typeorm-persistence-boundary",
"line": 6,
"message": "Business logic imports TypeORM directly.",
"hash": "b44bfdcf5ae3"
}
]
}
}

View File

@ -85,7 +85,6 @@ return 'blacksmith';
| Accessibility buckets | `packages/quality/testing/playwright/reporters/a11y-reporter.ts` | Per-bucket axe score, violated rules, violating elements |
| Build stats | `.github/scripts/send-build-stats.mjs` | Per-package build duration, cache hit/miss, run total |
| Docker stats | `.github/scripts/send-docker-stats.mjs` | Image size per platform, docker build duration |
| Dive image efficiency | `packages/quality/efficiency/images/image-efficiency.spec.ts` | Layer content size, estimated waste, efficiency score, and layer count through the shared Playwright reporter |
| Container stack | `packages/quality/environments/containers/telemetry.ts` | E2E stack startup times per service |
## Secrets

32
.github/WORKFLOWS.md vendored
View File

@ -236,6 +236,14 @@ parallelism). See the `--build-via-mcp` section in
| PR merged to `release/*` | `release-publish.yml` |
| PR closed with `codespace-preview` | `util-codespace-preview.yml` |
### Manual Triggers (PR Comments)
| Command | Workflow | Permissions |
|--------------------|------------------------------|---------------------|
| `/test-workflows` | `test-workflows-callable.yml`| admin/write/maintain|
**Why:** Re-run tests without pushing commits. Useful for flaky test investigation.
### Label Triggers
| Label | Workflow | Effect |
@ -411,9 +419,7 @@ Run-workflow dropdown, which only a user with write access can pick.
|-----------------------------|---------------------------------------------------------|
| `util-codespace-preview.yml`| Wake, re-serve or delete a PR preview instance by hand |
| `util-data-tooling.yml` | SQLite/PostgreSQL export/import validation (manual) |
| `test-image-efficiency.yml` | Measure n8n and runners image size and layer waste with Dive |
| `util-probe-registry.yml` | Diagnose slow npm metadata fetches (temporary) |
| `sec-sync-bundle-branches.yml` | Sync both bundle branches on demand, including before a bundle cut |
---
@ -447,6 +453,10 @@ test-sbom-nightly.yml
test-workflows-nightly.yml (manual dispatch only — nightly schedule disabled, DEVP-544)
└──────────────────────────▶ test-workflows-callable.yml
PR Comment Dispatchers (triggered by /command in PR comments):
test-workflows-pr-comment.yml
└──────────────────────────▶ test-workflows-callable.yml
```
---
@ -587,7 +597,7 @@ Push to master
| Daily 03:00 | `sec-sync-bundle-branches.yml` | Merge the base into `bundle/*` |
| Daily 00:00 | `docker-build-push.yml` | Nightly Docker images |
| Daily 00:00 | `test-db.yml` | Database compatibility |
| Daily 00:00 | `test-e2e-performance-reusable.yml`| Browser performance and idle memory baselines |
| Daily 00:00 | `test-e2e-performance-reusable.yml`| Performance E2E |
| Daily 00:00 | `release-storybook.yml` | Storybook deploy |
| Daily 00:00 | `release-chromatic.yml` | Visual regression |
| Daily 00:00 | `util-check-docs-urls.yml` | Doc link validation |
@ -600,7 +610,6 @@ Push to master
| Daily 08:00 | `build-v3-nightly.yml` | Nightly v3 Docker images |
| Monday 00:00 | `util-update-node-popularity.yml` | Node usage stats |
| Monday 02:00 | `test-e2e-coverage-weekly.yml` | Weekly E2E coverage |
| Wednesday 04:00 | `util-update-get-n8n-versions.yml` | get-n8n stable versions |
| Saturday 22:00 | `test-evals-ai.yml` | AI workflow evals |
| 1st of month 04:00 | `util-refresh-cubic-schema.yml` | Refresh vendored cubic schema |
@ -1141,9 +1150,9 @@ open the PR there. That PR **must stay a single-parent squash** — the publish
posts to `#alerts-build` when that gate fails on a PR opened *from* `bundle/2.x` or
`bundle/1.x` (link only, no PR title, since the branch is embargoed).
`sec-sync-bundle-branches.yml` keeps those branches current nightly at 03:00 UTC and on
`workflow_dispatch`, including before a bundle cut. It **merges the public base into** the
bundle branch via
`sec-sync-bundle-branches.yml` keeps those branches current after every public-to-private sync,
daily, whenever a PR is merged into one, and on `workflow_dispatch`. It **merges the public
base into** the bundle branch via
[`scripts/sync-bundle-branch.mjs`](scripts/sync-bundle-branch.mjs) and pushes without forcing.
Every push is verified to carry exactly the tree a merge of the two sides would produce (`git
merge-tree`); a mismatch, or a conflict marker, fails the run instead of pushing.
@ -1156,8 +1165,7 @@ private-only until publication. The mirror can replace that commit with the publ
the bundle branch is deleted. The next bundle branch must not inherit the replaced commit.
Deleting a bundle branch takes its open PRs with it: GitHub moves each one onto the deleted
branch's own base, and re-creating the branch does not move them back. The next nightly or manual
sync re-creates the branch and then calls
branch's own base, and re-creating the branch does not move them back. So the sync then calls
[`sec-sync-retarget-prs.yml`](workflows/sec-sync-retarget-prs.yml), which moves every open PR
on `master` onto `bundle/2.x` and every one on `1.x` onto `bundle/1.x`. It skips a bundle
branch that does not exist, and skips PRs whose *head* is `bundle/*` — those are the
@ -1257,6 +1265,12 @@ Adding a new channel requires inviting the bot first; the first run otherwise fa
## Future Vision
### Redundancy Review
Comment trigger (`/test-workflows`) is a workaround.
Long-term: Main CI should be reliable enough to not need these.
### Workflow Testability
- Tools like `act` for local testing

View File

@ -58,15 +58,6 @@ describe('matchGlob', () => {
);
});
it('backend module pattern matches packaged module files', () => {
assert.ok(
matchGlob(
'packages/modules/insights/backend/src/insights.service.ts',
'packages/modules/*/backend/**',
),
);
});
it('* matches single-level only', () => {
assert.ok(matchGlob('README.md', '*.md'));
assert.ok(!matchGlob('docs/README.md', '*.md'));

View File

@ -1,15 +1,8 @@
## Summary
<!--
Start with 1 to 3 sentences of background for a new reader. Then describe what the PR does, in prose, not as a list of edits.
Add photos or videos for UI changes.
-->
## Why
<!--
State the problem or the constraint that makes the current code unfit. Do not repeat the Summary.
Add a rejected alternative only when a reviewer would ask about it, in one or two sentences.
Describe what the PR does.
Photos and videos are recommended.
-->
## How to test

View File

@ -747,8 +747,8 @@ packages:
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
fast-uri@3.1.8:
resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==}
fast-uri@3.1.5:
resolution: {integrity: sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==}
fd-package-json@2.0.0:
resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==}
@ -1694,7 +1694,7 @@ snapshots:
ajv@8.20.0:
dependencies:
fast-deep-equal: 3.1.3
fast-uri: 3.1.8
fast-uri: 3.1.5
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
@ -1994,7 +1994,7 @@ snapshots:
fast-deep-equal@3.1.3: {}
fast-uri@3.1.8: {}
fast-uri@3.1.5: {}
fd-package-json@2.0.0:
dependencies:

View File

@ -1,68 +0,0 @@
#!/usr/bin/env node
// Splits a jscpd JSON report's `duplicates` array into N bucket files so a
// caller can download and sample one small file instead of the whole report
// (which can run into tens of MB on a large monorepo). Round-robin, not
// contiguous chunks, so a run of similarly-sized clusters in scan order
// doesn't pile up in one bucket.
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
import { join } from 'node:path';
export function splitDuplicates(duplicates, bucketCount) {
const buckets = Array.from({ length: bucketCount }, () => []);
duplicates.forEach((dup, i) => buckets[i % bucketCount].push(dup));
return buckets;
}
export function writeBuckets(buckets, outputDir, deps = {}) {
const mkdirImpl = deps.mkdir ?? mkdirSync;
const writeImpl = deps.write ?? writeFileSync;
mkdirImpl(outputDir, { recursive: true });
return buckets.map((duplicates, i) => {
const path = join(outputDir, `bucket-${i}.json`);
writeImpl(path, JSON.stringify({ duplicates }));
return path;
});
}
export function parseBucketCount(raw) {
const count = Number(raw ?? 20);
if (!Number.isInteger(count) || count <= 0) {
throw new Error(`BUCKET_COUNT must be a positive integer, got '${raw}'`);
}
return count;
}
export function loadDuplicates(reportPath, deps = {}) {
const readImpl = deps.read ?? readFileSync;
const report = JSON.parse(readImpl(reportPath, 'utf8'));
if (!Array.isArray(report.duplicates)) {
throw new Error('report.duplicates must be an array');
}
return report.duplicates;
}
// Exits non-zero on any failure. The workflow step already runs with
// continue-on-error, so this can't fail the job — it only stops a broken
// split (zero buckets written) from reporting success.
function main() {
const reportPath = process.env.REPORT_PATH;
const outputDir = process.env.OUTPUT_DIR;
if (!reportPath || !outputDir) {
process.stderr.write('split-jscpd-report: REPORT_PATH and OUTPUT_DIR are required\n');
process.exit(1);
}
try {
const bucketCount = parseBucketCount(process.env.BUCKET_COUNT);
const duplicates = loadDuplicates(reportPath);
const buckets = splitDuplicates(duplicates, bucketCount);
writeBuckets(buckets, outputDir);
} catch (err) {
process.stderr.write(`split-jscpd-report: ${err.message}\n`);
process.exit(1);
}
}
if (import.meta.url === `file://${process.argv[1]}`) {
main();
}

View File

@ -1,111 +0,0 @@
/**
* Run these tests by running
*
* node --test .github/scripts/split-jscpd-report.test.mjs
* */
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { splitDuplicates, writeBuckets, parseBucketCount, loadDuplicates } from './split-jscpd-report.mjs';
describe('splitDuplicates', () => {
it('distributes entries round-robin across buckets', () => {
const duplicates = [1, 2, 3, 4, 5, 6];
const buckets = splitDuplicates(duplicates, 3);
assert.deepEqual(buckets, [
[1, 4],
[2, 5],
[3, 6],
]);
});
it('leaves later buckets empty when there are fewer entries than buckets', () => {
const buckets = splitDuplicates([1, 2], 5);
assert.equal(buckets.length, 5);
assert.deepEqual(buckets[0], [1]);
assert.deepEqual(buckets[1], [2]);
assert.deepEqual(buckets[2], []);
});
it('returns bucketCount empty arrays for an empty report', () => {
const buckets = splitDuplicates([], 4);
assert.deepEqual(buckets, [[], [], [], []]);
});
});
describe('writeBuckets', () => {
it('writes one JSON file per bucket, named by index', () => {
const written = [];
const paths = writeBuckets([[{ a: 1 }], [{ b: 2 }]], '/tmp/buckets', {
mkdir: () => {},
write: (path, contents) => written.push({ path, contents }),
});
assert.deepEqual(paths, ['/tmp/buckets/bucket-0.json', '/tmp/buckets/bucket-1.json']);
assert.deepEqual(JSON.parse(written[0].contents), { duplicates: [{ a: 1 }] });
assert.deepEqual(JSON.parse(written[1].contents), { duplicates: [{ b: 2 }] });
});
it('creates the output directory before writing', () => {
let mkdirCalledWith = null;
writeBuckets([[]], '/tmp/buckets', {
mkdir: (dir, opts) => {
mkdirCalledWith = { dir, opts };
},
write: () => {},
});
assert.deepEqual(mkdirCalledWith, { dir: '/tmp/buckets', opts: { recursive: true } });
});
});
describe('parseBucketCount', () => {
it('parses a numeric string', () => {
assert.equal(parseBucketCount('20'), 20);
});
it('defaults to 20 when unset', () => {
assert.equal(parseBucketCount(undefined), 20);
});
it('rejects zero', () => {
assert.throws(() => parseBucketCount('0'), /positive integer/);
});
it('rejects a negative count', () => {
assert.throws(() => parseBucketCount('-1'), /positive integer/);
});
it('rejects a non-integer', () => {
assert.throws(() => parseBucketCount('1.5'), /positive integer/);
});
it('rejects a non-numeric value', () => {
assert.throws(() => parseBucketCount('abc'), /positive integer/);
});
});
describe('loadDuplicates', () => {
it('returns the duplicates array from a valid report', () => {
const duplicates = loadDuplicates('/tmp/report.json', {
read: () => JSON.stringify({ duplicates: [{ a: 1 }] }),
});
assert.deepEqual(duplicates, [{ a: 1 }]);
});
it('rejects a report missing the duplicates array', () => {
assert.throws(
() => loadDuplicates('/tmp/report.json', { read: () => JSON.stringify({}) }),
/duplicates must be an array/,
);
});
it('rejects a report whose duplicates field is not an array', () => {
assert.throws(
() => loadDuplicates('/tmp/report.json', { read: () => JSON.stringify({ duplicates: 'x' }) }),
/duplicates must be an array/,
);
});
it('propagates a JSON parse failure', () => {
assert.throws(() => loadDuplicates('/tmp/report.json', { read: () => 'not json' }), SyntaxError);
});
});

File diff suppressed because one or more lines are too long

View File

@ -32,11 +32,11 @@ jobs:
# when updating.
include:
- node_version: '22'
dhi_ref: dhi.io/node:22.23.3-alpine3.24-dev@sha256:23ee07ace431ea7d14e22c0e52fb52b0bd1853dabdacd89ba75f937f6dff8a8d
- node_version: '24.21.0'
dhi_ref: dhi.io/node:24.21.0-alpine3.24-dev@sha256:d22ba0e9ab2a54609ae533df4ebfd6f36c1f233b662a4c547f5a3195e8c21937
- node_version: '26.10.0'
dhi_ref: dhi.io/node:26.10.0-alpine3.24-dev@sha256:8da859df5dc853c923ace53c4cfe994a909a28917f7fcfc8508869beab8cf132
dhi_ref: dhi.io/node:22.23.2-alpine3.24-dev@sha256:155a95d59244a71e9479e191ff718f03a7197d6829612e0707608be92988cb87
- node_version: '24.19.0'
dhi_ref: dhi.io/node:24.19.0-alpine3.24-dev@sha256:dc2989ad23938772abaf549ed7bde5d61d70377005229bb55bef94bff40f8bbd
- node_version: '26.7.0'
dhi_ref: dhi.io/node:26.7.0-alpine3.24-dev@sha256:4b494d89fb26c950ce97865acf45b480dc7a6868fdc2b81c2d66599702eeac3f
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

View File

@ -25,7 +25,7 @@ on:
type: boolean
env:
NODE_VERSION: '26.10.0'
NODE_VERSION: '26.7.0'
jobs:
build:

View File

@ -80,7 +80,6 @@ jobs:
!**/*.test.ts
!**/*.spec.ts
!packages/quality/testing/playwright/**
!packages/quality/efficiency/**
!packages/frontend/@n8n/storybook/**
!.devcontainer/**
!scripts/agent-setup.mjs
@ -147,17 +146,10 @@ jobs:
cubic.yaml
.agents/review-rules/**
e2e-performance:
packages/quality/efficiency/memory/idle/**
packages/quality/efficiency/playwright.config.ts
packages/quality/efficiency/package.json
packages/quality/testing/playwright/package.json
packages/quality/testing/playwright/quality-*.ts
packages/quality/testing/playwright/fixtures/**
packages/quality/testing/playwright/tests/performance/**
packages/quality/testing/playwright/utils/performance-helper.ts
packages/quality/environments/containers/**
.github/workflows/test-e2e-performance-reusable.yml
.github/workflows/test-e2e-reusable.yml
# Whole directories, not the `engine-*` files alone. Engine v2
# routing lives in ordinary control plane code: `workflow-runner.ts`
# and the webhook and trigger paths decide whether a run reaches the
@ -186,7 +178,6 @@ jobs:
packages/core/src/execution-engine/eval-mock-helpers.ts
.github/workflows/test-evals-discovery.yml
db:
packages/modules/*/backend/**
packages/cli/src/databases/**
packages/cli/src/modules/*/database/**
packages/cli/src/modules/**/*.entity.ts
@ -194,17 +185,16 @@ jobs:
packages/cli/test/integration/**
packages/cli/test/migration/**
packages/cli/test/shared/db/**
packages/cli/test/setup-testcontainers.ts
packages/cli/test/setup-testcontainers.js
packages/cli/test/teardown-testcontainers.js
packages/@n8n/db/**
packages/@n8n/backend-test-utils/**
packages/@n8n/scheduler/src/**
packages/cli/src/scheduling/**
packages/cli/src/**/*.integration.test.ts
packages/cli/src/modules/instance-registry/**
packages/cli/vitest.*
packages/quality/environments/containers/services/postgres.ts
packages/quality/environments/containers/services/redis.ts
packages/quality/environments/containers/test-db-global-setup.ts
packages/quality/environments/containers/postgres-versions.json
packages/quality/environments/containers/test-containers.ts
.github/workflows/test-db-reusable.yml
@ -219,7 +209,8 @@ jobs:
packages/@n8n/backend-test-utils/**
packages/cli/test/migration/**
packages/cli/test/shared/db/**
packages/cli/test/setup-testcontainers.ts
packages/cli/test/setup-testcontainers.js
packages/cli/test/teardown-testcontainers.js
packages/cli/vitest.config.base.ts
packages/cli/vitest.config.migration.ts
packages/cli/vitest.config.migration.testcontainers.ts

View File

@ -8,7 +8,7 @@ run-name: "${{ github.event_name == 'workflow_dispatch' && format('Docker: Build
env:
NODE_OPTIONS: '--max-old-space-size=7168'
NODE_VERSION: '26.10.0'
NODE_VERSION: '26.7.0'
on:
schedule:

View File

@ -12,7 +12,7 @@ env:
# The images copy native bindings from the host build, so both have to use the same
# Node. dockerize-n8n.mjs reads this env for the image builds. Keep in sync with
# NODE_VERSION in docker-build-push.yml, which is what the published images use.
NODE_VERSION: '26.10.0'
NODE_VERSION: '26.7.0'
# Also build the distroless runners image and exec-check
# both runners images' interpreters, so a broken runtime assembly (e.g. a
# missing shared library after a Node bump) fails at PR time. The smoke

View File

@ -19,7 +19,7 @@ on:
default: false
env:
NODE_VERSION: '26.10.0'
NODE_VERSION: '26.7.0'
SCRATCH_TAG: sbom-probe-${{ github.run_id }}
# A separate package. These are throwaway fixtures (one is a two-layer
# alpine), and ghcr.io/<repo> is where the real release tags live - they

View File

@ -1,309 +0,0 @@
# 🍝 jscpd — deterministic copy-paste/duplication scan.
#
# Runs jscpd against this repo and uploads the full JSON+HTML report, plus
# the report split into BUCKET_COUNT small JSON files, so a caller can
# download one small bucket at random per invocation instead of the full
# report (which can run into tens of MB on a monorepo this size).
#
# Reporters/ignores/threshold come from this repo's own .jscpd.json; this
# workflow passes none of those flags itself.
name: 🍝 jscpd
on:
workflow_dispatch:
permissions:
contents: read
env:
# Number of small sample files the report is split into (split-jscpd-report.mjs).
# Fixed, not an input: changing it means adding/removing the matching
# per-bucket upload steps below, so it's a code change, not a dispatch option.
BUCKET_COUNT: '20'
jobs:
jscpd:
runs-on: ${{ vars.RUNNER_PROVIDER == 'github' && 'ubuntu-latest' || 'blacksmith-4vcpu-ubuntu-2204' }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 1
persist-credentials: false
- name: Setup Node.js and install dependencies
uses: ./.github/actions/setup-nodejs
with:
build-command: ''
- name: Run jscpd
id: jscpd
continue-on-error: true
run: |
mkdir -p "$RUNNER_TEMP/jscpd-report"
pnpm jscpd -- . --output "$RUNNER_TEMP/jscpd-report" --silent
- name: Upload jscpd report
id: report-artifact
if: always()
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-report-${{ github.run_id }}-${{ github.run_attempt }}
path: ${{ runner.temp }}/jscpd-report
retention-days: 31
if-no-files-found: warn
# jscpd exits non-zero once duplication crosses .jscpd.json's threshold,
# but still writes the report first. Gating the split on the report
# file existing (not on steps.jscpd.outcome) means an over-threshold
# run still gets its buckets instead of silently dropping all of them.
- name: Check jscpd report exists
id: report-exists
if: always()
run: |
if [ -f "$RUNNER_TEMP/jscpd-report/jscpd-report.json" ]; then
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
# Splits `duplicates` into BUCKET_COUNT files so a caller can download
# one small sample instead of the full report (tens of MB on a large
# monorepo). Logic + tests live in split-jscpd-report.mjs.
- name: Split report into buckets
id: split
if: always() && steps.report-exists.outputs.exists == 'true'
continue-on-error: true
env:
REPORT_PATH: ${{ runner.temp }}/jscpd-report/jscpd-report.json
OUTPUT_DIR: ${{ runner.temp }}/jscpd-buckets
run: node .github/scripts/split-jscpd-report.mjs
# BUCKET_COUNT static upload steps, one per bucket file: GitHub Actions
# has no per-job step loop, and each bucket needs its own small
# artifact (not one artifact holding all of them) so a caller can
# fetch a single sample without pulling the rest. Keep this block's
# step count in sync with BUCKET_COUNT above.
- name: Upload jscpd bucket 0
id: bucket-artifact-0
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-0
path: ${{ runner.temp }}/jscpd-buckets/bucket-0.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 1
id: bucket-artifact-1
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-1
path: ${{ runner.temp }}/jscpd-buckets/bucket-1.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 2
id: bucket-artifact-2
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-2
path: ${{ runner.temp }}/jscpd-buckets/bucket-2.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 3
id: bucket-artifact-3
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-3
path: ${{ runner.temp }}/jscpd-buckets/bucket-3.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 4
id: bucket-artifact-4
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-4
path: ${{ runner.temp }}/jscpd-buckets/bucket-4.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 5
id: bucket-artifact-5
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-5
path: ${{ runner.temp }}/jscpd-buckets/bucket-5.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 6
id: bucket-artifact-6
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-6
path: ${{ runner.temp }}/jscpd-buckets/bucket-6.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 7
id: bucket-artifact-7
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-7
path: ${{ runner.temp }}/jscpd-buckets/bucket-7.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 8
id: bucket-artifact-8
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-8
path: ${{ runner.temp }}/jscpd-buckets/bucket-8.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 9
id: bucket-artifact-9
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-9
path: ${{ runner.temp }}/jscpd-buckets/bucket-9.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 10
id: bucket-artifact-10
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-10
path: ${{ runner.temp }}/jscpd-buckets/bucket-10.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 11
id: bucket-artifact-11
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-11
path: ${{ runner.temp }}/jscpd-buckets/bucket-11.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 12
id: bucket-artifact-12
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-12
path: ${{ runner.temp }}/jscpd-buckets/bucket-12.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 13
id: bucket-artifact-13
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-13
path: ${{ runner.temp }}/jscpd-buckets/bucket-13.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 14
id: bucket-artifact-14
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-14
path: ${{ runner.temp }}/jscpd-buckets/bucket-14.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 15
id: bucket-artifact-15
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-15
path: ${{ runner.temp }}/jscpd-buckets/bucket-15.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 16
id: bucket-artifact-16
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-16
path: ${{ runner.temp }}/jscpd-buckets/bucket-16.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 17
id: bucket-artifact-17
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-17
path: ${{ runner.temp }}/jscpd-buckets/bucket-17.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 18
id: bucket-artifact-18
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-18
path: ${{ runner.temp }}/jscpd-buckets/bucket-18.json
retention-days: 31
if-no-files-found: error
- name: Upload jscpd bucket 19
id: bucket-artifact-19
if: always() && steps.split.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: jscpd-bucket-${{ github.run_id }}-${{ github.run_attempt }}-19
path: ${{ runner.temp }}/jscpd-buckets/bucket-19.json
retention-days: 31
if-no-files-found: error

View File

@ -9,16 +9,6 @@ name: 'Prepare n8n Docker (reusable)'
on:
workflow_call:
secrets:
QA_METRICS_WEBHOOK_URL:
description: 'QA metrics webhook URL.'
required: false
QA_METRICS_WEBHOOK_USER:
description: 'QA metrics webhook username.'
required: false
QA_METRICS_WEBHOOK_PASSWORD:
description: 'QA metrics webhook password.'
required: false
inputs:
build-variant:
description: 'standard, coverage, or pc'

View File

@ -12,8 +12,8 @@
# Every push is verified to carry exactly the tree a merge would produce. See
# sync-bundle-branch.mjs.
#
# Runs nightly at 03:00 UTC. Maintainers can also dispatch it before a bundle cut or when a
# bundle branch needs to be synced sooner.
# The public-to-private mirror dispatches this workflow after each run. The daily schedule is a
# fallback, and merged fixes trigger it so the cut PR sees the latest bundle state immediately.
#
# One job per bundle branch: a conflict on one FAILS THAT JOB and leaves its branch untouched,
# while the other still syncs. Recovery is manual and deliberate — merge the public base locally,
@ -25,6 +25,11 @@ name: 'Security: Sync Bundle Branches'
on:
schedule:
- cron: '0 3 * * *'
pull_request: # a fix landing on a bundle branch is when freshness matters most
types: [closed]
branches:
- 'bundle/2.x'
- 'bundle/1.x'
workflow_dispatch:
# Least privilege by default; the sync job opts into exactly what it needs.
@ -33,7 +38,9 @@ permissions: {}
jobs:
sync:
name: Sync ${{ matrix.bundle }}
if: github.repository == 'n8n-io/n8n-private'
if: |
github.repository == 'n8n-io/n8n-private' &&
(github.event_name != 'pull_request' || github.event.pull_request.merged == true)
runs-on: ubuntu-latest
permissions:
contents: write
@ -61,12 +68,17 @@ jobs:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Always run the script from the default branch. The sync fetches both branches itself.
# Always run the script from the default branch, never from a pull_request merge
# ref — the sync holds a contents:write token and fetches what it needs itself,
# so the checked-out branch is irrelevant beyond supplying trusted code.
ref: master
fetch-depth: 0
persist-credentials: false # we push with an explicit token URL instead
- name: Merge the base into the bundle branch
# On a merged bundle PR, only the branch that received it needs syncing.
# (`matrix` is not available in a job-level `if`, so the filter lives here.)
if: github.event_name != 'pull_request' || github.event.pull_request.base.ref == matrix.bundle
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
BUNDLE_BRANCH: ${{ matrix.bundle }}

View File

@ -7,6 +7,9 @@
# Manual runs always sync (for conflict recovery after failed cherry-pick).
#
# A skipped branch or a hard failure is reported to #alerts-build.
#
# This workflow dispatches the bundle sync after each mirror run. Bundle branches merge the
# public branch directly, so they never inherit a private-only bundle cut.
name: 'Security: Sync from Public'
run-name: "${{ github.event_name == 'workflow_dispatch' && format('Security: Sync from Public (force={0})', inputs.force) || '' }}"
@ -27,6 +30,7 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
actions: write
steps:
- name: Generate App Token
@ -99,6 +103,13 @@ jobs:
git reset --hard public-1.x
git push origin 1.x --force-with-lease
- name: Dispatch bundle branch sync
if: ${{ !cancelled() }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh workflow run sec-sync-bundle-branches.yml --ref master
- name: Notify Slack on failure
if: failure()
env:

View File

@ -55,13 +55,6 @@ jobs:
working-directory: packages/cli
run: ${{ matrix.test-cmd }}
# A packaged backend module opts in by defining `test:postgres`.
- name: Run packaged backend module PostgreSQL tests
if: matrix.TEST_IMAGE_POSTGRES != ''
env:
COVERAGE_ENABLED: 'false'
run: pnpm --filter './packages/modules/*/backend' --if-present run test:postgres --maxWorkers=100%
# Regenerates the schema docs for this leg's database (sqlite temp file /
# postgres testcontainer) and fails if they differ from what's committed.
# tbls runs as a Docker image in CI.

View File

@ -1,8 +1,5 @@
name: 'Test: E2E Performance'
permissions:
contents: read
on:
workflow_call:
workflow_dispatch:
@ -27,17 +24,6 @@ jobs:
artifact-prefix: performance
secrets: inherit
idle-memory-baselines:
needs: [prepare-docker]
uses: ./.github/workflows/test-e2e-reusable.yml
with:
test-mode: docker-artifact
test-command: pnpm --filter=@n8n/efficiency test:memory
workers: '1'
currents-project-id: 'O9BJaN'
artifact-prefix: memory-performance
secrets: inherit
canvas-perf-sentinels:
name: Canvas Perf Sentinels
# Sentinels are nightly only — wall-clock browser perf has 15-30% variance,

View File

@ -195,10 +195,9 @@ jobs:
with:
name: ${{ inputs.artifact-prefix }}-shard-${{ matrix.shard }}
path: |
packages/quality/*/test-results*
packages/quality/*/playwright-report/
packages/quality/*/*/test-results*
packages/quality/*/*/playwright-report/
packages/quality/testing/playwright/test-results/
packages/quality/testing/playwright/test-results.json
packages/quality/testing/playwright/playwright-report/
packages/quality/testing/playwright/coverage/lcov.info
packages/quality/testing/playwright/coverage/by-spec/
packages/quality/testing/playwright/coverage/index.html

View File

@ -346,7 +346,7 @@ jobs:
# ANTHROPIC_API_KEY is the provider-native key resolveEvalModelConfig prefers
# when N8N_INSTANCE_AI_EVAL_MODEL differs from N8N_INSTANCE_AI_MODEL.
MODEL_ARGS+=(
-e N8N_INSTANCE_AI_EVAL_MODEL=anthropic/claude-sonnet-5-5
-e N8N_INSTANCE_AI_EVAL_MODEL=anthropic/claude-sonnet-4-6
-e ANTHROPIC_API_KEY="$EVALS_ANTHROPIC_KEY"
)

View File

@ -1,71 +0,0 @@
name: 'Test: Image Efficiency'
on:
workflow_dispatch:
permissions:
contents: read
jobs:
prepare-docker:
uses: ./.github/workflows/prepare-docker-reusable.yml
secrets:
QA_METRICS_WEBHOOK_URL: ${{ secrets.QA_METRICS_WEBHOOK_URL }}
QA_METRICS_WEBHOOK_USER: ${{ secrets.QA_METRICS_WEBHOOK_USER }}
QA_METRICS_WEBHOOK_PASSWORD: ${{ secrets.QA_METRICS_WEBHOOK_PASSWORD }}
image-efficiency:
name: Image Efficiency
needs: prepare-docker
runs-on: ${{ vars.RUNNER_PROVIDER == 'github' && 'ubuntu-latest' || 'blacksmith-2vcpu-ubuntu-2204' }}
timeout-minutes: 20
env:
CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
CURRENTS_PROJECT_ID: 'nHHLA5'
CURRENTS_CI_BUILD_ID: ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}-images
QA_METRICS_WEBHOOK_URL: ${{ secrets.QA_METRICS_WEBHOOK_URL }}
QA_METRICS_WEBHOOK_USER: ${{ secrets.QA_METRICS_WEBHOOK_USER }}
QA_METRICS_WEBHOOK_PASSWORD: ${{ secrets.QA_METRICS_WEBHOOK_PASSWORD }}
steps:
- name: Checkout
uses: useblacksmith/checkout@bcec731f1eb1367240608d1c889a75b96db6ec53 # v1.5.0
- name: Setup Environment
uses: ./.github/actions/setup-nodejs
with:
build-command: pnpm turbo run build --filter=@n8n/utils...
- name: Load images from cache
uses: ./.github/actions/load-n8n-docker
- name: Install Dive
shell: bash
run: |
set -euo pipefail
# Keep this version in sync with efficiency/images/dive-results.ts.
VERSION=0.13.1
DIR=$(mktemp -d "$RUNNER_TEMP/dive.XXXXXX")
ARCHIVE="$DIR/dive.tar.gz"
curl --fail --location --retry 3 \
"https://github.com/wagoodman/dive/releases/download/v${VERSION}/dive_${VERSION}_linux_amd64.tar.gz" \
--output "$ARCHIVE"
echo "0970549eb4a306f8825a84145a2534153badb4d7dcf3febd1967c706367c3d0e $ARCHIVE" | sha256sum --check
tar -xzf "$ARCHIVE" -C "$DIR" dive
echo "$DIR" >> "$GITHUB_PATH"
- name: Measure image layer efficiency
run: >-
pnpm --filter=@n8n/efficiency exec playwright test
--project=image-efficiency:n8n --project=image-efficiency:runners
- name: Upload image efficiency reports
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: image-efficiency-${{ github.run_attempt }}
path: |
packages/quality/efficiency/test-results/
packages/quality/efficiency/test-results.json
packages/quality/efficiency/playwright-report/
retention-days: 7
if-no-files-found: ignore

View File

@ -0,0 +1,110 @@
name: 'Test: Workflows PR Comment'
on:
issue_comment:
types: [created]
permissions:
pull-requests: read
contents: read
jobs:
handle_comment_command:
name: Handle /test-workflows Command
if: github.event.issue.pull_request && startsWith(github.event.comment.body, '/test-workflows')
runs-on: ubuntu-latest
outputs:
permission_granted: ${{ steps.pr_check_and_details.outputs.permission_granted }}
git_ref: ${{ steps.pr_check_and_details.outputs.head_sha }}
pr_number: ${{ steps.pr_check_and_details.outputs.pr_number_string }}
steps:
- name: Validate User, Get PR Details, and React
id: pr_check_and_details
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const commenter = context.actor;
const issueOwner = context.repo.owner;
const issueRepo = context.repo.repo;
const commentId = context.payload.comment.id;
const prNumber = context.issue.number; // In issue_comment on a PR, issue.number is the PR number
// Function to add a reaction to the comment
async function addReaction(content) {
try {
await github.rest.reactions.createForIssueComment({
owner: issueOwner,
repo: issueRepo,
comment_id: commentId,
content: content
});
} catch (reactionError) {
// Log if reaction fails but don't fail the script for this
console.log(`Failed to add reaction '${content}': ${reactionError.message}`);
}
}
// Initialize outputs to a non-triggering state
core.setOutput('permission_granted', 'false');
core.setOutput('head_sha', '');
core.setOutput('pr_number_string', '');
// 1. Check user permissions
try {
const { data: permissions } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: issueOwner,
repo: issueRepo,
username: commenter
});
const allowedPermissions = ['admin', 'write', 'maintain'];
if (!allowedPermissions.includes(permissions.permission)) {
console.log(`User @${commenter} has '${permissions.permission}' permission. Needs 'admin', 'write', or 'maintain'.`);
await addReaction('-1'); // User does not have permission
return; // Exit script, tests will not be triggered
}
console.log(`User @${commenter} has '${permissions.permission}' permission.`);
} catch (error) {
console.log(`Could not verify permissions for @${commenter}: ${error.message}`);
await addReaction('confused'); // Error checking permissions
return; // Exit script
}
// 2. Fetch PR details (if permission check passed)
let headSha;
try {
const { data: pr } = await github.rest.pulls.get({
owner: issueOwner,
repo: issueRepo,
pull_number: prNumber,
});
headSha = pr.head.sha;
console.log(`Workspaced PR details: SHA - ${headSha}, PR Number - ${prNumber}`);
// Set outputs for the next job
core.setOutput('permission_granted', 'true');
core.setOutput('head_sha', headSha);
core.setOutput('pr_number_string', prNumber.toString());
await addReaction('+1'); // Command accepted, tests will be triggered
} catch (error) {
console.log(`Failed to fetch PR details for PR #${prNumber}: ${error.message}`);
core.setOutput('permission_granted', 'false'); // Ensure this is false if PR fetch fails
await addReaction('confused'); // Error fetching PR details
}
trigger_reusable_tests:
name: Trigger Reusable Test Workflow
needs: handle_comment_command
if: >
always() &&
needs.handle_comment_command.result != 'skipped' &&
needs.handle_comment_command.outputs.permission_granted == 'true' &&
needs.handle_comment_command.outputs.git_ref != ''
uses: ./.github/workflows/test-workflows-callable.yml
with:
git_ref: ${{ needs.handle_comment_command.outputs.git_ref }}
secrets: inherit

View File

@ -1,118 +0,0 @@
name: 'Util: Update get-n8n Versions'
on:
schedule:
# Run every Wednesday at 04:00 UTC.
- cron: '0 4 * * 3'
workflow_dispatch:
permissions: {}
concurrency:
group: update-get-n8n-versions
cancel-in-progress: false
jobs:
update-versions:
name: Update get-n8n versions
if: >-
github.ref_name == github.event.repository.default_branch &&
(github.event_name == 'workflow_dispatch' ||
(github.event_name == 'schedule' && github.repository == 'n8n-io/n8n'))
runs-on: ubuntu-latest
timeout-minutes: 25
permissions:
contents: read
steps:
- name: Generate GitHub App Token
id: generate-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
with:
app-id: ${{ secrets.N8N_ASSISTANT_APP_ID }}
private-key: ${{ secrets.N8N_ASSISTANT_PRIVATE_KEY }}
permission-contents: write
permission-pull-requests: write
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Resolve stable versions
id: versions
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
n8n_version="$(gh api repos/n8n-io/n8n/releases/latest --jq '.tag_name | sub("^n8n@"; "")')"
registry_token="$(curl -fsSL --retry 3 'https://ghcr.io/token?scope=repository:n8n-io/n8n-sandbox-service-api:pull' | jq -er '.token')"
stable_digest="$(docker buildx imagetools inspect \
'ghcr.io/n8n-io/n8n-sandbox-service-api:stable' \
--format '{{json .Manifest}}' | jq -er '.digest')"
sandbox_version=''
while IFS= read -r version; do
version_digest="$(docker buildx imagetools inspect \
"ghcr.io/n8n-io/n8n-sandbox-service-api:${version}" \
--format '{{json .Manifest}}' | jq -er '.digest')"
if [ "$version_digest" = "$stable_digest" ]; then
sandbox_version="$version"
break
fi
done < <(curl -fsSL --retry 3 \
-H "Authorization: Bearer $registry_token" \
'https://ghcr.io/v2/n8n-io/n8n-sandbox-service-api/tags/list?n=1000' |
jq -r '.tags[]' |
grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' |
sort -Vr)
printf '%s\n' "$n8n_version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'
printf '%s\n' "$sandbox_version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'
for image in api runner-dind sandbox; do
docker manifest inspect "ghcr.io/n8n-io/n8n-sandbox-service-${image}:${sandbox_version}" >/dev/null
done
sed -i "s/^FALLBACK_N8N_VERSION=.*/FALLBACK_N8N_VERSION=\"${n8n_version}\"/" docker/get-n8n.sh
sed -i "s/^SANDBOX_VERSION=.*/SANDBOX_VERSION=\"${sandbox_version}\"/" docker/get-n8n.sh
echo "n8n_version=$n8n_version" >> "$GITHUB_OUTPUT"
echo "sandbox_version=$sandbox_version" >> "$GITHUB_OUTPUT"
- name: Check for changes
id: changes
run: |
if git diff --quiet -- docker/get-n8n.sh; then
echo 'has-changes=false' >> "$GITHUB_OUTPUT"
else
echo 'has-changes=true' >> "$GITHUB_OUTPUT"
fi
- name: Test installer upgrade
if: steps.changes.outputs.has-changes == 'true'
run: |
shellcheck docker/get-n8n.sh docker/test-get-n8n.sh
dash -n docker/get-n8n.sh
dash -n docker/test-get-n8n.sh
sh docker/test-get-n8n.sh --e2e
- name: Create pull request
if: steps.changes.outputs.has-changes == 'true'
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
with:
token: ${{ steps.generate-token.outputs.token }}
add-paths: docker/get-n8n.sh
commit-message: 'chore: Update get-n8n fallback versions'
labels: 'automation:scheduled-update'
title: 'chore: Update get-n8n fallback versions'
body: |
This automated PR updates the get-n8n fallback release to ${{ steps.versions.outputs.n8n_version }}.
It also updates the sandbox service release to ${{ steps.versions.outputs.sandbox_version }}.
The workflow verified that all sandbox images use the same release. It also upgraded a legacy installation to these versions and checked the running stack.
_Generated by the weekly get-n8n version update workflow._
branch: update-get-n8n-versions
base: master
delete-branch: true
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

3
.gitignore vendored
View File

@ -1,5 +1,4 @@
node_modules
.build/
.pnpm-store
.DS_Store
.tmp
@ -9,7 +8,6 @@ dist
coverage
coverage-by-spec
coverage-by-spec-backend
/report
npm-debug.log*
yarn.lock
google-generated-credentials.json
@ -41,7 +39,6 @@ build.log
tcr-dry.log
.agent-setup/
.agent-recordings/
.vitest/
.vitest-profile/
.pi-subagents/
sbom-source.cdx.json

View File

@ -1,26 +0,0 @@
{
"threshold": 10.5,
"reporters": ["json", "html"],
"gitignore": true,
"ignore": [
"**/__snapshots__/**",
"**/*.snap",
"**/fixtures/**",
"**/locales/**",
"**/i18n/**",
"**/*.generated.*",
"**/__schema__/**",
"**/cassettes/**",
"packages/@n8n/typeorm/test/**",
"docs/generated/**",
"**/test/**/*.workflow.json",
"**/tests/**/*.workflow.json",
"**/__tests__/**/*.workflow.json",
"**/test/**/workflow.*.json",
"**/tests/**/workflow.*.json",
"**/__tests__/**/workflow.*.json",
"**/test/**/workflows/**/*.json",
"**/tests/**/workflows/**/*.json",
"**/__tests__/**/workflows/**/*.json"
]
}

View File

@ -52,8 +52,8 @@ skip:
# Uses merge commit SHA from GitHub - the code has already been reviewed
# and merged, not arbitrary PR code.
- .github/workflows/test-unit-reusable.yml
# Reachable only from test-workflows-nightly.yml, which is
# workflow_dispatch-only, so the ref comes from a maintainer, not a PR.
# Permission-gated: only maintainers (admin/write/maintain) can trigger
# via /test-workflows comment. Verified in test-workflows-pr-comment.yml.
- .github/workflows/test-workflows-callable.yml
# Reusable workflow reachable only via workflow_dispatch (manual) or from
# ci-mcp-evals.yml, which is itself workflow_dispatch-only — never from a

View File

@ -14,11 +14,6 @@ frontend, and extensible node-based workflow engine.
- Write all technical text (code comments, PR descriptions, issue and ticket
descriptions, docs) in ASD-STE100 Simplified Technical English: use short
sentences, the active voice, and one instruction for each sentence
- **JSDoc on `@Env(...)` config properties is public documentation.** The
docs team exports these comments into the environment variable reference on
docs.n8n.io. Write them for a self-hosting operator and follow the
`n8n:env-var-docs` skill, which applies the n8n docs style guide and
overrides the ASD-STE100 rule above for these comments
- **Secrets on the command line:** if a developer opted into anonymous dev
metrics (`scripts/dev-metrics`), pnpm command arguments are recorded. Arguments
of secret-carrying words (`config`, `login`, `publish`, `token`) — whether a
@ -40,10 +35,6 @@ frontend, and extensible node-based workflow engine.
suggested by Linear, **unless it is a security fix** (see Security Fix
Hygiene below)
- Use mermaid diagrams in MD files when you need to visualise something
- Write an ADR only when asked. When a change makes a decision that an
engineer could challenge in 12 months, say so in one line and let the
human decide. Read [docs/adr/README.md](docs/adr/README.md) before you
write one. CI enforces its conventions
- **Developing v3 features:** land normal feature work on `master` behind an
opt-in flag; introduce breaking changes only on the `3.x` branch. See
[.github/DEVELOPING_V3.md](.github/DEVELOPING_V3.md).
@ -74,15 +65,10 @@ are namespaced under `n8n:`. Use `n8n:` prefix when invoking them (e.g.
## Essential Commands
For routine pre-commit checks, follow [Verify changes](#verify-changes).
For full-repo lint and typecheck, use `pnpm agent:lint` and
`pnpm agent:typecheck`. They save full logs and return compact results.
For focused tests, use `pnpm agent:test` or `pnpm agent:playwright`.
Pass test files and worker limits after `--`. Run each command with `--help`
for its options.
`pnpm agent:lint` and `pnpm agent:typecheck` run full-repo checks by default.
With `--filter <package>`, they still check the whole package. These wrappers
save logs and reduce console output. They do not reduce CPU or memory use.
Do not use them as routine pre-commit checks.
Run each command with `--help` for its package, script, and file options.
### Fresh checkout / agent setup
@ -229,16 +215,12 @@ const children = getChildNodes(workflow.connections, 'NodeName', 'main', 1);
### Persistence layer & the TypeORM boundary
TypeORM (`@n8n/typeorm`) must stay in the **persistence layer**. The shared
`@n8n/db` package and backend persistence adapters can import it. A module can
colocate or group its entities and repositories according to its domain.
TypeORM (`@n8n/typeorm`) must stay in the **persistence layer** — the `@n8n/db`
package or a backend module's own `database/` folder (entity/repository files).
Business logic — services, controllers, handlers, commands, factories — must not
import from `@n8n/typeorm` (including `@n8n/typeorm/...` subpaths). The
`typeorm-persistence-boundary` Code Health rule recognizes entity and repository
declarations. It scans backend packages that depend on `@n8n/db` or
`@n8n/typeorm`. Tests, migrations, and explicit helper-only adapters are
exceptions. Existing business-logic imports stay in the shrink-only Code Health
baseline. A new business-logic import fails CI.
import from `@n8n/typeorm` (including `@n8n/typeorm/...` subpaths). In
`packages/cli` this is enforced by the `misplaced-n8n-typeorm-import` lint rule;
a new import (or an inline `eslint-disable` of the rule) fails CI.
- **Pattern:** when a query needs operators (`In`, `IsNull`, `LessThan`,
`FindOptionsWhere`, …), put it behind a **use-case-named repository method**
@ -324,20 +306,9 @@ extends one of those layers):
### Verify changes
- Before committing, run formatting and lint checks on changed files. Use
the package's configured tools through `pnpm exec` with explicit file paths.
Do not append file paths to `pnpm lint`; package scripts can still check
the whole package.
- Run tests that cover the changed behavior from the owning package:
`pnpm test <test-file> --maxWorkers=1`. Or use the root wrapper:
`pnpm agent:test --filter <package> -- <test-file> --maxWorkers=1`.
For Playwright, use `pnpm agent:playwright -- <spec-file> --workers=1`.
- For routine commits, run checks one at a time. Use one test worker by
default. Do not run full frontend typechecks locally. Use CI for
comprehensive lint, typechecks, and test suites.
- For documentation-only changes, review the diff and run `git diff --check`.
Skip code tests when no behavior changed.
- Report which checks ran and which checks were left to CI.
- Run focused tests from the owning package: `pnpm test <test-file>`.
- Run that package's `pnpm lint` and `pnpm typecheck` before committing code.
Build first when shared types or cross-package dependencies change.
- Use Vitest for unit tests. Use
[Playwright](packages/quality/testing/playwright/AGENTS.md) when a test needs its
browser, fixtures, or managed containers.

View File

@ -1,158 +1,3 @@
# [2.44.0](https://github.com/n8n-io/n8n/compare/n8n@2.43.0...n8n@2.44.0) (2026-10-13)
### Bug Fixes
* Align execution retry menu and clarify actions ([#40710](https://github.com/n8n-io/n8n/issues/40710)) ([84d2fd6](https://github.com/n8n-io/n8n/commit/84d2fd6f3ae68e973aa49f7e2b1dd5dbf06ad18c))
* Allow per-process crash journal paths ([#37670](https://github.com/n8n-io/n8n/issues/37670)) ([447e939](https://github.com/n8n-io/n8n/commit/447e939b732b778662572098d81f014527e3ffe2))
* **core:** Allow reverting a workflow version that uses credentials the user cannot use ([#40701](https://github.com/n8n-io/n8n/issues/40701)) ([033a9b5](https://github.com/n8n-io/n8n/commit/033a9b512c2d52d05b43d4dd2d0e10634dc36e2a))
* **core:** Apply node type policies to agent node tools ([#39711](https://github.com/n8n-io/n8n/issues/39711)) ([e7d8533](https://github.com/n8n-io/n8n/commit/e7d8533880df0d36438e39a07f0594fcaaaaab55))
* **core:** Apply the credential type policy to credential tests and probes ([#39927](https://github.com/n8n-io/n8n/issues/39927)) ([9191cf3](https://github.com/n8n-io/n8n/commit/9191cf3fb07ce6bbb7b2217592ce56372b52f6c2))
* **core:** Block the assistant when AI credits hit zero ([#40659](https://github.com/n8n-io/n8n/issues/40659)) ([8b7065a](https://github.com/n8n-io/n8n/commit/8b7065a87684bb3a055d8bcfc5d34c9b70094080))
* **core:** Check the credential save policy before package import creates stubs ([#40687](https://github.com/n8n-io/n8n/issues/40687)) ([a3391ba](https://github.com/n8n-io/n8n/commit/a3391ba93c4574405d06e79e2efc791b6ba8a21f))
* **core:** Check the target project's policy on folder, credential and delete-transfer moves ([#40301](https://github.com/n8n-io/n8n/issues/40301)) ([77370af](https://github.com/n8n-io/n8n/commit/77370af99a273073faf7df57a1fe8f71d3833bbe))
* **core:** Count jobs as running from the start of job processing ([#40050](https://github.com/n8n-io/n8n/issues/40050)) ([dc5c80f](https://github.com/n8n-io/n8n/commit/dc5c80f26af8d32e5887ccbf7634f3da1be5f771))
* **core:** Expose 1Password fields for secret preview and autocomplete ([#40538](https://github.com/n8n-io/n8n/issues/40538)) ([bef5f3f](https://github.com/n8n-io/n8n/commit/bef5f3f97aca163ac289af61e10869c0fa7fff60))
* **core:** Fix Kimi K3 and other OpenAI-compatible Assistant model providers on self-hosted Assistant ([#40439](https://github.com/n8n-io/n8n/issues/40439)) ([1ef7756](https://github.com/n8n-io/n8n/commit/1ef77564e3bef2e34c57d8a67df892ace3858a5d))
* **core:** Handle each Chat Hub segment once in queue mode ([#40791](https://github.com/n8n-io/n8n/issues/40791)) ([9ff8d4f](https://github.com/n8n-io/n8n/commit/9ff8d4fc738ca0e54db863c574e5a6d93df9ce2e))
* **core:** Improve node placement when n8n Assistant edits a workflow ([#40139](https://github.com/n8n-io/n8n/issues/40139)) ([d900743](https://github.com/n8n-io/n8n/commit/d900743bce0cf8274c42e1f4a579fc8b5cf74997))
* **core:** Keep waiting executions unchanged when a resume request fails ([#40683](https://github.com/n8n-io/n8n/issues/40683)) ([bbd35e2](https://github.com/n8n-io/n8n/commit/bbd35e281b100a36aa209518c5ab027eabf85a1f))
* **core:** Let the editor download binary data of an Engine v2 execution ([#40663](https://github.com/n8n-io/n8n/issues/40663)) ([c9cb3ee](https://github.com/n8n-io/n8n/commit/c9cb3ee3abd23fe146cd4a2daed49c4bddb80d97))
* **core:** Let the streaming heartbeat stop on Chat Hub responses ([#40792](https://github.com/n8n-io/n8n/issues/40792)) ([ee8a608](https://github.com/n8n-io/n8n/commit/ee8a608a22ec7a23dc795ee0554edd34186e87d2))
* **core:** Match regex case-insensitively when ignore case is enabled ([#33589](https://github.com/n8n-io/n8n/issues/33589)) ([2596f3a](https://github.com/n8n-io/n8n/commit/2596f3ac1c657aa4d2ddf40430b9e5940fb9c1b0))
* **core:** Match the Brazilian real symbol in the in-isolate currency regex ([#40893](https://github.com/n8n-io/n8n/issues/40893)) ([d3deffb](https://github.com/n8n-io/n8n/commit/d3deffbfa59d358614458f8b1ae2d56d118a9ca5))
* **core:** Pass `storedAt` into `WorkflowExecute` at every callsite ([#40495](https://github.com/n8n-io/n8n/issues/40495)) ([5ab2187](https://github.com/n8n-io/n8n/commit/5ab21874169d44eb01a19d6f0ba19bb7a254d952))
* **core:** Remove credentials of deleted projects on source control pull ([#40692](https://github.com/n8n-io/n8n/issues/40692)) ([978f810](https://github.com/n8n-io/n8n/commit/978f810bbef9e284b564db4897be7085257064b1))
* **core:** Report approval tools with no tool connected in workflow validation ([#40561](https://github.com/n8n-io/n8n/issues/40561)) ([bc0a9cb](https://github.com/n8n-io/n8n/commit/bc0a9cbc112aaed2853f14c32157082f41ba42b4))
* **core:** Report MCP server connection failures in verify_mcp_server ([#40559](https://github.com/n8n-io/n8n/issues/40559)) ([fbbbadc](https://github.com/n8n-io/n8n/commit/fbbbadc292791112e30101edee229e9d5f4dbc02))
* **core:** Require workflow create scope for single node runs in n8n Assistant ([#40908](https://github.com/n8n-io/n8n/issues/40908)) ([27fcb96](https://github.com/n8n-io/n8n/commit/27fcb968fb711a9957eed48fa78c5adfa78fc607))
* **core:** Resume tool calls for deferred tools that a skill loaded ([#40126](https://github.com/n8n-io/n8n/issues/40126)) ([1c84af2](https://github.com/n8n-io/n8n/commit/1c84af2e96bda41cd84852af82e5cae5b823f0f8))
* **core:** Return jobs dequeued during worker shutdown to the queue ([#40086](https://github.com/n8n-io/n8n/issues/40086)) ([084f3b3](https://github.com/n8n-io/n8n/commit/084f3b376a0d64594320853bae90f13537d3b8c9))
* **core:** Return jobs fetched before a worker paused to the queue ([#40162](https://github.com/n8n-io/n8n/issues/40162)) ([f26747b](https://github.com/n8n-io/n8n/commit/f26747bfc665ce0c137b0b7645245b1a97d1d01b))
* **core:** Save agent draft definitions atomically ([#40374](https://github.com/n8n-io/n8n/issues/40374)) ([9ee5d1a](https://github.com/n8n-io/n8n/commit/9ee5d1ad7a54cde445ac945fc56a7ba5a4ee4707))
* **core:** Serve the migration report on every main in a multi-main setup ([#40180](https://github.com/n8n-io/n8n/issues/40180)) ([a6f1e79](https://github.com/n8n-io/n8n/commit/a6f1e79394adced5958219f812e8ca14a10b9962))
* **core:** Show the policy block before node issues on execute and publish ([#40290](https://github.com/n8n-io/n8n/issues/40290)) ([0bbea43](https://github.com/n8n-io/n8n/commit/0bbea438e1906a0773cdbb46e273b4c01fea359b))
* **core:** Stabilise background child approval wait ([#40834](https://github.com/n8n-io/n8n/issues/40834)) ([2ca4e55](https://github.com/n8n-io/n8n/commit/2ca4e55502e03985d2c9b1b0033b6f5151ccb8f4))
* **core:** Start a new test session when call_agent gets an unknown session ID ([#40458](https://github.com/n8n-io/n8n/issues/40458)) ([e16566b](https://github.com/n8n-io/n8n/commit/e16566b31324991a369708b7eb1f46027f80445b))
* **core:** Stop marking the Message an Agent node as hidden ([#40358](https://github.com/n8n-io/n8n/issues/40358)) ([3366d2b](https://github.com/n8n-io/n8n/commit/3366d2b9b3151a769116a66499668c3a36cf65a4))
* **core:** Validate execution timeout against the configured maximum in Instance AI saves ([#40769](https://github.com/n8n-io/n8n/issues/40769)) ([2176819](https://github.com/n8n-io/n8n/commit/2176819865a03e9247dac0a61177572ac4f7711c))
* **core:** Validate the size argument of the chunk() expression extension ([#40880](https://github.com/n8n-io/n8n/issues/40880)) ([3ff9c83](https://github.com/n8n-io/n8n/commit/3ff9c83bdaf873509e4470f97e26919e0653add8))
* **core:** Wire Entra OAuth2 into agent Azure OpenAI runtime ([#40218](https://github.com/n8n-io/n8n/issues/40218)) ([96a8ff4](https://github.com/n8n-io/n8n/commit/96a8ff4d15baa2ab15debc8ea02da81847f5a504))
* **Databricks Node:** Request float encoding for embeddings from the Unity AI Gateway ([#40684](https://github.com/n8n-io/n8n/issues/40684)) ([4c0902f](https://github.com/n8n-io/n8n/commit/4c0902f6bf4a0aa6634d5598e75fc677aa55f429))
* **editor:** Add resend to retryable Agent preview errors ([#40592](https://github.com/n8n-io/n8n/issues/40592)) ([f7e52a8](https://github.com/n8n-io/n8n/commit/f7e52a851ed9416615167826daf706d90a19d53b))
* **editor:** Align nodes panel to the embedded canvas in the n8n Assistant split view ([#40795](https://github.com/n8n-io/n8n/issues/40795)) ([37799ad](https://github.com/n8n-io/n8n/commit/37799ad2f21067ec7951c2656c9e938dc87443e1))
* **editor:** Align tooltip trigger box with its content ([#40422](https://github.com/n8n-io/n8n/issues/40422)) ([a694531](https://github.com/n8n-io/n8n/commit/a694531a0367bc6b7991b194ec762e7ad51aaa0a))
* **editor:** Keep Agent Builder settings inside a narrow column ([#40759](https://github.com/n8n-io/n8n/issues/40759)) ([e2b4fee](https://github.com/n8n-io/n8n/commit/e2b4fee0ec0f0f34245664c23869153089362236))
* **editor:** Keep Assistant fixes in Agent builder and correct tooltips ([#40348](https://github.com/n8n-io/n8n/issues/40348)) ([a13705a](https://github.com/n8n-io/n8n/commit/a13705aa8fff5a170ba5b069946e205e9acc1985))
* **editor:** Keep folder creation available globally after Community registration ([#40082](https://github.com/n8n-io/n8n/issues/40082)) ([e1025f3](https://github.com/n8n-io/n8n/commit/e1025f35e4203b49436aedb89dcb679e96169528))
* **editor:** Keep same-named parameter values apart when their types differ ([#40170](https://github.com/n8n-io/n8n/issues/40170)) ([6013045](https://github.com/n8n-io/n8n/commit/601304543d2b87e6aa42211c3a8c6c2766c2c61d))
* **editor:** Keep the prompt visible while the assistant starts a new thread ([#40796](https://github.com/n8n-io/n8n/issues/40796)) ([be402be](https://github.com/n8n-io/n8n/commit/be402be262974d46f79ba3464e20efc0ee734ac4))
* **editor:** Keep the selected credential visible when the picker does not list it ([#40450](https://github.com/n8n-io/n8n/issues/40450)) ([66b382d](https://github.com/n8n-io/n8n/commit/66b382de52fb56db87987910929e932292837305))
* **editor:** Keep the workflow setup step counter on one line ([#40771](https://github.com/n8n-io/n8n/issues/40771)) ([55eb2ce](https://github.com/n8n-io/n8n/commit/55eb2ce44291648adf6ca05b5b1605efea8d77f7))
* **editor:** Keep typed characters in Markdown fields ([#40805](https://github.com/n8n-io/n8n/issues/40805)) ([16e29da](https://github.com/n8n-io/n8n/commit/16e29da52f3173ee5edc7b96697a4c227b4983d0))
* **editor:** Load node types before authenticated pages render ([#40812](https://github.com/n8n-io/n8n/issues/40812)) ([8297b2e](https://github.com/n8n-io/n8n/commit/8297b2e6d263d63571926545bf8b5c490f5125bf))
* **editor:** Place the restricted node popover per host, keep one open, and stack the admin dialog ([#40678](https://github.com/n8n-io/n8n/issues/40678)) ([b28dceb](https://github.com/n8n-io/n8n/commit/b28dceb462d8e51855d4e13a87e9c975638ef977))
* **editor:** Polish n8n Assistant and Execute button UI details ([#40414](https://github.com/n8n-io/n8n/issues/40414)) ([76cab1e](https://github.com/n8n-io/n8n/commit/76cab1e26d97cbbf50790926f1bbb14cfb12d078))
* **editor:** Preserve Live Data highlights on scroll in expression editor ([#33842](https://github.com/n8n-io/n8n/issues/33842)) ([0f02b50](https://github.com/n8n-io/n8n/commit/0f02b509be304523955e7700c7c9eeefe58d0aa9))
* **editor:** Remove redundant description for create workflow option in agent config ([#40882](https://github.com/n8n-io/n8n/issues/40882)) ([b542f66](https://github.com/n8n-io/n8n/commit/b542f6611998c23b40b54d25d1e923841ee24160))
* **editor:** Rename the "Executions fail" label to "Executions will fail" ([#40888](https://github.com/n8n-io/n8n/issues/40888)) ([2a51f38](https://github.com/n8n-io/n8n/commit/2a51f38d55f37f65382ebf3900a340fc62b15314))
* **editor:** Respect the default voice for chat read aloud ([#40440](https://github.com/n8n-io/n8n/issues/40440)) ([022b239](https://github.com/n8n-io/n8n/commit/022b23945ba576024685bfe1702489f427a3c9fe))
* **editor:** Shorten the share button label on the credential sharing tab ([#40637](https://github.com/n8n-io/n8n/issues/40637)) ([c133d6c](https://github.com/n8n-io/n8n/commit/c133d6c893a879c907d20bb71a10817d358db553))
* **editor:** Show the Agent artifact while the builder creates it ([#40535](https://github.com/n8n-io/n8n/issues/40535)) ([1c63119](https://github.com/n8n-io/n8n/commit/1c631197563b8f65d343d060355050c4551f381d))
* **editor:** Show the owner and credential type for credentials the user cannot use ([#40669](https://github.com/n8n-io/n8n/issues/40669)) ([63dc285](https://github.com/n8n-io/n8n/commit/63dc2854936f3e282ca422cd9b9babeab65a2375))
* **editor:** Show the renamed agent name in the assistant artifact tab ([#40770](https://github.com/n8n-io/n8n/issues/40770)) ([4032797](https://github.com/n8n-io/n8n/commit/40327977903613fee5d033efd31c6e01416a2bf0))
* **editor:** Show the unavailable credential at the top of the node picker ([#40693](https://github.com/n8n-io/n8n/issues/40693)) ([1933723](https://github.com/n8n-io/n8n/commit/19337237ec59bd03c89e300a23289d2bdfbf269e))
* **editor:** Show why a node on another branch can't be referenced ([#40565](https://github.com/n8n-io/n8n/issues/40565)) ([a195096](https://github.com/n8n-io/n8n/commit/a19509673336fbbf6687b107ce0af5bcfec68393))
* **editor:** Small UI fixes to budget guardrail setup components ([#40383](https://github.com/n8n-io/n8n/issues/40383)) ([958d23d](https://github.com/n8n-io/n8n/commit/958d23d81cd99d7b9fd63d2484b79382c2d20c23))
* **editor:** Use pulsing status dot for the enabled n8n Assistant setting ([#40712](https://github.com/n8n-io/n8n/issues/40712)) ([3ba5229](https://github.com/n8n-io/n8n/commit/3ba522910b1cc3009c108a202634388fd838717f))
* **Google Gemini Chat Model Node:** Point the AI builder to the model catalog for new Gemini models ([#40159](https://github.com/n8n-io/n8n/issues/40159)) ([c21ed4f](https://github.com/n8n-io/n8n/commit/c21ed4f13aee6a1551207a92122bea2859e1b8d3))
* **Invoice Ninja Node:** Fix retrieving currencies for bank transactions ([#12997](https://github.com/n8n-io/n8n/issues/12997)) ([00849c4](https://github.com/n8n-io/n8n/commit/00849c4deabada87641c146773c0981e873a6328))
* Keep execution details clear of preview canvas ([#40176](https://github.com/n8n-io/n8n/issues/40176)) ([af98327](https://github.com/n8n-io/n8n/commit/af98327a5e4f2332b78b4d460e6eb208f0782d28))
* Load only the publish history that the editor shows ([#40183](https://github.com/n8n-io/n8n/issues/40183)) ([b28adf9](https://github.com/n8n-io/n8n/commit/b28adf97895bbdba2e0c777bdfb5cd11d04c0e56))
* **Microsoft Outlook Trigger Node:** Report failed polls and limit the backlog per poll ([#40147](https://github.com/n8n-io/n8n/issues/40147)) ([6bc5c93](https://github.com/n8n-io/n8n/commit/6bc5c93513efbe4d236c5794cfd07e1ac4d916f6))
* Multiple migration timestamps withing a single PR ([#40379](https://github.com/n8n-io/n8n/issues/40379)) ([7db7fa4](https://github.com/n8n-io/n8n/commit/7db7fa42c80a8a24fb5ca5ec7448ffb12431fad9))
* **Odoo Node:** Normalize datetime fields to Odoo format before write ([#34186](https://github.com/n8n-io/n8n/issues/34186)) ([6b77613](https://github.com/n8n-io/n8n/commit/6b77613ee827560d9f34f551478a74daf4848dec))
* Prevent node types corruption when multiple loaders run at the same time ([#40633](https://github.com/n8n-io/n8n/issues/40633)) ([fdc3948](https://github.com/n8n-io/n8n/commit/fdc394819cecf96379ed7ba475364912099a6296))
* Remove loading flashes from data tables ([#39874](https://github.com/n8n-io/n8n/issues/39874)) ([2f4a386](https://github.com/n8n-io/n8n/commit/2f4a3868fbd74c07e91888eb35b1f3d4bcb2acb1))
* Report resource-operation violations as errors ([#40830](https://github.com/n8n-io/n8n/issues/40830)) ([a180010](https://github.com/n8n-io/n8n/commit/a1800105ef8f7c229ffd044e1233d273e95b6cd2))
* Return UTC ISO dates without changing other cells ([#40156](https://github.com/n8n-io/n8n/issues/40156)) ([8059b63](https://github.com/n8n-io/n8n/commit/8059b63da89ba89309cbc6eacce715110c9c5748))
* **S3 Node:** Percent-encode the copy source path ([#40282](https://github.com/n8n-io/n8n/issues/40282)) ([81f34c2](https://github.com/n8n-io/n8n/commit/81f34c23744424d17ca99eaf03beb9861c21a1ca))
* Separate agent response steps and show saved reasoning ([#40590](https://github.com/n8n-io/n8n/issues/40590)) ([1e6da4e](https://github.com/n8n-io/n8n/commit/1e6da4e615900d7665e6eeafe9ce6002d1510c31))
* Update matching nodes when selecting imported credentials ([#39650](https://github.com/n8n-io/n8n/issues/39650)) ([4b5b68e](https://github.com/n8n-io/n8n/commit/4b5b68ee2929344288b93469efe732379e3904a1))
* Use configured OAuth server rate limits ([#40542](https://github.com/n8n-io/n8n/issues/40542)) ([4c8b76b](https://github.com/n8n-io/n8n/commit/4c8b76b6f08d090bf6e7cf22f66d60ec3d0efdc6))
* Use ID token claims when UserInfo is unavailable ([#40779](https://github.com/n8n-io/n8n/issues/40779)) ([b8b0387](https://github.com/n8n-io/n8n/commit/b8b0387a31b556e296529235f9c4a75b307bb8f1))
* Validate and default public API pagination limits ([#40483](https://github.com/n8n-io/n8n/issues/40483)) ([f212d5b](https://github.com/n8n-io/n8n/commit/f212d5b900fe92c3012001b32f4cf17bd831921e))
* Wait for MockServer HTTP status without following logs ([#40846](https://github.com/n8n-io/n8n/issues/40846)) ([4593838](https://github.com/n8n-io/n8n/commit/45938389b86b6bfe25a8a8f3d132b600ee807f58))
### Features
* Add Antigravity to the MCP client connection dialog ([#40879](https://github.com/n8n-io/n8n/issues/40879)) ([f0a38cf](https://github.com/n8n-io/n8n/commit/f0a38cfe5801ba8d62b97f6d4ffeb031f23aa231))
* Add Google Vertex AI credentials ([#40665](https://github.com/n8n-io/n8n/issues/40665)) ([a7cba90](https://github.com/n8n-io/n8n/commit/a7cba90a854ea34198dd9c1fcb4f7eeae08c364d))
* **ai-builder:** Reopen closed AI Assistant tabs when the agent changes the artifact ([#40081](https://github.com/n8n-io/n8n/issues/40081)) ([5d38667](https://github.com/n8n-io/n8n/commit/5d3866775c828e766ca16642d5ae2a340d4133ca))
* **Azure AI Foundry Chat Model Node:** Speak the Anthropic Messages schema for Claude deployments ([#40306](https://github.com/n8n-io/n8n/issues/40306)) ([c134edf](https://github.com/n8n-io/n8n/commit/c134edf473276ff63387d28aea0d08c9ff676f7c))
* **Azure OpenAI Chat Model Node:** Rename the Foundry nodes and credentials to Microsoft Foundry ([#40398](https://github.com/n8n-io/n8n/issues/40398)) ([e5c8a8b](https://github.com/n8n-io/n8n/commit/e5c8a8bb62d2ce468d1cda3965562eeaa69996f8))
* Configure workflow tool inputs for Agents ([#40285](https://github.com/n8n-io/n8n/issues/40285)) ([4cb98ae](https://github.com/n8n-io/n8n/commit/4cb98aea9fbcede8ae414c3f817c7b0490d401f8))
* **core:** Add credentialTransfer policy enforcement point ([#40300](https://github.com/n8n-io/n8n/issues/40300)) ([c2f6920](https://github.com/n8n-io/n8n/commit/c2f6920794e66e7108b0005233506f7694a11a7e))
* **core:** Add execution identity to every OTel span ([#40649](https://github.com/n8n-io/n8n/issues/40649)) ([22ba4e7](https://github.com/n8n-io/n8n/commit/22ba4e7bc5c6fbe5243ff5c227c718ab7197c5e1))
* **core:** Add overwrite schema conflict policy to data table package import ([#40345](https://github.com/n8n-io/n8n/issues/40345)) ([3af9817](https://github.com/n8n-io/n8n/commit/3af98170d0d98a201df1a45f2ecee17f5f00f298))
* **core:** Add overwrite-non-destructive schema conflict policy to data table package import ([#40446](https://github.com/n8n-io/n8n/issues/40446)) ([dc33c29](https://github.com/n8n-io/n8n/commit/dc33c29d1af3f47a6179a76ff21ccc7bd1f75357))
* **core:** Add Prometheus metrics for database connection recovery ([#39890](https://github.com/n8n-io/n8n/issues/39890)) ([d904e7a](https://github.com/n8n-io/n8n/commit/d904e7a2476794acdf3928faacd86ae9b3e45220))
* **core:** Add the WhatsApp agent channel ([#38750](https://github.com/n8n-io/n8n/issues/38750)) ([b0d1a30](https://github.com/n8n-io/n8n/commit/b0d1a30f50fdf6b3720c2a5773e28efff5c5b0b5))
* **core:** Add workflow suggestion review actions ([#39858](https://github.com/n8n-io/n8n/issues/39858)) ([eaf8c25](https://github.com/n8n-io/n8n/commit/eaf8c25d1c2b680fe55f58fc9f6d10647e6ae640))
* **core:** Allow confirming destructive data table changes when continuing an apply ([#40491](https://github.com/n8n-io/n8n/issues/40491)) ([9946cfe](https://github.com/n8n-io/n8n/commit/9946cfe901b538ec5ca29e85cde3ec2044d33d00))
* **core:** Apply the member credential rule to Owners and admins in team projects ([#40448](https://github.com/n8n-io/n8n/issues/40448)) ([3cff8dc](https://github.com/n8n-io/n8n/commit/3cff8dc4ecac5fd173d198f3e319ab473cdd7b22))
* **core:** Block create/update of workflows with deprecated nodes ([#31360](https://github.com/n8n-io/n8n/issues/31360)) ([ea8417e](https://github.com/n8n-io/n8n/commit/ea8417e29ad6f8b981d9a04b17283d5d77f2b5bb))
* **core:** Email the agent owner when a monthly budget alert is crossed ([#40544](https://github.com/n8n-io/n8n/issues/40544)) ([19e1f70](https://github.com/n8n-io/n8n/commit/19e1f70ea62ad151abe18b5a25721caa35d7bedd))
* **core:** Emit opt-in start marker spans for workflow and node executions ([#40762](https://github.com/n8n-io/n8n/issues/40762)) ([c713545](https://github.com/n8n-io/n8n/commit/c7135451ebd552267aedf4898d845c53a97aab54))
* **core:** Experiment to show assistant composer and starter templates in agent list ([#40396](https://github.com/n8n-io/n8n/issues/40396)) ([fe26ba8](https://github.com/n8n-io/n8n/commit/fe26ba8d3a63963d6c7868338e73fb77378e94a9))
* **core:** Handle inbound media handling for whatsapp ([#39409](https://github.com/n8n-io/n8n/issues/39409)) ([50c2ca0](https://github.com/n8n-io/n8n/commit/50c2ca0a27189136d82339bdafd5d8c7513a9916))
* **core:** Handle message quality rate limits for whatsapp integration ([#39205](https://github.com/n8n-io/n8n/issues/39205)) ([3c33856](https://github.com/n8n-io/n8n/commit/3c33856997b084a3a87038c0d72f80d9b91af1b7))
* **core:** Hide credential-only nodes under a credential type policy ([#39652](https://github.com/n8n-io/n8n/issues/39652)) ([370b30f](https://github.com/n8n-io/n8n/commit/370b30f9195ba8d5ceaf75fb4cdfcf127105a3c6))
* **core:** Pair data table columns by id on package import ([#40709](https://github.com/n8n-io/n8n/issues/40709)) ([27b43de](https://github.com/n8n-io/n8n/commit/27b43de85f987ddd783e7c7ccbde7977d09a6d03))
* **core:** Persist self-healing results and handoffs ([#40115](https://github.com/n8n-io/n8n/issues/40115)) ([168a0ac](https://github.com/n8n-io/n8n/commit/168a0ac86056afd743bfde63863abbab4e8515f4))
* **core:** Post a budget-stop message on external agent channels ([#40767](https://github.com/n8n-io/n8n/issues/40767)) ([5e01906](https://github.com/n8n-io/n8n/commit/5e01906a1e6c177c0ce02d18317ce2d7b6ee7e97))
* **core:** Promote folder and project renames alongside selected workflows ([#40502](https://github.com/n8n-io/n8n/issues/40502)) ([a249e20](https://github.com/n8n-io/n8n/commit/a249e202905f30829fe3a7eacd2eba8dff6573ef))
* **core:** Report crashed executions from startup log recovery ([#40390](https://github.com/n8n-io/n8n/issues/40390)) ([668e71d](https://github.com/n8n-io/n8n/commit/668e71d54a26da7c12d092a7375a7cb3349a8471))
* **core:** Report destructive data table changes in the promotion apply preflight ([#40454](https://github.com/n8n-io/n8n/issues/40454)) ([5d208c8](https://github.com/n8n-io/n8n/commit/5d208c85ed275c22cc5597124b7a9cf590d18f11))
* **core:** Report the deployment artifact in telemetry ([#40319](https://github.com/n8n-io/n8n/issues/40319)) ([344dea5](https://github.com/n8n-io/n8n/commit/344dea5c77fc5f61ce10171a2553faa9bef4e609))
* **core:** Run the workflow history trim as a durable daily system task ([#40085](https://github.com/n8n-io/n8n/issues/40085)) ([38eea65](https://github.com/n8n-io/n8n/commit/38eea65993339ea3e8156cdbacef247749331351))
* **core:** Search, create and reopen agents from the command bar ([#40504](https://github.com/n8n-io/n8n/issues/40504)) ([75a9cc7](https://github.com/n8n-io/n8n/commit/75a9cc7e1219d35b441b02c20446dd89db186ff7))
* **core:** Serve Prometheus metrics while the database is unavailable ([#39908](https://github.com/n8n-io/n8n/issues/39908)) ([4e217ae](https://github.com/n8n-io/n8n/commit/4e217aeac6b029692fb8a692a3849ae8e5310b5a))
* **core:** Serve the instance CSP on all non-script responses ([#40205](https://github.com/n8n-io/n8n/issues/40205)) ([cabf0bf](https://github.com/n8n-io/n8n/commit/cabf0bf3b466a725deada3b532347b7db530dcac))
* **core:** Show every user the migration report, scoped to the workflows they can edit ([#40449](https://github.com/n8n-io/n8n/issues/40449)) ([f4f7dcf](https://github.com/n8n-io/n8n/commit/f4f7dcf13b6d93d46a2860e2c2577f9f6dda4c52))
* **core:** Show the agent chat attach button on the left of the composer ([#40320](https://github.com/n8n-io/n8n/issues/40320)) ([209adf9](https://github.com/n8n-io/n8n/commit/209adf9a7ee9e71cfe3d5119316ca9fce4b3ac68))
* **Databricks Node:** Guard the Vector Store insert against the wrong index ([#39699](https://github.com/n8n-io/n8n/issues/39699)) ([0932e95](https://github.com/n8n-io/n8n/commit/0932e9572e2650165b260fc591d1f02204c17aae))
* **editor:** Add a state column to the migration rule detail ([#40388](https://github.com/n8n-io/n8n/issues/40388)) ([682d092](https://github.com/n8n-io/n8n/commit/682d0920ba5cb2ab5e3ac0671f993c8e529e8389))
* **editor:** Add agent setup checklist ([#39919](https://github.com/n8n-io/n8n/issues/39919)) ([883ade4](https://github.com/n8n-io/n8n/commit/883ade4b9d2505f359057eb10c8d71ab153033a7))
* **editor:** Add order to settings sidebar links ([#40505](https://github.com/n8n-io/n8n/issues/40505)) ([cef87cf](https://github.com/n8n-io/n8n/commit/cef87cfcab3f59a657c8c27309f4807bd2d4a93a))
* **editor:** Add project selection to Vertex AI credentials ([#40667](https://github.com/n8n-io/n8n/issues/40667)) ([cdc23c6](https://github.com/n8n-io/n8n/commit/cdc23c666ffd6ed55f019aa24c99efdaf10fad14))
* **editor:** Animate the n8n Assistant activity indicator ([#40497](https://github.com/n8n-io/n8n/issues/40497)) ([04e1e7f](https://github.com/n8n-io/n8n/commit/04e1e7fc4771ff1371ac41f1d74aef7ced26b175))
* **editor:** Disable restricted model providers in the agent model selector ([#40658](https://github.com/n8n-io/n8n/issues/40658)) ([cde7a9d](https://github.com/n8n-io/n8n/commit/cde7a9dbd985ae9e83de2d39dccc508a41d9a676))
* **editor:** Explain a restricted model provider with the restriction popover ([#40705](https://github.com/n8n-io/n8n/issues/40705)) ([75de193](https://github.com/n8n-io/n8n/commit/75de193d9090d160dd191667adb85dc423951045))
* **editor:** Explain instance-role access in the credential sharing "Used in" row ([#40555](https://github.com/n8n-io/n8n/issues/40555)) ([48f05f9](https://github.com/n8n-io/n8n/commit/48f05f92fe9e7bd1c1d220a53a8c17055a17e70c))
* **editor:** Rebuild the command bar with type tabs and paged search ([#40461](https://github.com/n8n-io/n8n/issues/40461)) ([e36093b](https://github.com/n8n-io/n8n/commit/e36093b11db0580add10306d27d090a27790f4fb))
* **editor:** Rebuild the personal settings page with the design-system settings components ([#40298](https://github.com/n8n-io/n8n/issues/40298)) ([09436b7](https://github.com/n8n-io/n8n/commit/09436b78f9f6f320073f911ca11160ad9a66d94f))
* **editor:** Recommend Claude Opus 5.5 and GPT-6 models in AI Assistant setup ([#40660](https://github.com/n8n-io/n8n/issues/40660)) ([1ad3c54](https://github.com/n8n-io/n8n/commit/1ad3c54803569dd83976c055785b51b62555bf44))
* **editor:** Replace Windsurf with Devin in the MCP client dialog ([#40912](https://github.com/n8n-io/n8n/issues/40912)) ([e2c4054](https://github.com/n8n-io/n8n/commit/e2c4054cba14a2f1dc29215fc623f6ae42b7a238))
* **editor:** Show the restriction callout and lock the agent tool configuration form ([#40657](https://github.com/n8n-io/n8n/issues/40657)) ([01da889](https://github.com/n8n-io/n8n/commit/01da88958d490e5006874cce2b05554347301b9b))
* **editor:** Show who created each preference on the Preferences page ([#40868](https://github.com/n8n-io/n8n/issues/40868)) ([22ff2a0](https://github.com/n8n-io/n8n/commit/22ff2a06368b49fa25b0ad1c2cf74640c56a0284))
* **editor:** Sort the credential sharing list by people, then projects ([#40478](https://github.com/n8n-io/n8n/issues/40478)) ([02af7e7](https://github.com/n8n-io/n8n/commit/02af7e7659cce85749c719bb6a1b910043357baf))
* **Embeddings Azure OpenAI Node:** Add Entra ID authentication ([#39390](https://github.com/n8n-io/n8n/issues/39390)) ([830486a](https://github.com/n8n-io/n8n/commit/830486a851ceb3eeada1eb945e7cd11c05262901))
* **Google Gemini Node:** Show Nano Banana 2.1 and 2 Lite in the image model list ([#40596](https://github.com/n8n-io/n8n/issues/40596)) ([97c54f6](https://github.com/n8n-io/n8n/commit/97c54f618c6210bbe1dcfadaac702d40e89a820b))
* Make health check timeout configurable ([#39548](https://github.com/n8n-io/n8n/issues/39548)) ([df8605e](https://github.com/n8n-io/n8n/commit/df8605e8750443d66388060212306cd205a4f5d3))
* **Microsoft SharePoint Trigger Node:** Add the Microsoft SharePoint Trigger node ([#40055](https://github.com/n8n-io/n8n/issues/40055)) ([7c126fa](https://github.com/n8n-io/n8n/commit/7c126fab32772241473e1f180c6806af4ce189f8))
### Performance Improvements
* **core:** Keep agent builder system prompt static for prompt caching ([#40364](https://github.com/n8n-io/n8n/issues/40364)) ([ee1db0b](https://github.com/n8n-io/n8n/commit/ee1db0bc12bebb572afd04e6e53efc30ffa01209))
* **core:** Let the agent builder chain config writes without re-reading the config ([#40462](https://github.com/n8n-io/n8n/issues/40462)) ([6b4da93](https://github.com/n8n-io/n8n/commit/6b4da93dcbb909bcf86c03251e3c74033d0dd70f))
* **core:** Let the agent builder edit skill instructions in place ([#40447](https://github.com/n8n-io/n8n/issues/40447)) ([1de45a1](https://github.com/n8n-io/n8n/commit/1de45a1a9b0b0db7036cb25e27bffc95a7df41e2))
* **core:** Prepare Instance AI skill sandbox in the background ([#40363](https://github.com/n8n-io/n8n/issues/40363)) ([b36c2b5](https://github.com/n8n-io/n8n/commit/b36c2b506b92f391f859ec10067e57d96c8b09c8))
* **core:** Send agent builder config writes as objects with changed fields only ([#40666](https://github.com/n8n-io/n8n/issues/40666)) ([2aa3fbf](https://github.com/n8n-io/n8n/commit/2aa3fbf18547cfb6719baabdcd8719fa6d0f53af))
# [2.43.0](https://github.com/n8n-io/n8n/compare/n8n@2.42.0...n8n@2.43.0) (2026-10-06)

199
OWNERS
View File

@ -30,7 +30,6 @@ packages/@n8n/backend-network/ @n8n-io/catalysts
packages/@n8n/backend-services/ @n8n-io/catalysts
packages/@n8n/backend-services/src/services/role.service.ts @n8n-io/iam
packages/@n8n/backend-services/src/services/role-cache.service.ts @n8n-io/iam
packages/@n8n/backend-services/src/services/jwt.service.ts @n8n-io/iam
packages/@n8n/backend-test-utils/ @n8n-io/catalysts
packages/@n8n/di/ @n8n-io/catalysts
packages/@n8n/errors/ @n8n-io/catalysts
@ -53,20 +52,21 @@ packages/@n8n/db/src/migrations/ @n8n-io/migrations-revie
# Top-level paths
scripts/ @n8n-io/qa-dx
patches/ @n8n-io/qa-dx
assets/ @n8n-io/adore
security/ @n8n-io/qa-dx
.code-health-baseline.json @n8n-io/qa-dx required
OWNERS @n8n-io/qa-dx required
# @n8n/cli
packages/@n8n/cli/ @n8n-io/context
packages/@n8n/cli/ @n8n-io/adore
packages/@n8n/cli/src/commands/credential/ @n8n-io/iam
packages/@n8n/cli/src/commands/user/ @n8n-io/iam
packages/@n8n/cli/src/commands/data-table/ @n8n-io/knowledge
packages/@n8n/cli/src/commands/tag/ @n8n-io/context
packages/@n8n/cli/src/commands/data-table/ @n8n-io/adore
packages/@n8n/cli/src/commands/tag/ @n8n-io/adore
packages/@n8n/cli/src/commands/project/ @n8n-io/ligo
packages/@n8n/cli/src/commands/source-control/ @n8n-io/ligo
packages/@n8n/cli/src/commands/variable/ @n8n-io/ligo
packages/@n8n/cli/src/commands/skill/ @n8n-io/context
packages/@n8n/cli/src/commands/skill/ @n8n-io/ai
# packages/cli
packages/cli/ @n8n-io/catalysts
@ -85,6 +85,7 @@ packages/cli/src/security-audit/ @n8n-io/catalysts
packages/cli/src/modules/workflow-index/ @n8n-io/catalysts
packages/cli/src/modules/breaking-changes/ @n8n-io/catalysts
packages/cli/src/workflows/publication/ @n8n-io/catalysts required
packages/cli/src/modules/otel/ @n8n-io/ligo
packages/cli/src/auth/ @n8n-io/iam
packages/cli/src/credentials/ @n8n-io/iam
@ -108,22 +109,23 @@ packages/cli/src/environments.ee/ @n8n-io/ligo
packages/cli/src/public-api/ @n8n-io/ligo
packages/cli/src/modules/source-control.ee/ @n8n-io/ligo
packages/cli/src/modules/external-secrets.ee/ @n8n-io/ligo
packages/modules/insights/ @n8n-io/ligo
packages/cli/src/modules/insights/ @n8n-io/ligo
packages/cli/src/collaboration/ @n8n-io/catalysts
packages/cli/src/binary-data/ @n8n-io/catalysts
packages/cli/src/posthog/ @n8n-io/growth
packages/cli/src/modules/data-table/ @n8n-io/knowledge
packages/cli/src/posthog/ @n8n-io/adore
packages/cli/src/modules/data-table/ @n8n-io/adore
packages/cli/src/evaluation.ee/ @n8n-io/ai-trust
packages/cli/src/chat/ @n8n-io/ai-agents
packages/cli/src/modules/agents/ @n8n-io/ai-agents
packages/cli/src/evaluation.ee/ @n8n-io/ai
packages/cli/src/chat/ @n8n-io/ai
packages/cli/src/tool-generation/ @n8n-io/ai
packages/modules/workflow-builder/ @n8n-io/ai-assistant
packages/cli/src/modules/mcp/ @n8n-io/context
packages/cli/src/modules/workflow-builder/ @n8n-io/ai
packages/cli/src/modules/mcp/ @n8n-io/adore
packages/cli/src/modules/quick-connect/ @n8n-io/ai
packages/cli/src/modules/chat-hub/ @n8n-io/ai-assistant
packages/cli/src/modules/instance-ai/ @n8n-io/ai-assistant
packages/modules/inbox/ @n8n-io/ligo
packages/cli/src/modules/community-packages/ @n8n-io/nodes
# CLI controllers
packages/cli/src/controllers/auth.controller.ts @n8n-io/iam
@ -138,14 +140,14 @@ packages/cli/src/controllers/user-settings.controller.ts @n8n-io/iam
packages/cli/src/controllers/api-keys.controller.ts @n8n-io/iam
packages/cli/src/controllers/security-settings.controller.ts @n8n-io/iam
packages/cli/src/controllers/oauth/ @n8n-io/iam
packages/cli/src/controllers/ai.controller.ts @n8n-io/ai-assistant
packages/cli/src/controllers/ai.controller.ts @n8n-io/ai
packages/cli/src/controllers/annotation-tags.controller.ee.ts @n8n-io/ai
packages/cli/src/controllers/cta.controller.ts @n8n-io/knowledge
packages/cli/src/controllers/folder.controller.ts @n8n-io/context
packages/cli/src/controllers/tags.controller.ts @n8n-io/context
packages/cli/src/controllers/binary-data.controller.ts @n8n-io/knowledge
packages/cli/src/controllers/posthog.controller.ts @n8n-io/context
packages/cli/src/controllers/translation.controller.ts @n8n-io/catalysts
packages/cli/src/controllers/cta.controller.ts @n8n-io/adore
packages/cli/src/controllers/folder.controller.ts @n8n-io/adore
packages/cli/src/controllers/tags.controller.ts @n8n-io/adore
packages/cli/src/controllers/binary-data.controller.ts @n8n-io/adore
packages/cli/src/controllers/posthog.controller.ts @n8n-io/adore
packages/cli/src/controllers/translation.controller.ts @n8n-io/adore
packages/cli/src/controllers/project.controller.ts @n8n-io/ligo
packages/cli/src/controllers/workflow-statistics.controller.ts @n8n-io/ligo
packages/cli/src/controllers/node-types.controller.ts @n8n-io/nodes
@ -153,23 +155,22 @@ packages/cli/src/controllers/dynamic-node-parameters.controller.ts @n8n-io/node
packages/cli/src/controllers/e2e.controller.ts @n8n-io/qa-dx
# CLI services
packages/cli/src/services/jwt.service.ts @n8n-io/iam
packages/cli/src/services/user.service.ts @n8n-io/iam
packages/cli/src/services/password.utility.ts @n8n-io/iam
packages/cli/src/services/public-api-key.service.ts @n8n-io/iam
packages/cli/src/services/security-settings.service.ts @n8n-io/iam
packages/cli/src/services/static-auth-service.ts @n8n-io/iam
packages/cli/src/services/access.service.ts @n8n-io/iam
packages/cli/src/services/ai.service.ts @n8n-io/ai-assistant
packages/cli/src/services/ai-usage.service.ts @n8n-io/ai-assistant
packages/cli/src/services/__tests__/ai-usage.service.test.ts @n8n-io/ai-assistant
packages/cli/src/controllers/__tests__/ai.controller.test.ts @n8n-io/ai-assistant
packages/cli/src/services/ai-workflow-builder.service.ts @n8n-io/ai-assistant
packages/cli/src/services/annotation-tag.service.ee.ts @n8n-io/context
packages/cli/src/services/folder.service.ts @n8n-io/context
packages/cli/src/services/tag.service.ts @n8n-io/context
packages/cli/src/services/cta.service.ts @n8n-io/knowledge
packages/cli/src/services/frontend.service.ts @n8n-io/catalysts
packages/cli/src/services/banner.service.ts @n8n-io/context
packages/cli/src/services/ai.service.ts @n8n-io/ai
packages/cli/src/services/ai-usage.service.ts @n8n-io/ai
packages/cli/src/services/ai-workflow-builder.service.ts @n8n-io/ai
packages/cli/src/services/annotation-tag.service.ee.ts @n8n-io/ai
packages/cli/src/services/folder.service.ts @n8n-io/adore
packages/cli/src/services/tag.service.ts @n8n-io/adore
packages/cli/src/services/cta.service.ts @n8n-io/adore
packages/cli/src/services/frontend.service.ts @n8n-io/adore
packages/cli/src/services/banner.service.ts @n8n-io/adore
packages/cli/src/services/project.service.ee.ts @n8n-io/ligo
packages/cli/src/services/workflow-statistics.service.ts @n8n-io/ligo
packages/cli/src/services/export.service.ts @n8n-io/ligo
@ -177,11 +178,11 @@ packages/cli/src/services/import.service.ts @n8n-io/ligo
packages/cli/src/services/ownership.service.ts @n8n-io/ligo
packages/cli/src/services/dynamic-node-parameters.service.ts @n8n-io/nodes
# Adore
packages/frontend/editor-ui/ @n8n-io/frontend
packages/frontend/editor-ui/src/features/ai/ @n8n-io/ai
packages/frontend/editor-ui/src/features/ai/assistant/ @n8n-io/ai-assistant
packages/frontend/editor-ui/src/features/ai/chatHub/ @n8n-io/ai-assistant
packages/frontend/editor-ui/src/features/ai/instanceAi/ @n8n-io/ai-assistant
packages/frontend/editor-ui/src/features/credentials/ @n8n-io/iam
packages/frontend/editor-ui/src/features/execution/ @n8n-io/ligo
packages/frontend/editor-ui/src/features/integrations/ @n8n-io/ligo
@ -194,42 +195,15 @@ packages/frontend/@n8n/storybook/ @n8n-io/design-engineeri
packages/frontend/@n8n/i18n/ @n8n-io/frontend
packages/@n8n/stylelint-config/ @n8n-io/qa-dx
packages/frontend/editor-ui/src/features/ai/gateway/ @n8n-io/relay
packages/frontend/editor-ui/src/app/composables/useAiGatewayTopUp.ts @n8n-io/relay
packages/frontend/editor-ui/src/app/composables/useFreeAiCredits.ts @n8n-io/relay
packages/frontend/editor-ui/src/features/settings/communityNodes/ @n8n-io/nodes
packages/frontend/editor-ui/src/features/credentials/quickConnect/ @n8n-io/nodes required
packages/frontend/editor-ui/src/features/ndv/runData/schemaPreview.api.ts @n8n-io/nodes
packages/frontend/editor-ui/src/features/ndv/runData/schemaPreview.store.ts @n8n-io/nodes
packages/frontend/editor-ui/src/features/agents/channels/ @n8n-io/nodes
# AI
packages/@n8n/instance-ai/ @n8n-io/ai-assistant
packages/@n8n/nodes-langchain/ @n8n-io/ai
packages/@n8n/nodes-langchain/nodes/agents/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/chains/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/code/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/output_parser/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/llms/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/vendors/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/ModelSelector/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/embeddings/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/vector_store/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/document_loaders/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/text_splitters/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/retrievers/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/rerankers/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/memory/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/tools/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/ToolExecutor/ @n8n-io/ai-agents
packages/@n8n/nodes-langchain/nodes/trigger/ @n8n-io/ai-agents
packages/@n8n/ai-utilities/ @n8n-io/ai-agents
packages/@n8n/ai-workflow-builder.ee/ @n8n-io/ai-assistant
packages/@n8n/agents/ @n8n-io/ai-agents
packages/frontend/@n8n/chat/ @n8n-io/ai-agents
packages/frontend/editor-ui/src/features/agents/ @n8n-io/ai-agents
packages/@n8n/ai-utilities/ @n8n-io/ai
packages/@n8n/ai-node-sdk/ @n8n-io/ai
packages/@n8n/ai-workflow-builder.ee/ @n8n-io/ai
packages/@n8n/agents/ @n8n-io/ai
packages/frontend/@n8n/chat/ @n8n-io/ai
# Chat Hub
@ -244,7 +218,6 @@ packages/@n8n/nodes-langchain/nodes/vector_store/shared/chatHub.ts @n8n-io/ai-as
packages/@n8n/nodes-langchain/credentials/ChatHubVectorStorePGVectorApi.credentials.ts @n8n-io/ai-assistant
packages/@n8n/nodes-langchain/credentials/ChatHubVectorStorePineconeApi.credentials.ts @n8n-io/ai-assistant
packages/@n8n/nodes-langchain/credentials/ChatHubVectorStoreQdrantApi.credentials.ts @n8n-io/ai-assistant
packages/@n8n/nodes-langchain/nodes/mcp/ @n8n-io/nodes required
packages/frontend/editor-ui/src/features/shared/commandBar/composables/useChatHubCommands.ts @n8n-io/ai-assistant
packages/cli/src/modules/breaking-changes/rules/v3/chat-hub-deprecated.rule.ts @n8n-io/ai-assistant
@ -254,89 +227,37 @@ packages/@n8n/codemirror-lang/ @n8n-io/nodes
packages/@n8n/codemirror-lang-html/ @n8n-io/nodes
packages/@n8n/codemirror-lang-sql/ @n8n-io/nodes
packages/nodes-base/ @n8n-io/nodes
packages/nodes-base/nodes/Code/ @n8n-io/nodes required
packages/nodes-base/nodes/ExecuteCommand/ @n8n-io/nodes required
packages/nodes-base/nodes/Ssh/ @n8n-io/nodes required
packages/nodes-base/nodes/HttpRequest/ @n8n-io/nodes required
packages/nodes-base/nodes/Webhook/ @n8n-io/nodes required
packages/nodes-base/nodes/RespondToWebhook/ @n8n-io/nodes required
packages/nodes-base/nodes/Form/ @n8n-io/nodes required
packages/nodes-base/nodes/Wait/ @n8n-io/nodes required
packages/nodes-base/utils/sendAndWait/ @n8n-io/nodes required
packages/nodes-base/nodes/Git/ @n8n-io/nodes required
packages/@n8n/decorators/ @n8n-io/catalysts
packages/node-dev/ @n8n-io/nodes
packages/@n8n/imap/ @n8n-io/nodes
packages/@n8n/computer-use/ @n8n-io/nodes required
packages/@n8n/local-gateway/ @n8n-io/nodes required
packages/@n8n/mcp-browser/ @n8n-io/nodes required
packages/@n8n/mcp-browser-extension/ @n8n-io/nodes required
packages/modules/quick-connect/ @n8n-io/nodes required
packages/@n8n/api-types/src/dto/quick-connect/ @n8n-io/nodes required
packages/@n8n/api-types/src/quick-connect.ts @n8n-io/nodes required
packages/cli/src/modules/community-packages/ @n8n-io/nodes
packages/cli/src/modules/mcp-registry/ @n8n-io/nodes required
packages/cli/src/modules/agents/integrations/ @n8n-io/nodes
packages/@n8n/api-types/src/schemas/mcp-registry.schema.ts @n8n-io/nodes required
packages/cli/templates/send-and-wait-no-action-required.handlebars @n8n-io/nodes required
packages/@n8n/ai-node-sdk/ @n8n-io/nodes required
# Relay (AI gateway & credits)
packages/cli/src/services/ai-gateway.service.ts @n8n-io/relay required
packages/cli/src/services/ai-gateway-eligibility.ts @n8n-io/relay required
packages/cli/src/services/free-ai-credits.service.ts @n8n-io/relay required
packages/@n8n/config/src/configs/ai-gateway.config.ts @n8n-io/relay
packages/@n8n/api-types/src/dto/ai/ai-gateway-config-response.dto.ts @n8n-io/relay
packages/@n8n/api-types/src/dto/ai/ai-gateway-usage-response.dto.ts @n8n-io/relay
packages/@n8n/api-types/src/dto/ai/ai-gateway-wallet-response.dto.ts @n8n-io/relay
packages/cli/src/modules/instance-ai/instance-ai-gateway.service.ts @n8n-io/relay
packages/cli/src/modules/mcp/mcp-ai-gateway.helper.ts @n8n-io/relay
packages/cli/src/modules/agents/json-config/node-tool-ai-gateway.service.ts @n8n-io/relay
packages/frontend/editor-ui/src/app/stores/aiGateway.store.ts @n8n-io/relay
packages/frontend/editor-ui/src/app/composables/useAiGateway.ts @n8n-io/relay
packages/frontend/editor-ui/src/features/credentials/gatewayCreditsPromotion/ @n8n-io/relay
packages/frontend/editor-ui/src/features/shared/nodeCreator/components/SectionHeaderCreditsTag.vue @n8n-io/relay
packages/@n8n/create-node/ @n8n-io/nodes
packages/@n8n/node-cli/ @n8n-io/community-engineering
packages/@n8n/imap/ @n8n-io/iam
packages/@n8n/syslog-client/ @n8n-io/iam
packages/@n8n/scan-community-package/ @n8n-io/community-engineering
packages/@n8n/eslint-plugin-community-nodes/ @n8n-io/community-engineering
packages/@n8n/computer-use/ @n8n-io/nodes
packages/@n8n/local-gateway/ @n8n-io/nodes
packages/@n8n/mcp-browser/ @n8n-io/nodes
packages/@n8n/mcp-browser-extension/ @n8n-io/nodes
# Community engineering
.agents/skills/create-community-node-lint-rule/ @n8n-io/community-engineering
.agents/skills/community-pr-readiness-check/ @n8n-io/community-engineering
packages/@n8n/scan-community-package/ @n8n-io/community-engineering
packages/@n8n/eslint-plugin-community-nodes/ @n8n-io/community-engineering
packages/@n8n/node-cli/ @n8n-io/community-engineering
packages/@n8n/create-node/ @n8n-io/community-engineering
# IAM
packages/@n8n/permissions/ @n8n-io/iam
packages/@n8n/client-oauth2/ @n8n-io/iam
packages/@n8n/inbound-auth/ @n8n-io/iam
packages/@n8n/syslog-client/ @n8n-io/iam
# LiGo
packages/extensions/insights/ @n8n-io/ligo
# Governance & Observability
packages/modules/type-availability-policies/ @n8n-io/governance-and-observability
packages/cli/src/modules/type-availability-policies/ @n8n-io/governance-and-observability
packages/modules/otel/ @n8n-io/governance-and-observability
packages/cli/src/modules/otel/ @n8n-io/governance-and-observability
packages/cli/src/public-api/v1/controllers/otel.public.controller.ts @n8n-io/governance-and-observability
packages/cli/src/public-api/v1/shared/otel.mapper.ts @n8n-io/governance-and-observability
packages/cli/src/public-api/v1/controllers/node-type-policies.public.controller.ts @n8n-io/governance-and-observability
packages/cli/src/public-api/v1/controllers/credential-type-policies.public.controller.ts @n8n-io/governance-and-observability
packages/cli/src/public-api/v1/handlers/node-type-policies/ @n8n-io/governance-and-observability
packages/cli/src/public-api/v1/handlers/credential-type-policies/ @n8n-io/governance-and-observability
packages/cli/src/modules/policy-infrastructure/ @n8n-io/governance-and-observability
packages/cli/src/policy/ @n8n-io/governance-and-observability
packages/@n8n/decorators/src/policy-check/ @n8n-io/governance-and-observability
packages/@n8n/api-types/src/dto/otel/ @n8n-io/governance-and-observability
packages/@n8n/api-types/src/dto/type-availability-policies/ @n8n-io/governance-and-observability
packages/@n8n/api-types/src/node-type-availability.ts @n8n-io/governance-and-observability
packages/@n8n/api-types/src/credential-type-availability.ts @n8n-io/governance-and-observability
packages/@n8n/api-types/src/schemas/policy-check-failure.schema.ts @n8n-io/governance-and-observability
packages/@n8n/api-types/src/schemas/policy-violation.schema.ts @n8n-io/governance-and-observability
packages/@n8n/telemetry/src/events/policies.ts @n8n-io/governance-and-observability
packages/@n8n/telemetry/src/events/type-availability-policies.ts @n8n-io/governance-and-observability
packages/workflow/src/errors/policy-refusal.ts @n8n-io/governance-and-observability
packages/frontend/editor-ui/src/app/composables/usePolicyViolationToast.ts @n8n-io/governance-and-observability
# CI/CD
@ -364,15 +285,3 @@ packages/@n8n/db/src/entities/deployment-key.ts @n8n-io/iam required
packages/@n8n/db/src/repositories/deployment-key.repository.ts @n8n-io/iam required
packages/@n8n/eslint-config/src/configs/encryption-boundary.ts @n8n-io/iam required
packages/@n8n/eslint-config/src/rules/no-encryption-guardrail-disable.ts @n8n-io/iam required
# AI Trust (evaluations)
# Placed last so these rules override the broader package rules above.
packages/@n8n/instance-ai/evaluations/ @n8n-io/ai-trust
packages/cli/src/modules/instance-ai/eval/ @n8n-io/ai-trust
packages/quality/testing/playwright/tests/evals/instance-ai/ @n8n-io/ai-trust
.agents/skills/create-instance-ai-eval/ @n8n-io/ai-trust
.agents/skills/create-agent-builder-eval/ @n8n-io/ai-trust
packages/cli/src/modules/agent-evals/ @n8n-io/ai-trust
packages/@n8n/agents/src/evals/ @n8n-io/ai-trust
packages/frontend/editor-ui/src/features/ai/evaluation.ee/ @n8n-io/ai-trust

View File

@ -1,6 +1,6 @@
{
"repository": "n8n-io/cat-bot",
"releaseTag": "harness-v0.6.0",
"version": "0.6.0",
"assetName": "n8n-opencode-harness-0.6.0.tgz"
"releaseTag": "harness-v0.3.0",
"version": "0.3.0",
"assetName": "n8n-opencode-harness-0.3.0.tgz"
}

View File

@ -1,7 +1,7 @@
# Every n8n image build uses this file. `pnpm build:docker` and CI both drive
# these targets, so a pin changed here changes both.
variable "NODE_VERSION" { default = "26.10.0" }
variable "NODE_VERSION" { default = "26.7.0" }
variable "N8N_VERSION" { default = "snapshot" }
variable "N8N_RELEASE_TYPE" { default = "dev" }
@ -15,14 +15,14 @@ variable "BUILDER_IMAGE" { default = "" }
variable "RUNTIME_IMAGE" { default = "" }
variable "PC_BUILDER_IMAGE" {
default = "n8nio/node-pc:26.10.0-dev@sha256:61e4b1f3b3824ffb908812e01bcbddabb64a01ef23d408d561696c344c6679e3"
default = "n8nio/node-pc:26.7.0-dev@sha256:c64642dcb9464e50bd08aef8504affafeb795d01aed2f7ab158976c334a36ef6"
}
variable "PC_RUNTIME_IMAGE" {
default = "n8nio/node-pc:26.10.0@sha256:386bae24d41c0091d21b4eee124a86464710fff24d5cb7f37386c4c5649b0c89"
default = "n8nio/node-pc:26.7.0@sha256:6577d0742ad043baaa39db7dda2ce8aeb73f32c84eb241c49bf716f170c53297"
}
variable "DHI_REF" {
default = "dhi.io/node:26.10.0-alpine3.24-dev@sha256:8da859df5dc853c923ace53c4cfe994a909a28917f7fcfc8508869beab8cf132"
default = "dhi.io/node:26.7.0-alpine3.24-dev@sha256:4b494d89fb26c950ce97865acf45b480dc7a6868fdc2b81c2d66599702eeac3f"
}
variable "N8N_TAGS" { default = "" }

View File

@ -15,11 +15,11 @@ set -eu
SCRIPT_VERSION="1.4.0"
# The version to install is derived from the latest stable GitHub release in
# resolve_n8n_version(); this fallback only applies when that lookup fails.
FALLBACK_N8N_VERSION="2.43.4"
FALLBACK_N8N_VERSION="2.32.0"
# Sandbox service release (API, runner and sandbox images ship together).
# Pinned here, not resolved at run time: the stack definition must match it.
# --upgrade moves existing installs to this pin.
SANDBOX_VERSION="1.8.1"
SANDBOX_VERSION="1.3.4"
N8N_DIR="${N8N_DIR:-./n8n}"
N8N_PORT=5678
SOURCE_URL="https://github.com/n8n-io/n8n/blob/master/docker/get-n8n.sh"

View File

@ -1,6 +1,6 @@
# CI passes one DHI reference per published Node version (see the matrix in
# build-base-image.yml). The default keeps plain `docker build` working.
ARG DHI_REF=dhi.io/node:24.21.0-alpine3.24-dev@sha256:d22ba0e9ab2a54609ae533df4ebfd6f36c1f233b662a4c547f5a3195e8c21937
ARG DHI_REF=dhi.io/node:24.19.0-alpine3.24-dev@sha256:dc2989ad23938772abaf549ed7bde5d61d70377005229bb55bef94bff40f8bbd
FROM ${DHI_REF}
# Install all dependencies in a single layer to minimize image size

View File

@ -1,9 +1,9 @@
ARG NODE_VERSION=26.10.0
ARG NODE_VERSION=26.7.0
ARG N8N_VERSION=snapshot
# The digest pins node:26.10.0-alpine3.24 for amd64 and arm64. Change the tag and the digest together.
ARG BUILDER_IMAGE=node:26.10.0-alpine3.24@sha256:0b36e8c136b94cd4fcf02188228e76c31ad5872eef3fec8cbd2eee500cfd9e80
ARG RUNTIME_IMAGE=n8nio/base:26.10.0@sha256:9205c76a7745bfe71de35c2a0b7420238ccb0bdf69fc5273ab2e617fe918cf5f
# The digest pins node:26.7.0-alpine3.24 for amd64 and arm64. Change the tag and the digest together.
ARG BUILDER_IMAGE=node:26.7.0-alpine3.24@sha256:aadf416b2cdce311a8811ba3f0608a61b77dbf997500e2eafe781b51f6a0b019
ARG RUNTIME_IMAGE=n8nio/base:26.7.0@sha256:33687300c4e94dc00f42ec79ae15082ae07330ecd82ae1167125905b65908ff8
# The runtime base has no compiler, so this stage supplies one.
FROM ${BUILDER_IMAGE} AS toolchain

View File

@ -10,14 +10,14 @@
# dev - plain Alpine with apk usable, for the n8n builder
# stage, which must compile native addons against this
# Node's headers
ARG NODE_VERSION=26.10.0
ARG NODE_VERSION=26.7.0
# Compiling V8 needs 1.5-2 GB of memory per parallel job. Lower this on
# builders whose memory-to-core ratio cannot cover all cores.
ARG MAKE_JOBS=
# Pinned to a multi-arch index digest (linux/amd64 + linux/arm64) for reproducible builds.
# Bump the tag and digest together when updating.
FROM alpine:3.24@sha256:294b683cb724975bec92580e1e685676bd4b50bda910ddb8c51d4cabeaec77e6 AS builder
FROM alpine:3.24@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b AS builder
ARG NODE_VERSION
ARG MAKE_JOBS
@ -70,7 +70,7 @@ RUN apk add --no-cache --virtual .build-deps \
# Remove unused OpenSSL headers to save ~34MB. See https://github.com/nodejs/node/issues/46451
&& find /node-install/usr/local/include/node/openssl/archs -mindepth 1 -maxdepth 1 ! -name "$OPENSSL_ARCH" -exec rm -rf {} \;
FROM alpine:3.24@sha256:294b683cb724975bec92580e1e685676bd4b50bda910ddb8c51d4cabeaec77e6 AS base
FROM alpine:3.24@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b AS base
RUN addgroup -g 1000 node \
&& adduser -u 1000 -G node -s /bin/sh -D node \
@ -90,7 +90,7 @@ ENV npm_config_nodedir=/usr/local
# npx, corepack) are swapped for the pointer-compressed build's files.
# Pinned to a multi-arch index digest (linux/amd64 + linux/arm64) for reproducible builds.
# Bump the tag and digest together when updating.
FROM n8nio/base:26.10.0@sha256:9205c76a7745bfe71de35c2a0b7420238ccb0bdf69fc5273ab2e617fe918cf5f AS runtime
FROM n8nio/base:26.7.0@sha256:33687300c4e94dc00f42ec79ae15082ae07330ecd82ae1167125905b65908ff8 AS runtime
RUN rm -f /usr/bin/node /usr/bin/nodejs /usr/bin/npm /usr/bin/npx /usr/bin/corepack /usr/local/bin/node
COPY --from=builder /node-install/usr/local /usr/local

View File

@ -1,4 +1,4 @@
ARG NODE_VERSION=26.10.0
ARG NODE_VERSION=26.7.0
ARG PNPM_VERSION=12.4.2
ARG PYTHON_VERSION=3.13

View File

@ -12,7 +12,7 @@
# - Uses distroless nonroot user (UID 65532)
# ==============================================================================
ARG NODE_VERSION=26.10.0
ARG NODE_VERSION=26.7.0
ARG PNPM_VERSION=12.4.2
ARG PYTHON_VERSION=3.13

View File

@ -1,183 +0,0 @@
# Architecture Decision Records
An Architecture Decision Record (ADR) is a short, dated record of one
important technical decision: the context, the decision, the alternatives,
and the consequences.
The company process is defined in the Notion page
[Engineering Technical Decisions][process] and its sub-page
[Architecture Decision Records][adr-page].
This README applies that process to this repository and records the
conventions that the reviews of the first records settled.
## When to write an ADR
Write an ADR when the reason for a decision can matter in the future. The
test from the company process: if an engineer challenges this choice in 12
months, will the original context and alternatives help them?
Write one record for each decision. The test: can this decision be reversed on
its own? If yes, it gets its own file. Do not put two independent decisions
into one record.
Do not write an ADR for an implementation detail, a refactor, or a choice that
follows an existing decision.
## Location
Store a record in the package where the implementation lives, in its
`docs/adr/` directory. For example, a record about engine v2 goes in
`packages/@n8n/engine/docs/adr/`. A record that concerns the whole repository
goes in the root `docs/adr/`, next to this README. CI rejects any other
location.
## File name
The file name follows from the title and the date:
```text
ADR-YYYYMMDD-<title in kebab-case>.md
```
The title is the H1 of the record. It states the decision, not the topic:
"Use PostgreSQL advisory locks", not "Database locking". The date is the date
of the decision, and it matches the `Date` field. CI checks both.
Do not rename a record after it is merged. Links depend on the file name.
Refer to a record by its full file name, for example
`ADR-20260828-obtain-trigger-output-before-creating-the-execution`, not by a
number. CI checks that every record ID a record mentions names a file.
## Template
Copy [`docs/ADR_TEMPLATE.md`](../ADR_TEMPLATE.md) from the repository root.
It is the one template, and CI checks every record against its structure.
The header has three required fields, `Date`, `Status`, and `Decision Owner`,
in that order, and three optional fields, `Source`, `Supersedes`, and
`Superseded by`. Omit an optional field that has no value. `Source` names
where the decision came from: a ticket, an RFC, or an incident. The body
names none of these. The `RFC` field under `Links` holds the link to the RFC.
## Status
Use one of three values:
- **Active.** The decision stands.
- **Superseded.** A newer record replaced the decision. Link to it in
`Superseded by`.
- **Deprecated.** The decision no longer applies and no record replaces it.
There is no Draft or Proposed status. The pull request holds that state while
the record is written and checked.
The status says whether the decision stands. It does not say whether the code
exists. Implementation progress belongs nowhere in the record.
## What goes where
**Context.** The problem and the constraints. State the world as it is, in
the present tense: "In engine v1, `putExecutionToWait` sleeps in the process
for a time wait under 65 seconds." Do not date a fact ("at the date of this
record"), do not narrate history ("core has since decided"), and do not phase
work ("the shim's part lands later"). The record is dated once, in its header.
Aim for fewer than 150 words.
**Decision.** What we decided, and the main reason. State the behaviour the
decision guarantees, in the present tense and the active voice: "A wait fires
at its deadline and not before it. A wait fires once, however many replicas
run." Describe the mechanism only when the mechanism is the decision. A sweep
that sleeps until the next deadline is how the engine fires waits today; the
guarantee is what the record decides. Do not write implementation state here.
A sentence such as "the engine does not do this yet" goes stale exactly where
a reader takes the text as the current contract.
**Alternatives Considered.** Each option we did not select, and why. Lead with
the reason: "We rejected it for two reasons." An option that reads as an equal
choice leaves the reader to guess why it lost. Use the conditional mood for
what an alternative would do: "This option would need a column." The
indicative mood ("this option needs a column") reads as a description of
shipped code.
**Consequences.** What follows from the decision: benefits, trade-offs,
constraints, and operational effects. A constraint on the mechanism belongs
here: "One statement must read the step rows and write the status." How the
code meets the constraint today, and the order in which the work lands, do
not. This is the one section that may grow after the record is merged. A
consequence that the team learned later belongs here. A changed decision does
not.
**Links.** Exactly three fields, each on one line: `RFC`, `Documentation`, and
`Related ADRs`. Write `-` when a field has no value. Name related records by
full file name. There is no `Tickets` field.
## Changing a decision
A merged record is history. Do not edit its Context, Decision, or Alternatives
to reflect a later change. Write a new record instead.
Therefore a change to the Context, the Decision, or the Alternatives rides the
pull request that merges the record. In a stack, the change belongs in the
first pull request that carries the record, not in the follow-up that
implements it. A decision can merge before its code. That is normal, and not a
reason to move or edit the record.
When a new decision replaces an old one:
1. Write a new record. Explain the new context.
2. Set `Supersedes` in the new record and `Superseded by` in the old one.
3. Set the old record's status to `Superseded`.
When a decision no longer applies and nothing replaces it, set its status to
`Deprecated`.
## Style
- Write in ASD-STE100 Simplified Technical English, as `AGENTS.md` requires:
short sentences, the active voice, one idea for each sentence.
- Wrap paragraph lines at 100 columns. CI enforces it. The `Links` fields
are exempt and stay on one line each.
- Do not reference a ticket in the body. Every sentence must stand without
the ID: "Send-and-wait nodes need credentials to send their message." The
`Source` field is the one place for a ticket.
- Use plain words. "Nothing moves a step from `waiting` to `completed` in one
step" beats "No component completes a waiting step directly".
- Keep the record short. A reader should understand the decision in a few
minutes without the pull request or the design document.
- Use a Mermaid diagram when a picture says it better than prose.
## Checked by CI
The `adr-conventions` rule of `@n8n/code-health` runs in the Static Analysis
check of every pull request. For every `ADR-*.md` file it checks:
- a `docs/adr` directory at the repository root or at a package root;
- a file name that matches the H1 and the `Date` field;
- the header fields, their order, and one blank line between them;
- a `Decision Owner` from the allowed list in
`packages/quality/policy/code-health/src/index.ts`;
- a full file name in `Supersedes` and `Superseded by`;
- exactly the five sections, in order, each with content;
- the three `Links` fields, one line each;
- paragraph lines of at most 100 characters outside `Links`;
- that every record ID the record mentions is a full ID that names a file in
this repository. A date alone, `ADR-20260902`, is rejected.
Run it locally:
```bash
pnpm --filter=@n8n/code-health check --rule=adr-conventions --ignore-baseline
```
## Process
1. The decision is made: in an RFC, a design review, a team discussion, or a
pull request.
2. The Decision Owner, or a delegate, writes the record.
3. Open a pull request. The review checks that the record is accurate and
clear. It does not reopen the decision.
4. Merge. The record is `Active`.
5. Implementation pull requests link to the record they implement.
[process]: https://app.notion.com/p/n8n/3bd5b6e0c94f804bac20ecc31500ce37
[adr-page]: https://app.notion.com/p/n8n/3bf5b6e0c94f8046b204c4b50533ec8b

View File

@ -19,7 +19,7 @@ Auto-generated from the PostgreSQL migrations in @n8n/db. Do not edit by hand.
| [public.agent_credential_dependency](public.agent_credential_dependency.md) | 3 | | BASE TABLE |
| [public.agent_eval_dataset](public.agent_eval_dataset.md) | 10 | | BASE TABLE |
| [public.agent_eval_rating](public.agent_eval_rating.md) | 8 | | BASE TABLE |
| [public.agent_eval_result](public.agent_eval_result.md) | 16 | | BASE TABLE |
| [public.agent_eval_result](public.agent_eval_result.md) | 15 | | BASE TABLE |
| [public.agent_eval_run](public.agent_eval_run.md) | 14 | | BASE TABLE |
| [public.agent_execution](public.agent_execution.md) | 23 | | BASE TABLE |
| [public.agent_execution_message_links](public.agent_execution_message_links.md) | 5 | | BASE TABLE |
@ -29,14 +29,12 @@ Auto-generated from the PostgreSQL migrations in @n8n/db. Do not edit by hand.
| [public.agent_message_queue](public.agent_message_queue.md) | 10 | | BASE TABLE |
| [public.agent_plan](public.agent_plan.md) | 8 | | BASE TABLE |
| [public.agent_plan_history](public.agent_plan_history.md) | 6 | | BASE TABLE |
| [public.agent_skill_dependency](public.agent_skill_dependency.md) | 4 | | BASE TABLE |
| [public.agent_task_definition](public.agent_task_definition.md) | 8 | | BASE TABLE |
| [public.agent_task_run_lock](public.agent_task_run_lock.md) | 6 | | BASE TABLE |
| [public.agent_task_snapshot](public.agent_task_snapshot.md) | 9 | | BASE TABLE |
| [public.agent_thread_grants](public.agent_thread_grants.md) | 4 | | BASE TABLE |
| [public.agent_version_skill_dependency](public.agent_version_skill_dependency.md) | 4 | | BASE TABLE |
| [public.agent_workflow_dependency](public.agent_workflow_dependency.md) | 3 | | BASE TABLE |
| [public.agents](public.agents.md) | 15 | | BASE TABLE |
| [public.agents](public.agents.md) | 14 | | BASE TABLE |
| [public.agents_memory_entries](public.agents_memory_entries.md) | 13 | | BASE TABLE |
| [public.agents_memory_entry_candidates](public.agents_memory_entry_candidates.md) | 14 | | BASE TABLE |
| [public.agents_memory_entry_locks](public.agents_memory_entry_locks.md) | 6 | | BASE TABLE |
@ -77,7 +75,6 @@ Auto-generated from the PostgreSQL migrations in @n8n/db. Do not edit by hand.
| [public.execution_metadata](public.execution_metadata.md) | 4 | | BASE TABLE |
| [public.folder](public.folder.md) | 6 | | BASE TABLE |
| [public.folder_tag](public.folder_tag.md) | 2 | | BASE TABLE |
| [public.idempotency_key](public.idempotency_key.md) | 9 | | BASE TABLE |
| [public.insights_by_period](public.insights_by_period.md) | 6 | | BASE TABLE |
| [public.insights_metadata](public.insights_metadata.md) | 5 | | BASE TABLE |
| [public.insights_raw](public.insights_raw.md) | 5 | | BASE TABLE |
@ -105,7 +102,6 @@ Auto-generated from the PostgreSQL migrations in @n8n/db. Do not edit by hand.
| [public.mcp_registry_server](public.mcp_registry_server.md) | 7 | | BASE TABLE |
| [public.migration_finding](public.migration_finding.md) | 10 | | BASE TABLE |
| [public.migration_finding_sync](public.migration_finding_sync.md) | 3 | | BASE TABLE |
| [public.migration_workflow_owner](public.migration_workflow_owner.md) | 7 | | BASE TABLE |
| [public.oauth_access_tokens](public.oauth_access_tokens.md) | 3 | | BASE TABLE |
| [public.oauth_authorization_codes](public.oauth_authorization_codes.md) | 13 | | BASE TABLE |
| [public.oauth_clients](public.oauth_clients.md) | 10 | | BASE TABLE |
@ -121,30 +117,24 @@ Auto-generated from the PostgreSQL migrations in @n8n/db. Do not edit by hand.
| [public.promotion_connection](public.promotion_connection.md) | 7 | | BASE TABLE |
| [public.promotion_connection_project](public.promotion_connection_project.md) | 4 | | BASE TABLE |
| [public.promotion_provider](public.promotion_provider.md) | 8 | | BASE TABLE |
| [public.promotion_review](public.promotion_review.md) | 10 | | BASE TABLE |
| [public.promotion_run](public.promotion_run.md) | 8 | | BASE TABLE |
| [public.role](public.role.md) | 7 | | BASE TABLE |
| [public.role_mapping_rule](public.role_mapping_rule.md) | 7 | | BASE TABLE |
| [public.role_mapping_rule_project](public.role_mapping_rule_project.md) | 2 | | BASE TABLE |
| [public.role_scope](public.role_scope.md) | 2 | | BASE TABLE |
| [public.scheduled_job](public.scheduled_job.md) | 25 | | BASE TABLE |
| [public.scheduled_task](public.scheduled_task.md) | 19 | | BASE TABLE |
| [public.scheduled_job](public.scheduled_job.md) | 24 | | BASE TABLE |
| [public.scheduled_task](public.scheduled_task.md) | 18 | | BASE TABLE |
| [public.scope](public.scope.md) | 3 | | BASE TABLE |
| [public.secrets_provider_connection](public.secrets_provider_connection.md) | 7 | | BASE TABLE |
| [public.self_healing_result](public.self_healing_result.md) | 15 | | BASE TABLE |
| [public.settings](public.settings.md) | 3 | | BASE TABLE |
| [public.shared_credentials](public.shared_credentials.md) | 5 | | BASE TABLE |
| [public.shared_workflow](public.shared_workflow.md) | 5 | | BASE TABLE |
| [public.skill](public.skill.md) | 7 | | BASE TABLE |
| [public.skill_file](public.skill_file.md) | 5 | | BASE TABLE |
| [public.skill_version](public.skill_version.md) | 11 | | BASE TABLE |
| [public.tag_entity](public.tag_entity.md) | 4 | | BASE TABLE |
| [public.test_case_execution](public.test_case_execution.md) | 14 | | BASE TABLE |
| [public.test_run](public.test_run.md) | 16 | | BASE TABLE |
| [public.token_exchange_jti](public.token_exchange_jti.md) | 3 | | BASE TABLE |
| [public.trusted_key](public.trusted_key.md) | 4 | | BASE TABLE |
| [public.trusted_key_source](public.trusted_key_source.md) | 8 | | BASE TABLE |
| [public.trusted_source](public.trusted_source.md) | 15 | | BASE TABLE |
| [public.trusted_source](public.trusted_source.md) | 12 | | BASE TABLE |
| [public.trusted_source_identity](public.trusted_source_identity.md) | 8 | | BASE TABLE |
| [public.type_availability_policy](public.type_availability_policy.md) | 7 | | BASE TABLE |
| [public.type_availability_policy_attachment](public.type_availability_policy_attachment.md) | 6 | | BASE TABLE |
@ -171,8 +161,8 @@ Auto-generated from the PostgreSQL migrations in @n8n/db. Do not edit by hand.
| [public.workflow_review_request_workflow](public.workflow_review_request_workflow.md) | 5 | | BASE TABLE |
| [public.workflow_statistics](public.workflow_statistics.md) | 7 | | BASE TABLE |
| [public.workflow_statistics_delta](public.workflow_statistics_delta.md) | 6 | | BASE TABLE |
| [public.workflow_suggestion](public.workflow_suggestion.md) | 16 | | BASE TABLE |
| [public.workflow_suggestion_activity](public.workflow_suggestion_activity.md) | 7 | | BASE TABLE |
| [public.workflow_suggestion](public.workflow_suggestion.md) | 11 | | BASE TABLE |
| [public.workflow_suggestion_activity](public.workflow_suggestion_activity.md) | 6 | | BASE TABLE |
| [public.workflows_tags](public.workflows_tags.md) | 2 | | BASE TABLE |
## Stored procedures and functions
@ -230,19 +220,13 @@ erDiagram
"public.agent_message_queue" }o--|| "public.agent_execution_threads" : "FOREIGN KEY (#quot;threadId#quot;) REFERENCES agent_execution_threads(id) ON DELETE CASCADE"
"public.agent_plan" }o--|| "public.agent_execution_threads" : "FOREIGN KEY (#quot;threadId#quot;) REFERENCES agent_execution_threads(id) ON DELETE CASCADE"
"public.agent_plan_history" }o--|| "public.agent_plan" : "FOREIGN KEY (#quot;planId#quot;) REFERENCES agent_plan(id) ON DELETE CASCADE"
"public.agent_skill_dependency" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agent_skill_dependency" }o--|| "public.skill" : "FOREIGN KEY (#quot;skillId#quot;) REFERENCES skill(id) ON DELETE CASCADE"
"public.agent_skill_dependency" }o--o| "public.skill_version" : "FOREIGN KEY (#quot;skillVersionId#quot;) REFERENCES skill_version(id)"
"public.agent_task_definition" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agent_task_run_lock" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agent_task_snapshot" }o--|| "public.agent_history" : "FOREIGN KEY (#quot;versionId#quot;) REFERENCES agent_history(#quot;versionId#quot;) ON DELETE CASCADE"
"public.agent_thread_grants" }o--|| "public.agent_execution_threads" : "FOREIGN KEY (#quot;threadId#quot;) REFERENCES agent_execution_threads(id) ON DELETE CASCADE"
"public.agent_version_skill_dependency" }o--|| "public.agent_history" : "FOREIGN KEY (#quot;agentVersionId#quot;) REFERENCES agent_history(#quot;versionId#quot;) ON DELETE CASCADE"
"public.agent_version_skill_dependency" }o--|| "public.skill" : "FOREIGN KEY (#quot;skillId#quot;) REFERENCES skill(id) ON DELETE CASCADE"
"public.agent_version_skill_dependency" }o--|| "public.skill_version" : "FOREIGN KEY (#quot;skillVersionId#quot;) REFERENCES skill_version(id)"
"public.agent_workflow_dependency" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.agent_workflow_dependency" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agents" }o--o| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.agents" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.agents" }o--o| "public.agent_history" : "FOREIGN KEY (#quot;activeVersionId#quot;) REFERENCES agent_history(#quot;versionId#quot;) ON DELETE SET NULL"
"public.agents_memory_entries" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agents_memory_entries" }o--|| "public.agents_resources" : "FOREIGN KEY (#quot;resourceId#quot;) REFERENCES agents_resources(id) ON DELETE CASCADE"
@ -314,7 +298,6 @@ erDiagram
"public.folder" }o--o| "public.folder" : "FOREIGN KEY (#quot;parentFolderId#quot;) REFERENCES folder(id) ON DELETE CASCADE"
"public.folder_tag" }o--|| "public.tag_entity" : "FOREIGN KEY (#quot;tagId#quot;) REFERENCES tag_entity(id) ON DELETE CASCADE"
"public.folder_tag" }o--|| "public.folder" : "FOREIGN KEY (#quot;folderId#quot;) REFERENCES folder(id) ON DELETE CASCADE"
"public.idempotency_key" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.insights_by_period" }o--|| "public.insights_metadata" : "FOREIGN KEY (#quot;metaId#quot;) REFERENCES insights_metadata(#quot;metaId#quot;) ON DELETE CASCADE"
"public.insights_metadata" }o--o| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE SET NULL"
"public.insights_metadata" }o--o| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE SET NULL"
@ -343,9 +326,6 @@ erDiagram
"public.instance_ai_threads" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.instance_credential_assignment" }o--|| "public.credentials_entity" : "FOREIGN KEY (#quot;credentialId#quot;) REFERENCES credentials_entity(id) ON DELETE RESTRICT"
"public.migration_finding" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.migration_workflow_owner" }o--o| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.migration_workflow_owner" }o--o| "public.user" : "FOREIGN KEY (#quot;assignedById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.migration_workflow_owner" |o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.oauth_access_tokens" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.oauth_access_tokens" }o--|| "public.oauth_clients" : "FOREIGN KEY (#quot;clientId#quot;) REFERENCES oauth_clients(id) ON DELETE CASCADE"
"public.oauth_authorization_codes" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
@ -367,33 +347,16 @@ erDiagram
"public.promotion_connection" }o--|| "public.promotion_provider" : "FOREIGN KEY (#quot;providerId#quot;) REFERENCES promotion_provider(id) ON DELETE RESTRICT"
"public.promotion_connection_project" |o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.promotion_connection_project" }o--|| "public.promotion_connection" : "FOREIGN KEY (#quot;connectionId#quot;) REFERENCES promotion_connection(id) ON DELETE CASCADE"
"public.promotion_review" }o--o| "public.user" : "FOREIGN KEY (#quot;approvedById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.promotion_review" }o--o| "public.user" : "FOREIGN KEY (#quot;createdById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.promotion_review" }o--o| "public.promotion_connection" : "FOREIGN KEY (#quot;connectionId#quot;) REFERENCES promotion_connection(id) ON DELETE SET NULL"
"public.promotion_run" }o--o| "public.user" : "FOREIGN KEY (#quot;createdById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.promotion_run" }o--o| "public.promotion_config" : "FOREIGN KEY (#quot;configId#quot;) REFERENCES promotion_config(id) ON DELETE SET NULL"
"public.promotion_run" }o--o| "public.promotion_review" : "FOREIGN KEY (#quot;reviewId#quot;) REFERENCES promotion_review(id) ON DELETE SET NULL"
"public.role_mapping_rule" }o--|| "public.role" : "FOREIGN KEY (role) REFERENCES role(slug) ON UPDATE CASCADE ON DELETE CASCADE"
"public.role_mapping_rule_project" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.role_mapping_rule_project" }o--|| "public.role_mapping_rule" : "FOREIGN KEY (#quot;roleMappingRuleId#quot;) REFERENCES role_mapping_rule(id) ON DELETE CASCADE"
"public.role_scope" }o--|| "public.scope" : "FOREIGN KEY (#quot;scopeSlug#quot;) REFERENCES scope(slug) ON UPDATE CASCADE ON DELETE CASCADE"
"public.role_scope" }o--|| "public.role" : "FOREIGN KEY (#quot;roleSlug#quot;) REFERENCES role(slug) ON UPDATE CASCADE ON DELETE CASCADE"
"public.scheduled_task" }o--|| "public.scheduled_job" : "FOREIGN KEY (#quot;jobId#quot;) REFERENCES scheduled_job(id) ON DELETE CASCADE"
"public.self_healing_result" }o--|| "public.user" : "FOREIGN KEY (#quot;backgroundUserId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.self_healing_result" }o--o| "public.user" : "FOREIGN KEY (#quot;dismissedById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.self_healing_result" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.self_healing_result" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.self_healing_result" }o--o| "public.workflow_suggestion" : "FOREIGN KEY (#quot;suggestionId#quot;) REFERENCES workflow_suggestion(id) ON DELETE CASCADE"
"public.shared_credentials" }o--|| "public.credentials_entity" : "FOREIGN KEY (#quot;credentialsId#quot;) REFERENCES credentials_entity(id) ON DELETE CASCADE"
"public.shared_credentials" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.shared_workflow" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.shared_workflow" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.skill" }o--o| "public.user" : "FOREIGN KEY (#quot;createdById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.skill" }o--o| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.skill" }o--o| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.skill_file" }o--|| "public.skill_version" : "FOREIGN KEY (#quot;skillVersionId#quot;) REFERENCES skill_version(id) ON DELETE CASCADE"
"public.skill_version" }o--o| "public.user" : "FOREIGN KEY (#quot;createdById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.skill_version" }o--|| "public.skill" : "FOREIGN KEY (#quot;skillId#quot;) REFERENCES skill(id) ON DELETE CASCADE"
"public.test_case_execution" }o--o| "public.execution_entity" : "FOREIGN KEY (#quot;executionId#quot;) REFERENCES execution_entity(id) ON DELETE SET NULL"
"public.test_case_execution" }o--|| "public.test_run" : "FOREIGN KEY (#quot;testRunId#quot;) REFERENCES test_run(id) ON DELETE CASCADE"
"public.test_run" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
@ -443,7 +406,6 @@ erDiagram
"public.workflow_suggestion" }o--|| "public.user" : "FOREIGN KEY (#quot;backgroundUserId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.workflow_suggestion" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.workflow_suggestion" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.workflow_suggestion_activity" }o--o| "public.user" : "FOREIGN KEY (#quot;actorId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.workflow_suggestion_activity" }o--|| "public.workflow_suggestion" : "FOREIGN KEY (#quot;suggestionId#quot;) REFERENCES workflow_suggestion(id) ON DELETE CASCADE"
"public.workflows_tags" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.workflows_tags" }o--|| "public.tag_entity" : "FOREIGN KEY (#quot;tagId#quot;) REFERENCES tag_entity(id) ON DELETE CASCADE"
@ -580,7 +542,6 @@ erDiagram
varchar status
json toolCalls
timestamp_3__with_time_zone updatedAt
json verdict
}
"public.agent_eval_run" {
varchar_36_ agentVersionId
@ -704,12 +665,6 @@ erDiagram
uuid planId FK
integer revision
}
"public.agent_skill_dependency" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
varchar_36_ skillId FK
uuid skillVersionId FK
}
"public.agent_task_definition" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
@ -745,12 +700,6 @@ erDiagram
varchar_128_ threadId FK
timestamp_3__with_time_zone updatedAt
}
"public.agent_version_skill_dependency" {
varchar_36_ agentVersionId FK
timestamp_3__with_time_zone createdAt
varchar_36_ skillId FK
uuid skillVersionId FK
}
"public.agent_workflow_dependency" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
@ -766,7 +715,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools
@ -1163,17 +1111,6 @@ erDiagram
varchar_36_ folderId FK
varchar_36_ tagId FK
}
"public.idempotency_key" {
timestamp_3__with_time_zone createdAt
text fingerprint
varchar_16_ id
varchar_128_ idempotencyKey
json responseBody
smallint responseStatus
varchar_16_ status
timestamp_3__with_time_zone updatedAt
uuid userId FK
}
"public.insights_by_period" {
integer id
integer metaId FK
@ -1426,15 +1363,6 @@ erDiagram
timestamp_3__with_time_zone syncedAt
varchar_16_ targetVersion
}
"public.migration_workflow_owner" {
timestamp_3__with_time_zone assignedAt
uuid assignedById FK
timestamp_3__with_time_zone createdAt
varchar_16_ source
timestamp_3__with_time_zone updatedAt
uuid userId FK
varchar_36_ workflowId FK
}
"public.oauth_access_tokens" {
varchar clientId FK
varchar token
@ -1565,28 +1493,6 @@ erDiagram
varchar_32_ type
timestamp_3__with_time_zone updatedAt
}
"public.promotion_review" {
timestamp_3__with_time_zone approvedAt
uuid approvedById FK
varchar_36_ connectionId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
uuid id
timestamp_3__with_time_zone lastStateChangeAt
varchar_255_ remoteReviewId
varchar_32_ state
varchar_16_ type
}
"public.promotion_run" {
varchar_36_ configId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
json details
varchar_16_ direction
uuid id
uuid reviewId FK
varchar_16_ type
}
"public.role" {
timestamp_3__with_time_zone createdAt
text description
@ -1636,7 +1542,6 @@ erDiagram
integer recurrenceSize
varchar_16_ recurrenceUnit
varchar_128_ taskType
integer timeoutSeconds
varchar_64_ timezone
timestamp_3__with_time_zone updatedAt
}
@ -1659,7 +1564,6 @@ erDiagram
timestamp_3__with_time_zone startedAt
varchar_16_ status
varchar_128_ taskType
integer timeoutSeconds
}
"public.scope" {
text description
@ -1675,23 +1579,6 @@ erDiagram
varchar_36_ type
timestamp_3__with_time_zone updatedAt
}
"public.self_healing_result" {
uuid backgroundUserId FK
timestamp_3__with_time_zone completedAt
timestamp_3__with_time_zone createdAt
timestamp_3__with_time_zone dismissedAt
uuid dismissedById FK
varchar_36_ executionId
varchar_36_ id
varchar_16_ outcome
varchar_36_ projectId FK
text report
varchar_36_ suggestionId FK
text summary
timestamp_3__with_time_zone updatedAt
json usage
varchar_36_ workflowId FK
}
"public.settings" {
varchar_255_ key
boolean loadOnStartup
@ -1711,35 +1598,6 @@ erDiagram
timestamp_3__with_time_zone updatedAt
varchar_36_ workflowId FK
}
"public.skill" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_36_ id
varchar_36_ projectId FK
varchar_16_ source
timestamp_3__with_time_zone updatedAt
}
"public.skill_file" {
text content
timestamp_3__with_time_zone createdAt
varchar_512_ path
uuid skillVersionId FK
timestamp_3__with_time_zone updatedAt
}
"public.skill_version" {
varchar_64_ contentHash
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_1024_ description
json frontmatter
uuid id
text instructions
varchar_128_ name
varchar_36_ skillId FK
timestamp_3__with_time_zone updatedAt
integer version
}
"public.tag_entity" {
timestamp_3__with_time_zone createdAt
varchar_36_ id
@ -1805,14 +1663,11 @@ erDiagram
text config
integer configVersion
timestamp_3__with_time_zone createdAt
varchar_36_ discoveryClaimToken
timestamp_3__with_time_zone discoveryClaimedAt
varchar_36_ id
varchar issuer
timestamp_3__with_time_zone lastCheckedAt
text lastError
varchar_16_ managedBy
text metadata
varchar_128_ name
varchar_16_ status
varchar_32_ type
@ -2067,10 +1922,6 @@ erDiagram
varchar_128_ workflowName
}
"public.workflow_suggestion" {
varchar_32_ appliedAction
uuid appliedActorId
varchar_64_ appliedChecksum
varchar_36_ appliedVersionId
uuid backgroundUserId FK
timestamp_3__with_time_zone closedAt
varchar_16_ closedReason
@ -2079,14 +1930,12 @@ erDiagram
varchar_36_ id
json payload
varchar_36_ projectId FK
varchar_16_ resultKind
varchar_16_ state
timestamp_3__with_time_zone updatedAt
varchar_36_ workflowId FK
}
"public.workflow_suggestion_activity" {
varchar_16_ action
uuid actorId FK
varchar_16_ author
timestamp_3__with_time_zone createdAt
varchar_36_ id

View File

@ -35,7 +35,6 @@
| Name | Definition |
| ---- | ---------- |
| IDX_activity_event_project | CREATE INDEX "IDX_activity_event_project" ON public.activity_event USING btree ("projectId", id) |
| IDX_activity_event_resource | CREATE INDEX "IDX_activity_event_resource" ON public.activity_event USING btree ("resourceId", id) |
| IDX_activity_event_user | CREATE INDEX "IDX_activity_event_user" ON public.activity_event USING btree ("userId", id) |
| PK_c2c1e9fdda754a6bf7f664d7e04 | CREATE UNIQUE INDEX "PK_c2c1e9fdda754a6bf7f664d7e04" ON public.activity_event USING btree (id) |

View File

@ -95,7 +95,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -70,7 +70,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -75,7 +75,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -15,7 +15,7 @@
| Name | Type | Definition |
| ---- | ---- | ---------- |
| CHK_agent_chat_subscriptions_integrationType | CHECK | CHECK ((("integrationType")::text = ANY ((ARRAY['telegram'::character varying, 'slack'::character varying, 'linear'::character varying, 'discord'::character varying, 'teams'::character varying, 'whatsapp'::character varying])::text[]))) |
| CHK_agent_chat_subscriptions_integrationType | CHECK | CHECK ((("integrationType")::text = ANY ((ARRAY['telegram'::character varying, 'slack'::character varying, 'linear'::character varying, 'discord'::character varying, 'teams'::character varying])::text[]))) |
| FK_e79153bd179c011e779d5016796 | FOREIGN KEY | FOREIGN KEY ("agentId") REFERENCES agents(id) ON DELETE CASCADE |
| PK_76598cf91038bee1f3ac94c94bc | PRIMARY KEY | PRIMARY KEY ("agentId", "integrationType", "credentialId", "threadId") |
| agent_chat_subscriptions_agentId_not_null | n | NOT NULL "agentId" |
@ -56,7 +56,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -58,7 +58,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -49,7 +49,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -69,7 +69,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -85,7 +85,6 @@ erDiagram
varchar status
json toolCalls
timestamp_3__with_time_zone updatedAt
json verdict
}
```

View File

@ -19,7 +19,6 @@
| status | varchar | | false | | | Per-case lifecycle |
| toolCalls | json | | true | | | Tool-call timeline captured during the run |
| updatedAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| verdict | json | | true | | | |
## Constraints
@ -65,7 +64,6 @@ erDiagram
varchar status
json toolCalls
timestamp_3__with_time_zone updatedAt
json verdict
}
"public.agent_eval_rating" {
text comment

View File

@ -111,7 +111,6 @@ erDiagram
varchar status
json toolCalls
timestamp_3__with_time_zone updatedAt
json verdict
}
```

View File

@ -102,7 +102,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -70,7 +70,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -12,7 +12,7 @@
| skills | json | | true | | | Frozen map of `skillId → AgentSkill` at publish time |
| tools | json | | true | | | Frozen map of `toolId → { code, descriptor }` at publish time |
| updatedAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| versionId | varchar(36) | | false | [public.agent_execution_threads](public.agent_execution_threads.md) [public.agent_task_snapshot](public.agent_task_snapshot.md) [public.agent_version_skill_dependency](public.agent_version_skill_dependency.md) [public.agents](public.agents.md) | | |
| versionId | varchar(36) | | false | [public.agent_execution_threads](public.agent_execution_threads.md) [public.agent_task_snapshot](public.agent_task_snapshot.md) [public.agents](public.agents.md) | | |
## Constraints
@ -43,7 +43,6 @@ erDiagram
"public.agent_history" }o--o| "public.user" : "FOREIGN KEY (#quot;publishedById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.agent_execution_threads" }o--o| "public.agent_history" : "FOREIGN KEY (#quot;taskVersionId#quot;) REFERENCES agent_history(#quot;versionId#quot;) ON DELETE SET NULL"
"public.agent_task_snapshot" }o--|| "public.agent_history" : "FOREIGN KEY (#quot;versionId#quot;) REFERENCES agent_history(#quot;versionId#quot;) ON DELETE CASCADE"
"public.agent_version_skill_dependency" }o--|| "public.agent_history" : "FOREIGN KEY (#quot;agentVersionId#quot;) REFERENCES agent_history(#quot;versionId#quot;) ON DELETE CASCADE"
"public.agents" }o--o| "public.agent_history" : "FOREIGN KEY (#quot;activeVersionId#quot;) REFERENCES agent_history(#quot;versionId#quot;) ON DELETE SET NULL"
"public.agent_history" {
@ -67,7 +66,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools
@ -123,12 +121,6 @@ erDiagram
timestamp_3__with_time_zone updatedAt
varchar_36_ versionId FK
}
"public.agent_version_skill_dependency" {
varchar_36_ agentVersionId FK
timestamp_3__with_time_zone createdAt
varchar_36_ skillId FK
uuid skillVersionId FK
}
```
---

View File

@ -1,89 +0,0 @@
# public.agent_skill_dependency
## Columns
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| agentId | varchar(36) | | false | | [public.agents](public.agents.md) | |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| skillId | varchar(36) | | false | | [public.skill](public.skill.md) | |
| skillVersionId | uuid | | true | | [public.skill_version](public.skill_version.md) | Set when the agent draft pins a saved version. NULL = follows the latest saved version |
## Constraints
| Name | Type | Definition |
| ---- | ---- | ---------- |
| FK_068f21aefba31ae621482f396dc | FOREIGN KEY | FOREIGN KEY ("skillId") REFERENCES skill(id) ON DELETE CASCADE |
| FK_72325bb13511a51847c53fcb377 | FOREIGN KEY | FOREIGN KEY ("agentId") REFERENCES agents(id) ON DELETE CASCADE |
| FK_7676571bd6f41d9e32f0d066fe9 | FOREIGN KEY | FOREIGN KEY ("skillVersionId") REFERENCES skill_version(id) |
| PK_18a54f60491d3e2aa2200b70f4a | PRIMARY KEY | PRIMARY KEY ("agentId", "skillId") |
| agent_skill_dependency_agentId_not_null | n | NOT NULL "agentId" |
| agent_skill_dependency_createdAt_not_null | n | NOT NULL "createdAt" |
| agent_skill_dependency_skillId_not_null | n | NOT NULL "skillId" |
## Indexes
| Name | Definition |
| ---- | ---------- |
| IDX_068f21aefba31ae621482f396d | CREATE INDEX "IDX_068f21aefba31ae621482f396d" ON public.agent_skill_dependency USING btree ("skillId") |
| PK_18a54f60491d3e2aa2200b70f4a | CREATE UNIQUE INDEX "PK_18a54f60491d3e2aa2200b70f4a" ON public.agent_skill_dependency USING btree ("agentId", "skillId") |
## Relations
```mermaid
erDiagram
"public.agent_skill_dependency" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agent_skill_dependency" }o--|| "public.skill" : "FOREIGN KEY (#quot;skillId#quot;) REFERENCES skill(id) ON DELETE CASCADE"
"public.agent_skill_dependency" }o--o| "public.skill_version" : "FOREIGN KEY (#quot;skillVersionId#quot;) REFERENCES skill_version(id)"
"public.agent_skill_dependency" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
varchar_36_ skillId FK
uuid skillVersionId FK
}
"public.agents" {
varchar_36_ activeVersionId FK
boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
varchar_128_ name
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools
timestamp_3__with_time_zone updatedAt
varchar_36_ versionId
}
"public.skill" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_36_ id
varchar_36_ projectId FK
varchar_16_ source
timestamp_3__with_time_zone updatedAt
}
"public.skill_version" {
varchar_64_ contentHash
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_1024_ description
json frontmatter
uuid id
text instructions
varchar_128_ name
varchar_36_ skillId FK
timestamp_3__with_time_zone updatedAt
integer version
}
```
---
> Generated by [tbls](https://github.com/k1LoW/tbls)

View File

@ -61,7 +61,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -55,7 +55,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -1,85 +0,0 @@
# public.agent_version_skill_dependency
## Columns
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| agentVersionId | varchar(36) | | false | | [public.agent_history](public.agent_history.md) | |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| skillId | varchar(36) | | false | | [public.skill](public.skill.md) | |
| skillVersionId | uuid | | false | | [public.skill_version](public.skill_version.md) | |
## Constraints
| Name | Type | Definition |
| ---- | ---- | ---------- |
| FK_97472baf9196d914d9cd9de6201 | FOREIGN KEY | FOREIGN KEY ("agentVersionId") REFERENCES agent_history("versionId") ON DELETE CASCADE |
| FK_c494292243a7e510acd0331c3d1 | FOREIGN KEY | FOREIGN KEY ("skillId") REFERENCES skill(id) ON DELETE CASCADE |
| FK_df63badfd7d3f2aa622ece471c4 | FOREIGN KEY | FOREIGN KEY ("skillVersionId") REFERENCES skill_version(id) |
| PK_df0a2577371b94f3c7008d81822 | PRIMARY KEY | PRIMARY KEY ("agentVersionId", "skillId") |
| agent_version_skill_dependency_agentVersionId_not_null | n | NOT NULL "agentVersionId" |
| agent_version_skill_dependency_createdAt_not_null | n | NOT NULL "createdAt" |
| agent_version_skill_dependency_skillId_not_null | n | NOT NULL "skillId" |
| agent_version_skill_dependency_skillVersionId_not_null | n | NOT NULL "skillVersionId" |
## Indexes
| Name | Definition |
| ---- | ---------- |
| IDX_c494292243a7e510acd0331c3d | CREATE INDEX "IDX_c494292243a7e510acd0331c3d" ON public.agent_version_skill_dependency USING btree ("skillId") |
| IDX_df63badfd7d3f2aa622ece471c | CREATE INDEX "IDX_df63badfd7d3f2aa622ece471c" ON public.agent_version_skill_dependency USING btree ("skillVersionId") |
| PK_df0a2577371b94f3c7008d81822 | CREATE UNIQUE INDEX "PK_df0a2577371b94f3c7008d81822" ON public.agent_version_skill_dependency USING btree ("agentVersionId", "skillId") |
## Relations
```mermaid
erDiagram
"public.agent_version_skill_dependency" }o--|| "public.agent_history" : "FOREIGN KEY (#quot;agentVersionId#quot;) REFERENCES agent_history(#quot;versionId#quot;) ON DELETE CASCADE"
"public.agent_version_skill_dependency" }o--|| "public.skill" : "FOREIGN KEY (#quot;skillId#quot;) REFERENCES skill(id) ON DELETE CASCADE"
"public.agent_version_skill_dependency" }o--|| "public.skill_version" : "FOREIGN KEY (#quot;skillVersionId#quot;) REFERENCES skill_version(id)"
"public.agent_version_skill_dependency" {
varchar_36_ agentVersionId FK
timestamp_3__with_time_zone createdAt
varchar_36_ skillId FK
uuid skillVersionId FK
}
"public.agent_history" {
varchar_36_ agentId FK
varchar_255_ author
timestamp_3__with_time_zone createdAt
uuid publishedById FK
json schema
json skills
json tools
timestamp_3__with_time_zone updatedAt
varchar_36_ versionId
}
"public.skill" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_36_ id
varchar_36_ projectId FK
varchar_16_ source
timestamp_3__with_time_zone updatedAt
}
"public.skill_version" {
varchar_64_ contentHash
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_1024_ description
json frontmatter
uuid id
text instructions
varchar_128_ name
varchar_36_ skillId FK
timestamp_3__with_time_zone updatedAt
integer version
}
```
---
> Generated by [tbls](https://github.com/k1LoW/tbls)

View File

@ -49,7 +49,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -7,13 +7,12 @@
| activeVersionId | varchar(36) | | true | | [public.agent_history](public.agent_history.md) | |
| availableInMCP | boolean | false | false | | | Whether MCP clients granted agent scopes may operate on this agent |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| id | varchar(36) | | false | [public.agent_background_job](public.agent_background_job.md) [public.agent_channel_status](public.agent_channel_status.md) [public.agent_chat_attachments](public.agent_chat_attachments.md) [public.agent_chat_subscriptions](public.agent_chat_subscriptions.md) [public.agent_checkpoints](public.agent_checkpoints.md) [public.agent_credential_dependency](public.agent_credential_dependency.md) [public.agent_eval_dataset](public.agent_eval_dataset.md) [public.agent_execution_threads](public.agent_execution_threads.md) [public.agent_files](public.agent_files.md) [public.agent_history](public.agent_history.md) [public.agent_skill_dependency](public.agent_skill_dependency.md) [public.agent_task_definition](public.agent_task_definition.md) [public.agent_task_run_lock](public.agent_task_run_lock.md) [public.agent_workflow_dependency](public.agent_workflow_dependency.md) [public.agents_memory_entries](public.agents_memory_entries.md) [public.agents_memory_entry_candidates](public.agents_memory_entry_candidates.md) [public.agents_memory_entry_locks](public.agents_memory_entry_locks.md) [public.agents_memory_entry_sources](public.agents_memory_entry_sources.md) [public.agents_observation_cursors](public.agents_observation_cursors.md) [public.agents_observation_locks](public.agents_observation_locks.md) [public.agents_observations](public.agents_observations.md) [public.skill](public.skill.md) | | |
| id | varchar(36) | | false | [public.agent_background_job](public.agent_background_job.md) [public.agent_channel_status](public.agent_channel_status.md) [public.agent_chat_attachments](public.agent_chat_attachments.md) [public.agent_chat_subscriptions](public.agent_chat_subscriptions.md) [public.agent_checkpoints](public.agent_checkpoints.md) [public.agent_credential_dependency](public.agent_credential_dependency.md) [public.agent_eval_dataset](public.agent_eval_dataset.md) [public.agent_execution_threads](public.agent_execution_threads.md) [public.agent_files](public.agent_files.md) [public.agent_history](public.agent_history.md) [public.agent_task_definition](public.agent_task_definition.md) [public.agent_task_run_lock](public.agent_task_run_lock.md) [public.agent_workflow_dependency](public.agent_workflow_dependency.md) [public.agents_memory_entries](public.agents_memory_entries.md) [public.agents_memory_entry_candidates](public.agents_memory_entry_candidates.md) [public.agents_memory_entry_locks](public.agents_memory_entry_locks.md) [public.agents_memory_entry_sources](public.agents_memory_entry_sources.md) [public.agents_observation_cursors](public.agents_observation_cursors.md) [public.agents_observation_locks](public.agents_observation_locks.md) [public.agents_observations](public.agents_observations.md) | | |
| integrations | json | '[]'::json | false | | | |
| name | varchar(128) | | false | | | |
| projectId | varchar(255) | | true | | [public.project](public.project.md) | |
| projectId | varchar(255) | | false | | [public.project](public.project.md) | |
| revision | integer | 0 | false | | | |
| schema | json | | true | | | |
| scope | varchar(16) | 'project'::character varying | false | | | project: belongs to projectId; instance: code-defined, belongs to no project (projectId is null) |
| setupCompletedAt | timestamp(3) with time zone | | true | | | When this agent first reached a complete, publishable setup |
| skills | json | '{}'::json | false | | | |
| tools | json | '{}'::json | false | | | |
@ -24,8 +23,6 @@
| Name | Type | Definition |
| ---- | ---- | ---------- |
| CHK_agents_scope | CHECK | CHECK (((scope)::text = ANY ((ARRAY['project'::character varying, 'instance'::character varying])::text[]))) |
| CHK_agents_scope_project | CHECK | CHECK ((((scope)::text = 'instance'::text) = ("projectId" IS NULL))) |
| FK_940597dfe9753375309ce6aeea0 | FOREIGN KEY | FOREIGN KEY ("activeVersionId") REFERENCES agent_history("versionId") ON DELETE SET NULL |
| FK_a30d560207c4071d98aa03c179c | FOREIGN KEY | FOREIGN KEY ("projectId") REFERENCES project(id) ON DELETE CASCADE |
| PK_9c653f28ae19c5884d5baf6a1d9 | PRIMARY KEY | PRIMARY KEY (id) |
@ -34,8 +31,8 @@
| agents_id_not_null | n | NOT NULL id |
| agents_integrations_not_null | n | NOT NULL integrations |
| agents_name_not_null | n | NOT NULL name |
| agents_projectId_not_null | n | NOT NULL "projectId" |
| agents_revision_not_null | n | NOT NULL revision |
| agents_scope_not_null | n | NOT NULL scope |
| agents_skills_not_null | n | NOT NULL skills |
| agents_tools_not_null | n | NOT NULL tools |
| agents_updatedAt_not_null | n | NOT NULL "updatedAt" |
@ -64,7 +61,6 @@ erDiagram
"public.agent_execution_threads" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agent_files" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agent_history" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agent_skill_dependency" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agent_task_definition" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agent_task_run_lock" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agent_workflow_dependency" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
@ -75,8 +71,7 @@ erDiagram
"public.agents_observation_cursors" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agents_observation_locks" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agents_observations" }o--|| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.skill" }o--o| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.agents" }o--o| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.agents" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.agents" {
varchar_36_ activeVersionId FK
@ -88,7 +83,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools
@ -222,12 +216,6 @@ erDiagram
varchar_2_ storedAt
timestamp_3__with_time_zone updatedAt
}
"public.agent_skill_dependency" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
varchar_36_ skillId FK
uuid skillVersionId FK
}
"public.agent_task_definition" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
@ -332,15 +320,6 @@ erDiagram
integer tokenCount
timestamp_3__with_time_zone updatedAt
}
"public.skill" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_36_ id
varchar_36_ projectId FK
varchar_16_ source
timestamp_3__with_time_zone updatedAt
}
"public.project" {
timestamp_3__with_time_zone createdAt
uuid creatorId FK

View File

@ -82,7 +82,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -91,7 +91,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -58,7 +58,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -80,7 +80,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -58,7 +58,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -62,7 +62,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -81,7 +81,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools

View File

@ -1,80 +0,0 @@
# public.idempotency_key
## Columns
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| fingerprint | text | | false | | | Hash of the request method, path, and body |
| id | varchar(16) | | false | | | Application-generated n8n nano ID |
| idempotencyKey | varchar(128) | | false | | | Client Idempotency-Key header. Opaque ASCII, length 1 to 128 |
| responseBody | json | | true | | | Stored response body. NULL while status is processing |
| responseStatus | smallint | | true | | | HTTP status of the stored response. NULL while processing, required once completed |
| status | varchar(16) | 'processing'::character varying | false | | | processing while the handler runs. completed after the response is stored |
| updatedAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| userId | uuid | | false | | [public.user](public.user.md) | |
## Constraints
| Name | Type | Definition |
| ---- | ---- | ---------- |
| CHK_idempotency_key_responseStatus | CHECK | CHECK (((((status)::text = 'processing'::text) AND ("responseStatus" IS NULL)) OR (((status)::text = 'completed'::text) AND ("responseStatus" IS NOT NULL)))) |
| CHK_idempotency_key_status | CHECK | CHECK (((status)::text = ANY ((ARRAY['processing'::character varying, 'completed'::character varying])::text[]))) |
| FK_idempotency_key_userId | FOREIGN KEY | FOREIGN KEY ("userId") REFERENCES "user"(id) ON DELETE CASCADE |
| PK_213f125e14469be304f9ff1d452 | PRIMARY KEY | PRIMARY KEY (id) |
| idempotency_key_createdAt_not_null | n | NOT NULL "createdAt" |
| idempotency_key_fingerprint_not_null | n | NOT NULL fingerprint |
| idempotency_key_id_not_null | n | NOT NULL id |
| idempotency_key_idempotencyKey_not_null | n | NOT NULL "idempotencyKey" |
| idempotency_key_status_not_null | n | NOT NULL status |
| idempotency_key_updatedAt_not_null | n | NOT NULL "updatedAt" |
| idempotency_key_userId_not_null | n | NOT NULL "userId" |
## Indexes
| Name | Definition |
| ---- | ---------- |
| IDX_25289244569e505292cde510d7 | CREATE UNIQUE INDEX "IDX_25289244569e505292cde510d7" ON public.idempotency_key USING btree ("userId", "idempotencyKey") |
| IDX_38536b1937c55d305af4d69a97 | CREATE INDEX "IDX_38536b1937c55d305af4d69a97" ON public.idempotency_key USING btree ("createdAt") |
| PK_213f125e14469be304f9ff1d452 | CREATE UNIQUE INDEX "PK_213f125e14469be304f9ff1d452" ON public.idempotency_key USING btree (id) |
## Relations
```mermaid
erDiagram
"public.idempotency_key" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.idempotency_key" {
timestamp_3__with_time_zone createdAt
text fingerprint
varchar_16_ id
varchar_128_ idempotencyKey
json responseBody
smallint responseStatus
varchar_16_ status
timestamp_3__with_time_zone updatedAt
uuid userId FK
}
"public.user" {
timestamp_3__with_time_zone createdAt
boolean disabled
varchar_255_ email
varchar_32_ firstName
uuid id
date lastActiveAt
varchar_32_ lastName
boolean mfaEnabled
text mfaRecoveryCodes
text mfaSecret
varchar_255_ password
json personalizationAnswers
varchar_128_ roleSlug FK
json settings
timestamp_3__with_time_zone updatedAt
}
```
---
> Generated by [tbls](https://github.com/k1LoW/tbls)

View File

@ -1,97 +0,0 @@
# public.migration_workflow_owner
## Columns
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| assignedAt | timestamp(3) with time zone | | true | | | When a person assigned the owner. NULL for a suggestion. |
| assignedById | uuid | | true | | [public.user](public.user.md) | Who assigned the owner. NULL for a suggestion, or after that user was deleted. |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| source | varchar(16) | | false | | | MigrationOwnerSource enum: "suggested" by the heuristic, or "assigned" by a person. |
| updatedAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| userId | uuid | | true | | [public.user](public.user.md) | The owner. NULL after the user was deleted. |
| workflowId | varchar(36) | | false | | [public.workflow_entity](public.workflow_entity.md) | |
## Constraints
| Name | Type | Definition |
| ---- | ---- | ---------- |
| CHK_migration_workflow_owner_source | CHECK | CHECK (((source)::text = ANY ((ARRAY['suggested'::character varying, 'assigned'::character varying])::text[]))) |
| FK_59cde25bbb0edbb82286e4806d2 | FOREIGN KEY | FOREIGN KEY ("workflowId") REFERENCES workflow_entity(id) ON DELETE CASCADE |
| FK_ca859918be95d42fa6f698791c3 | FOREIGN KEY | FOREIGN KEY ("userId") REFERENCES "user"(id) ON DELETE SET NULL |
| FK_e6e5e4cab49ec23a544ffc9337a | FOREIGN KEY | FOREIGN KEY ("assignedById") REFERENCES "user"(id) ON DELETE SET NULL |
| PK_59cde25bbb0edbb82286e4806d2 | PRIMARY KEY | PRIMARY KEY ("workflowId") |
| migration_workflow_owner_createdAt_not_null | n | NOT NULL "createdAt" |
| migration_workflow_owner_source_not_null | n | NOT NULL source |
| migration_workflow_owner_updatedAt_not_null | n | NOT NULL "updatedAt" |
| migration_workflow_owner_workflowId_not_null | n | NOT NULL "workflowId" |
## Indexes
| Name | Definition |
| ---- | ---------- |
| IDX_ca859918be95d42fa6f698791c | CREATE INDEX "IDX_ca859918be95d42fa6f698791c" ON public.migration_workflow_owner USING btree ("userId") |
| PK_59cde25bbb0edbb82286e4806d2 | CREATE UNIQUE INDEX "PK_59cde25bbb0edbb82286e4806d2" ON public.migration_workflow_owner USING btree ("workflowId") |
## Relations
```mermaid
erDiagram
"public.migration_workflow_owner" }o--o| "public.user" : "FOREIGN KEY (#quot;assignedById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.migration_workflow_owner" }o--o| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.migration_workflow_owner" |o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.migration_workflow_owner" {
timestamp_3__with_time_zone assignedAt
uuid assignedById FK
timestamp_3__with_time_zone createdAt
varchar_16_ source
timestamp_3__with_time_zone updatedAt
uuid userId FK
varchar_36_ workflowId FK
}
"public.user" {
timestamp_3__with_time_zone createdAt
boolean disabled
varchar_255_ email
varchar_32_ firstName
uuid id
date lastActiveAt
varchar_32_ lastName
boolean mfaEnabled
text mfaRecoveryCodes
text mfaSecret
varchar_255_ password
json personalizationAnswers
varchar_128_ roleSlug FK
json settings
timestamp_3__with_time_zone updatedAt
}
"public.workflow_entity" {
boolean active
varchar_36_ activeVersionId FK
json connections
timestamp_3__with_time_zone createdAt
text description
varchar_36_ id
boolean isArchived
json meta
varchar_128_ name
json nodeGroups
json nodes
varchar_36_ parentFolderId FK
json pinData
json settings
varchar sourceWorkflowId
json staticData
integer triggerCount
timestamp_3__with_time_zone updatedAt
integer versionCounter
character_36_ versionId
}
```
---
> Generated by [tbls](https://github.com/k1LoW/tbls)

View File

@ -9,7 +9,7 @@
| customTelemetryTags | json | '[]'::json | false | | | |
| description | varchar(512) | | true | | | |
| icon | json | | true | | | |
| id | varchar(36) | | false | [public.activity_event](public.activity_event.md) [public.agent_chat_attachments](public.agent_chat_attachments.md) [public.agent_execution_threads](public.agent_execution_threads.md) [public.agents](public.agents.md) [public.ai_preference](public.ai_preference.md) [public.data_table](public.data_table.md) [public.folder](public.folder.md) [public.insights_metadata](public.insights_metadata.md) [public.instance_ai_threads](public.instance_ai_threads.md) [public.project_pool_settings](public.project_pool_settings.md) [public.project_relation](public.project_relation.md) [public.project_secrets_provider_access](public.project_secrets_provider_access.md) [public.promotion_connection_project](public.promotion_connection_project.md) [public.role_mapping_rule_project](public.role_mapping_rule_project.md) [public.self_healing_result](public.self_healing_result.md) [public.shared_credentials](public.shared_credentials.md) [public.shared_workflow](public.shared_workflow.md) [public.skill](public.skill.md) [public.type_availability_policy_scope](public.type_availability_policy_scope.md) [public.variables](public.variables.md) [public.workflow_review_request](public.workflow_review_request.md) [public.workflow_suggestion](public.workflow_suggestion.md) | | |
| id | varchar(36) | | false | [public.activity_event](public.activity_event.md) [public.agent_chat_attachments](public.agent_chat_attachments.md) [public.agent_execution_threads](public.agent_execution_threads.md) [public.agents](public.agents.md) [public.ai_preference](public.ai_preference.md) [public.data_table](public.data_table.md) [public.folder](public.folder.md) [public.insights_metadata](public.insights_metadata.md) [public.instance_ai_threads](public.instance_ai_threads.md) [public.project_pool_settings](public.project_pool_settings.md) [public.project_relation](public.project_relation.md) [public.project_secrets_provider_access](public.project_secrets_provider_access.md) [public.promotion_connection_project](public.promotion_connection_project.md) [public.role_mapping_rule_project](public.role_mapping_rule_project.md) [public.shared_credentials](public.shared_credentials.md) [public.shared_workflow](public.shared_workflow.md) [public.type_availability_policy_scope](public.type_availability_policy_scope.md) [public.variables](public.variables.md) [public.workflow_review_request](public.workflow_review_request.md) [public.workflow_suggestion](public.workflow_suggestion.md) | | |
| name | varchar(255) | | false | | | |
| type | varchar(36) | | false | | | |
| updatedAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
@ -42,7 +42,7 @@ erDiagram
"public.activity_event" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.agent_chat_attachments" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.agent_execution_threads" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.agents" }o--o| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.agents" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.ai_preference" }o--o| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.data_table" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.folder" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
@ -53,10 +53,8 @@ erDiagram
"public.project_secrets_provider_access" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.promotion_connection_project" |o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.role_mapping_rule_project" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.self_healing_result" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.shared_credentials" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.shared_workflow" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.skill" }o--o| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.type_availability_policy_scope" }o--o| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.variables" }o--o| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.workflow_review_request" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
@ -148,7 +146,6 @@ erDiagram
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools
@ -226,23 +223,6 @@ erDiagram
varchar_36_ projectId FK
varchar_16_ roleMappingRuleId FK
}
"public.self_healing_result" {
uuid backgroundUserId FK
timestamp_3__with_time_zone completedAt
timestamp_3__with_time_zone createdAt
timestamp_3__with_time_zone dismissedAt
uuid dismissedById FK
varchar_36_ executionId
varchar_36_ id
varchar_16_ outcome
varchar_36_ projectId FK
text report
varchar_36_ suggestionId FK
text summary
timestamp_3__with_time_zone updatedAt
json usage
varchar_36_ workflowId FK
}
"public.shared_credentials" {
timestamp_3__with_time_zone createdAt
varchar_36_ credentialsId FK
@ -257,15 +237,6 @@ erDiagram
timestamp_3__with_time_zone updatedAt
varchar_36_ workflowId FK
}
"public.skill" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_36_ id
varchar_36_ projectId FK
varchar_16_ source
timestamp_3__with_time_zone updatedAt
}
"public.type_availability_policy_scope" {
timestamp_3__with_time_zone createdAt
varchar_16_ defaultAction
@ -298,10 +269,6 @@ erDiagram
uuid updatedById FK
}
"public.workflow_suggestion" {
varchar_32_ appliedAction
uuid appliedActorId
varchar_64_ appliedChecksum
varchar_36_ appliedVersionId
uuid backgroundUserId FK
timestamp_3__with_time_zone closedAt
varchar_16_ closedReason
@ -310,7 +277,6 @@ erDiagram
varchar_36_ id
json payload
varchar_36_ projectId FK
varchar_16_ resultKind
varchar_16_ state
timestamp_3__with_time_zone updatedAt
varchar_36_ workflowId FK

View File

@ -7,7 +7,7 @@
| connectionId | varchar(36) | | false | | [public.promotion_connection](public.promotion_connection.md) | |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| direction | varchar(16) | | false | | | PromotionDirection enum: "apply", "promote". Cannot change after creation. |
| id | varchar(36) | | false | [public.promotion_run](public.promotion_run.md) | | Also the name of the local checkout directory. |
| id | varchar(36) | | false | | | Also the name of the local checkout directory. |
| name | varchar(128) | | false | | | |
| settings | json | | false | | | Branch settings for this direction, with their own schemaVersion. Validated in code. |
| updatedAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
@ -40,7 +40,6 @@
erDiagram
"public.promotion_config" }o--|| "public.promotion_connection" : "FOREIGN KEY (#quot;connectionId#quot;) REFERENCES promotion_connection(id) ON DELETE CASCADE"
"public.promotion_run" }o--o| "public.promotion_config" : "FOREIGN KEY (#quot;configId#quot;) REFERENCES promotion_config(id) ON DELETE SET NULL"
"public.promotion_config" {
varchar_36_ connectionId FK
@ -60,16 +59,6 @@ erDiagram
json target
timestamp_3__with_time_zone updatedAt
}
"public.promotion_run" {
varchar_36_ configId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
json details
varchar_16_ direction
uuid id
uuid reviewId FK
varchar_16_ type
}
```
---

View File

@ -5,7 +5,7 @@
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| id | varchar(36) | | false | [public.promotion_config](public.promotion_config.md) [public.promotion_connection_project](public.promotion_connection_project.md) [public.promotion_review](public.promotion_review.md) | | |
| id | varchar(36) | | false | [public.promotion_config](public.promotion_config.md) [public.promotion_connection_project](public.promotion_connection_project.md) | | |
| name | varchar(128) | | false | | | |
| providerId | varchar(36) | | false | | [public.promotion_provider](public.promotion_provider.md) | The provider whose credentials this connection uses. |
| scope | varchar(16) | | false | | | PromotionConnectionScope enum: "instance", "projects". Cannot change after creation. |
@ -42,7 +42,6 @@ erDiagram
"public.promotion_config" }o--|| "public.promotion_connection" : "FOREIGN KEY (#quot;connectionId#quot;) REFERENCES promotion_connection(id) ON DELETE CASCADE"
"public.promotion_connection_project" }o--|| "public.promotion_connection" : "FOREIGN KEY (#quot;connectionId#quot;) REFERENCES promotion_connection(id) ON DELETE CASCADE"
"public.promotion_review" }o--o| "public.promotion_connection" : "FOREIGN KEY (#quot;connectionId#quot;) REFERENCES promotion_connection(id) ON DELETE SET NULL"
"public.promotion_connection" }o--|| "public.promotion_provider" : "FOREIGN KEY (#quot;providerId#quot;) REFERENCES promotion_provider(id) ON DELETE RESTRICT"
"public.promotion_connection" {
@ -69,18 +68,6 @@ erDiagram
varchar_36_ projectId FK
timestamp_3__with_time_zone updatedAt
}
"public.promotion_review" {
timestamp_3__with_time_zone approvedAt
uuid approvedById FK
varchar_36_ connectionId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
uuid id
timestamp_3__with_time_zone lastStateChangeAt
varchar_255_ remoteReviewId
varchar_32_ state
varchar_16_ type
}
"public.promotion_provider" {
text auth
varchar_32_ authType

View File

@ -10,7 +10,7 @@
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| id | varchar(36) | | false | [public.promotion_connection](public.promotion_connection.md) | | |
| name | varchar(128) | | false | | | |
| type | varchar(32) | | false | | | PromotionProviderType enum: "git", "gitlab" |
| type | varchar(32) | | false | | | PromotionProviderType enum: "git" |
| updatedAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
## Constraints
@ -18,7 +18,7 @@
| Name | Type | Definition |
| ---- | ---- | ---------- |
| CHK_promotion_provider_authType | CHECK | CHECK ((("authType")::text = ANY ((ARRAY['ssh-key'::character varying, 'token'::character varying])::text[]))) |
| CHK_promotion_provider_type | CHECK | CHECK (((type)::text = ANY ((ARRAY['git'::character varying, 'gitlab'::character varying])::text[]))) |
| CHK_promotion_provider_type | CHECK | CHECK (((type)::text = 'git'::text)) |
| PK_6e968555ff44699f59ad10be765 | PRIMARY KEY | PRIMARY KEY (id) |
| promotion_provider_authType_not_null | n | NOT NULL "authType" |
| promotion_provider_auth_not_null | n | NOT NULL auth |

View File

@ -1,104 +0,0 @@
# public.promotion_review
## Columns
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| approvedAt | timestamp(3) with time zone | | true | | | When the n8n user approved the review. |
| approvedById | uuid | | true | | [public.user](public.user.md) | The one n8n user who approved the review in n8n. NULL until then. n8n does not copy an approver from the host. |
| connectionId | varchar(36) | | true | | [public.promotion_connection](public.promotion_connection.md) | The connection that remoteReviewId resolves through. NULL after the connection is deleted. |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| createdById | uuid | | true | | [public.user](public.user.md) | The n8n user whose Promote opened this review. NULL after that user is deleted. |
| id | uuid | | false | [public.promotion_run](public.promotion_run.md) | | |
| lastStateChangeAt | timestamp(3) with time zone | | true | | | Time of the latest state change. Covers every transition, including changes_requested and a reopened review. NULL until the first change. |
| remoteReviewId | varchar(255) | | true | | | Host reference for type. GitLab stores "\<projectId\>!\<iid\>". NULL when the review lives in n8n. |
| state | varchar(32) | 'open'::character varying | false | | | PromotionReviewState enum: "open", "changes_requested", "merged", "closed". "merged" and "closed" are terminal. |
| type | varchar(16) | | false | | | PromotionReviewType enum: "gitlab". |
## Constraints
| Name | Type | Definition |
| ---- | ---- | ---------- |
| CHK_promotion_review_state | CHECK | CHECK (((state)::text = ANY ((ARRAY['open'::character varying, 'changes_requested'::character varying, 'merged'::character varying, 'closed'::character varying])::text[]))) |
| CHK_promotion_review_type | CHECK | CHECK (((type)::text = 'gitlab'::text)) |
| FK_promotion_review_approvedById | FOREIGN KEY | FOREIGN KEY ("approvedById") REFERENCES "user"(id) ON DELETE SET NULL |
| FK_promotion_review_connectionId | FOREIGN KEY | FOREIGN KEY ("connectionId") REFERENCES promotion_connection(id) ON DELETE SET NULL |
| FK_promotion_review_createdById | FOREIGN KEY | FOREIGN KEY ("createdById") REFERENCES "user"(id) ON DELETE SET NULL |
| PK_fe93e2f1add228dc14d3330c8e5 | PRIMARY KEY | PRIMARY KEY (id) |
| promotion_review_createdAt_not_null | n | NOT NULL "createdAt" |
| promotion_review_id_not_null | n | NOT NULL id |
| promotion_review_state_not_null | n | NOT NULL state |
| promotion_review_type_not_null | n | NOT NULL type |
## Indexes
| Name | Definition |
| ---- | ---------- |
| IDX_82d6930410e9e6c7d04c515079 | CREATE INDEX "IDX_82d6930410e9e6c7d04c515079" ON public.promotion_review USING btree (state, "createdAt") |
| IDX_93e4ec34f4091a0333af0076b6 | CREATE INDEX "IDX_93e4ec34f4091a0333af0076b6" ON public.promotion_review USING btree ("connectionId") |
| IDX_promotion_review_connectionId_remoteReviewId | CREATE UNIQUE INDEX "IDX_promotion_review_connectionId_remoteReviewId" ON public.promotion_review USING btree ("connectionId", "remoteReviewId") WHERE ("remoteReviewId" IS NOT NULL) |
| PK_fe93e2f1add228dc14d3330c8e5 | CREATE UNIQUE INDEX "PK_fe93e2f1add228dc14d3330c8e5" ON public.promotion_review USING btree (id) |
## Relations
```mermaid
erDiagram
"public.promotion_review" }o--o| "public.user" : "FOREIGN KEY (#quot;approvedById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.promotion_review" }o--o| "public.promotion_connection" : "FOREIGN KEY (#quot;connectionId#quot;) REFERENCES promotion_connection(id) ON DELETE SET NULL"
"public.promotion_review" }o--o| "public.user" : "FOREIGN KEY (#quot;createdById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.promotion_run" }o--o| "public.promotion_review" : "FOREIGN KEY (#quot;reviewId#quot;) REFERENCES promotion_review(id) ON DELETE SET NULL"
"public.promotion_review" {
timestamp_3__with_time_zone approvedAt
uuid approvedById FK
varchar_36_ connectionId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
uuid id
timestamp_3__with_time_zone lastStateChangeAt
varchar_255_ remoteReviewId
varchar_32_ state
varchar_16_ type
}
"public.user" {
timestamp_3__with_time_zone createdAt
boolean disabled
varchar_255_ email
varchar_32_ firstName
uuid id
date lastActiveAt
varchar_32_ lastName
boolean mfaEnabled
text mfaRecoveryCodes
text mfaSecret
varchar_255_ password
json personalizationAnswers
varchar_128_ roleSlug FK
json settings
timestamp_3__with_time_zone updatedAt
}
"public.promotion_connection" {
timestamp_3__with_time_zone createdAt
varchar_36_ id
varchar_128_ name
varchar_36_ providerId FK
varchar_16_ scope
json target
timestamp_3__with_time_zone updatedAt
}
"public.promotion_run" {
varchar_36_ configId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
json details
varchar_16_ direction
uuid id
uuid reviewId FK
varchar_16_ type
}
```
---
> Generated by [tbls](https://github.com/k1LoW/tbls)

View File

@ -1,100 +0,0 @@
# public.promotion_run
## Columns
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| configId | varchar(36) | | true | | [public.promotion_config](public.promotion_config.md) | The config this run used. NULL after the config is deleted. |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| createdById | uuid | | true | | [public.user](public.user.md) | The user who ran Promote or Apply. |
| details | json | | true | | | Payload for type. A git run stores schemaVersion, branchName and commitSha. NULL when the type has no details. |
| direction | varchar(16) | | false | | | PromotionDirection enum: "promote" pushes to the remote, "apply" imports from it. Copied from the config when the run is written. |
| id | uuid | | false | | | |
| reviewId | uuid | | true | | [public.promotion_review](public.promotion_review.md) | The review this run belongs to. NULL when the push has no review. Not unique: an amend adds another run. |
| type | varchar(16) | | false | | | PromotionRunType enum: "git". Git covers GitHub, GitLab and plain Git. |
## Constraints
| Name | Type | Definition |
| ---- | ---- | ---------- |
| CHK_promotion_run_direction | CHECK | CHECK (((direction)::text = ANY ((ARRAY['promote'::character varying, 'apply'::character varying])::text[]))) |
| CHK_promotion_run_type | CHECK | CHECK (((type)::text = 'git'::text)) |
| FK_promotion_run_configId | FOREIGN KEY | FOREIGN KEY ("configId") REFERENCES promotion_config(id) ON DELETE SET NULL |
| FK_promotion_run_createdById | FOREIGN KEY | FOREIGN KEY ("createdById") REFERENCES "user"(id) ON DELETE SET NULL |
| FK_promotion_run_reviewId | FOREIGN KEY | FOREIGN KEY ("reviewId") REFERENCES promotion_review(id) ON DELETE SET NULL |
| PK_f5b941d810bf2eb7a5f8327f446 | PRIMARY KEY | PRIMARY KEY (id) |
| promotion_run_createdAt_not_null | n | NOT NULL "createdAt" |
| promotion_run_direction_not_null | n | NOT NULL direction |
| promotion_run_id_not_null | n | NOT NULL id |
| promotion_run_type_not_null | n | NOT NULL type |
## Indexes
| Name | Definition |
| ---- | ---------- |
| IDX_5c00951cc85ac1bc6f120b1e69 | CREATE INDEX "IDX_5c00951cc85ac1bc6f120b1e69" ON public.promotion_run USING btree ("configId") |
| IDX_b24c3e6b803dc496c8702f12ab | CREATE INDEX "IDX_b24c3e6b803dc496c8702f12ab" ON public.promotion_run USING btree ("reviewId") |
| PK_f5b941d810bf2eb7a5f8327f446 | CREATE UNIQUE INDEX "PK_f5b941d810bf2eb7a5f8327f446" ON public.promotion_run USING btree (id) |
## Relations
```mermaid
erDiagram
"public.promotion_run" }o--o| "public.promotion_config" : "FOREIGN KEY (#quot;configId#quot;) REFERENCES promotion_config(id) ON DELETE SET NULL"
"public.promotion_run" }o--o| "public.user" : "FOREIGN KEY (#quot;createdById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.promotion_run" }o--o| "public.promotion_review" : "FOREIGN KEY (#quot;reviewId#quot;) REFERENCES promotion_review(id) ON DELETE SET NULL"
"public.promotion_run" {
varchar_36_ configId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
json details
varchar_16_ direction
uuid id
uuid reviewId FK
varchar_16_ type
}
"public.promotion_config" {
varchar_36_ connectionId FK
timestamp_3__with_time_zone createdAt
varchar_16_ direction
varchar_36_ id
varchar_128_ name
json settings
timestamp_3__with_time_zone updatedAt
}
"public.user" {
timestamp_3__with_time_zone createdAt
boolean disabled
varchar_255_ email
varchar_32_ firstName
uuid id
date lastActiveAt
varchar_32_ lastName
boolean mfaEnabled
text mfaRecoveryCodes
text mfaSecret
varchar_255_ password
json personalizationAnswers
varchar_128_ roleSlug FK
json settings
timestamp_3__with_time_zone updatedAt
}
"public.promotion_review" {
timestamp_3__with_time_zone approvedAt
uuid approvedById FK
varchar_36_ connectionId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
uuid id
timestamp_3__with_time_zone lastStateChangeAt
varchar_255_ remoteReviewId
varchar_32_ state
varchar_16_ type
}
```
---
> Generated by [tbls](https://github.com/k1LoW/tbls)

View File

@ -26,7 +26,6 @@
| recurrenceSize | integer | | true | | | The N in a recurring_cron schedule's every-N-periods filter, e.g. 3 for every 3 weeks; at least 2. Set only when kind is 'recurring_cron'. |
| recurrenceUnit | varchar(16) | | true | | | Calendar period counted by a recurring_cron schedule's every-N-periods filter (hours, days, weeks, months). Set only when kind is 'recurring_cron'. |
| taskType | varchar(128) | | false | | | Selects which registered handler runs the task. |
| timeoutSeconds | integer | 300 | false | | | How long, in seconds, one attempt of an occurrence may run before the executor stops it. |
| timezone | varchar(64) | | true | | | IANA timezone the cron expression is evaluated in; NULL uses the instance default. |
| updatedAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
@ -44,7 +43,6 @@
| CHK_scheduled_job_recurrence_size | CHECK | CHECK (("recurrenceSize" >= 2)) |
| CHK_scheduled_job_recurrence_unit | CHECK | CHECK ((("recurrenceUnit")::text = ANY ((ARRAY['hours'::character varying, 'days'::character varying, 'weeks'::character varying, 'months'::character varying])::text[]))) |
| CHK_scheduled_job_recurring_cron | CHECK | CHECK ((((kind)::text <> 'recurring_cron'::text) OR (("cronExpression" IS NOT NULL) AND ("recurrenceUnit" IS NOT NULL) AND ("recurrenceSize" IS NOT NULL)))) |
| CHK_scheduled_job_timeoutSeconds | CHECK | CHECK ((("timeoutSeconds" > 0) AND ("timeoutSeconds" <= 2147483))) NOT VALID |
| PK_893185383f029ca8d57bb781fa8 | PRIMARY KEY | PRIMARY KEY (id) |
| scheduled_job_createdAt_not_null | n | NOT NULL "createdAt" |
| scheduled_job_enabled_not_null | n | NOT NULL enabled |
@ -58,7 +56,6 @@
| scheduled_job_ownerType_not_null | n | NOT NULL "ownerType" |
| scheduled_job_payload_not_null | n | NOT NULL payload |
| scheduled_job_taskType_not_null | n | NOT NULL "taskType" |
| scheduled_job_timeoutSeconds_not_null | n | NOT NULL "timeoutSeconds" |
| scheduled_job_updatedAt_not_null | n | NOT NULL "updatedAt" |
## Indexes
@ -101,7 +98,6 @@ erDiagram
integer recurrenceSize
varchar_16_ recurrenceUnit
varchar_128_ taskType
integer timeoutSeconds
varchar_64_ timezone
timestamp_3__with_time_zone updatedAt
}
@ -124,7 +120,6 @@ erDiagram
timestamp_3__with_time_zone startedAt
varchar_16_ status
varchar_128_ taskType
integer timeoutSeconds
}
```

View File

@ -22,7 +22,6 @@
| startedAt | timestamp(3) with time zone | | true | | | When the current attempt started running. |
| status | varchar(16) | 'pending'::character varying | false | | | Lifecycle state; drives which occurrences the claim and reaper scans consider. |
| taskType | varchar(128) | | false | | | What kind of work to run, copied from the job so a run is self-contained (no join to execute it). Also lets a run exist without a parent job in future. |
| timeoutSeconds | integer | 300 | false | | | How long, in seconds, one attempt of an occurrence may run before the executor stops it. |
## Constraints
@ -30,7 +29,6 @@
| ---- | ---- | ---------- |
| CHK_scheduled_task_running_lease | CHECK | CHECK ((((status)::text <> 'running'::text) OR ("leaseExpiresAt" IS NOT NULL))) |
| CHK_scheduled_task_status | CHECK | CHECK (((status)::text = ANY ((ARRAY['pending'::character varying, 'running'::character varying, 'succeeded'::character varying, 'failed'::character varying, 'missed'::character varying, 'cancelled'::character varying])::text[]))) |
| CHK_scheduled_task_timeoutSeconds | CHECK | CHECK ((("timeoutSeconds" > 0) AND ("timeoutSeconds" <= 2147483))) NOT VALID |
| FK_scheduled_task_jobId | FOREIGN KEY | FOREIGN KEY ("jobId") REFERENCES scheduled_job(id) ON DELETE CASCADE |
| PK_d690af24e57e30594c1948af1e6 | PRIMARY KEY | PRIMARY KEY (id) |
| scheduled_task_attempts_not_null | n | NOT NULL attempts |
@ -44,7 +42,6 @@
| scheduled_task_scheduledFor_not_null | n | NOT NULL "scheduledFor" |
| scheduled_task_status_not_null | n | NOT NULL status |
| scheduled_task_taskType_not_null | n | NOT NULL "taskType" |
| scheduled_task_timeoutSeconds_not_null | n | NOT NULL "timeoutSeconds" |
## Indexes
@ -83,7 +80,6 @@ erDiagram
timestamp_3__with_time_zone startedAt
varchar_16_ status
varchar_128_ taskType
integer timeoutSeconds
}
"public.scheduled_job" {
integer concurrencyLimit
@ -108,7 +104,6 @@ erDiagram
integer recurrenceSize
varchar_16_ recurrenceUnit
varchar_128_ taskType
integer timeoutSeconds
varchar_64_ timezone
timestamp_3__with_time_zone updatedAt
}

View File

@ -1,158 +0,0 @@
# public.self_healing_result
## Columns
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| backgroundUserId | uuid | | false | | [public.user](public.user.md) | User who enabled the investigation |
| completedAt | timestamp(3) with time zone | | false | | | |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| dismissedAt | timestamp(3) with time zone | | true | | | |
| dismissedById | uuid | | true | | [public.user](public.user.md) | Reviewer who dismissed the result |
| executionId | varchar(36) | | false | | | Execution reference retained after pruning; also supports the external v2 data plane |
| id | varchar(36) | | false | | | |
| outcome | varchar(16) | | false | | | Accepted investigation outcome, separate from review closure |
| projectId | varchar(36) | | false | | [public.project](public.project.md) | Original workflow owner project |
| report | text | | false | | | Saved report, independent of execution and chat data |
| suggestionId | varchar(36) | | true | | [public.workflow_suggestion](public.workflow_suggestion.md) | Optional isolated workflow suggestion |
| summary | text | | false | | | |
| updatedAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| usage | json | | false | | | Recorded runtime and accounting usage; null measurements mean unknown |
| workflowId | varchar(36) | | false | | [public.workflow_entity](public.workflow_entity.md) | Investigated workflow |
## Constraints
| Name | Type | Definition |
| ---- | ---- | ---------- |
| CHK_self_healing_result_outcome | CHECK | CHECK (((outcome)::text = ANY ((ARRAY['fix_ready'::character varying, 'needs_you'::character varying, 'could_not_fix'::character varying])::text[]))) |
| FK_3cb48b62bf261b7a6da666fee2d | FOREIGN KEY | FOREIGN KEY ("projectId") REFERENCES project(id) ON DELETE CASCADE |
| FK_738c3c0198c5ad104645a14fdc1 | FOREIGN KEY | FOREIGN KEY ("suggestionId") REFERENCES workflow_suggestion(id) ON DELETE CASCADE |
| FK_8366669b58b0f63a07cf2bbffcc | FOREIGN KEY | FOREIGN KEY ("backgroundUserId") REFERENCES "user"(id) ON DELETE CASCADE |
| FK_98095dea3ff814d4ee37a1380e6 | FOREIGN KEY | FOREIGN KEY ("dismissedById") REFERENCES "user"(id) ON DELETE SET NULL |
| FK_9a3fe8a8f872917949d8de1bb4a | FOREIGN KEY | FOREIGN KEY ("workflowId") REFERENCES workflow_entity(id) ON DELETE CASCADE |
| PK_0a772d117fddff1eaf6a759e1b6 | PRIMARY KEY | PRIMARY KEY (id) |
| self_healing_result_backgroundUserId_not_null | n | NOT NULL "backgroundUserId" |
| self_healing_result_completedAt_not_null | n | NOT NULL "completedAt" |
| self_healing_result_createdAt_not_null | n | NOT NULL "createdAt" |
| self_healing_result_executionId_not_null | n | NOT NULL "executionId" |
| self_healing_result_id_not_null | n | NOT NULL id |
| self_healing_result_outcome_not_null | n | NOT NULL outcome |
| self_healing_result_projectId_not_null | n | NOT NULL "projectId" |
| self_healing_result_report_not_null | n | NOT NULL report |
| self_healing_result_summary_not_null | n | NOT NULL summary |
| self_healing_result_updatedAt_not_null | n | NOT NULL "updatedAt" |
| self_healing_result_usage_not_null | n | NOT NULL usage |
| self_healing_result_workflowId_not_null | n | NOT NULL "workflowId" |
## Indexes
| Name | Definition |
| ---- | ---------- |
| IDX_3cb48b62bf261b7a6da666fee2 | CREATE INDEX "IDX_3cb48b62bf261b7a6da666fee2" ON public.self_healing_result USING btree ("projectId") |
| IDX_8366669b58b0f63a07cf2bbffc | CREATE INDEX "IDX_8366669b58b0f63a07cf2bbffc" ON public.self_healing_result USING btree ("backgroundUserId") |
| IDX_98095dea3ff814d4ee37a1380e | CREATE INDEX "IDX_98095dea3ff814d4ee37a1380e" ON public.self_healing_result USING btree ("dismissedById") |
| IDX_9a3fe8a8f872917949d8de1bb4 | CREATE INDEX "IDX_9a3fe8a8f872917949d8de1bb4" ON public.self_healing_result USING btree ("workflowId") |
| IDX_self_healing_result_suggestionId | CREATE UNIQUE INDEX "IDX_self_healing_result_suggestionId" ON public.self_healing_result USING btree ("suggestionId") WHERE ("suggestionId" IS NOT NULL) |
| PK_0a772d117fddff1eaf6a759e1b6 | CREATE UNIQUE INDEX "PK_0a772d117fddff1eaf6a759e1b6" ON public.self_healing_result USING btree (id) |
## Relations
```mermaid
erDiagram
"public.self_healing_result" }o--|| "public.user" : "FOREIGN KEY (#quot;backgroundUserId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.self_healing_result" }o--o| "public.user" : "FOREIGN KEY (#quot;dismissedById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.self_healing_result" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.self_healing_result" }o--o| "public.workflow_suggestion" : "FOREIGN KEY (#quot;suggestionId#quot;) REFERENCES workflow_suggestion(id) ON DELETE CASCADE"
"public.self_healing_result" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.self_healing_result" {
uuid backgroundUserId FK
timestamp_3__with_time_zone completedAt
timestamp_3__with_time_zone createdAt
timestamp_3__with_time_zone dismissedAt
uuid dismissedById FK
varchar_36_ executionId
varchar_36_ id
varchar_16_ outcome
varchar_36_ projectId FK
text report
varchar_36_ suggestionId FK
text summary
timestamp_3__with_time_zone updatedAt
json usage
varchar_36_ workflowId FK
}
"public.user" {
timestamp_3__with_time_zone createdAt
boolean disabled
varchar_255_ email
varchar_32_ firstName
uuid id
date lastActiveAt
varchar_32_ lastName
boolean mfaEnabled
text mfaRecoveryCodes
text mfaSecret
varchar_255_ password
json personalizationAnswers
varchar_128_ roleSlug FK
json settings
timestamp_3__with_time_zone updatedAt
}
"public.project" {
timestamp_3__with_time_zone createdAt
uuid creatorId FK
json customTelemetryTags
varchar_512_ description
json icon
varchar_36_ id
varchar_255_ name
varchar_36_ type
timestamp_3__with_time_zone updatedAt
}
"public.workflow_suggestion" {
varchar_32_ appliedAction
uuid appliedActorId
varchar_64_ appliedChecksum
varchar_36_ appliedVersionId
uuid backgroundUserId FK
timestamp_3__with_time_zone closedAt
varchar_16_ closedReason
timestamp_3__with_time_zone createdAt
json expectedBaseline
varchar_36_ id
json payload
varchar_36_ projectId FK
varchar_16_ resultKind
varchar_16_ state
timestamp_3__with_time_zone updatedAt
varchar_36_ workflowId FK
}
"public.workflow_entity" {
boolean active
varchar_36_ activeVersionId FK
json connections
timestamp_3__with_time_zone createdAt
text description
varchar_36_ id
boolean isArchived
json meta
varchar_128_ name
json nodeGroups
json nodes
varchar_36_ parentFolderId FK
json pinData
json settings
varchar sourceWorkflowId
json staticData
integer triggerCount
timestamp_3__with_time_zone updatedAt
integer versionCounter
character_36_ versionId
}
```
---
> Generated by [tbls](https://github.com/k1LoW/tbls)

View File

@ -1,132 +0,0 @@
# public.skill
## Columns
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| agentId | varchar(36) | | true | | [public.agents](public.agents.md) | Set when only this agent can use the skill. projectId is then NULL: the agent holds the project |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| createdById | uuid | | true | | [public.user](public.user.md) | Author. NULL after the author is deleted |
| id | varchar(36) | | false | [public.agent_skill_dependency](public.agent_skill_dependency.md) [public.agent_version_skill_dependency](public.agent_version_skill_dependency.md) [public.skill_version](public.skill_version.md) | | skill_\<nanoid\>, the same format agents use |
| projectId | varchar(36) | | true | | [public.project](public.project.md) | Set for a project skill, team or personal. NULL otherwise |
| source | varchar(16) | | false | | | How the skill was created, set by the server: "ui" (the skills hub) or "agent" (the agent builder or the copy of agent skills) |
| updatedAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
## Constraints
| Name | Type | Definition |
| ---- | ---- | ---------- |
| CHK_skill_single_target | CHECK | CHECK ((("agentId" IS NULL) OR ("projectId" IS NULL))) |
| FK_402ed37bff0d3134f6e782455ed | FOREIGN KEY | FOREIGN KEY ("projectId") REFERENCES project(id) ON DELETE CASCADE |
| FK_4de4501583cd1fcd6f5ea85f547 | FOREIGN KEY | FOREIGN KEY ("createdById") REFERENCES "user"(id) ON DELETE SET NULL |
| FK_7d4fb6af107e507d9a86293cf9d | FOREIGN KEY | FOREIGN KEY ("agentId") REFERENCES agents(id) ON DELETE CASCADE |
| PK_a0d33334424e64fb78dc3ce7196 | PRIMARY KEY | PRIMARY KEY (id) |
| skill_createdAt_not_null | n | NOT NULL "createdAt" |
| skill_id_not_null | n | NOT NULL id |
| skill_source_not_null | n | NOT NULL source |
| skill_updatedAt_not_null | n | NOT NULL "updatedAt" |
## Indexes
| Name | Definition |
| ---- | ---------- |
| IDX_402ed37bff0d3134f6e782455e | CREATE INDEX "IDX_402ed37bff0d3134f6e782455e" ON public.skill USING btree ("projectId") |
| IDX_7d4fb6af107e507d9a86293cf9 | CREATE INDEX "IDX_7d4fb6af107e507d9a86293cf9" ON public.skill USING btree ("agentId") |
| PK_a0d33334424e64fb78dc3ce7196 | CREATE UNIQUE INDEX "PK_a0d33334424e64fb78dc3ce7196" ON public.skill USING btree (id) |
## Relations
```mermaid
erDiagram
"public.skill" }o--o| "public.agents" : "FOREIGN KEY (#quot;agentId#quot;) REFERENCES agents(id) ON DELETE CASCADE"
"public.skill" }o--o| "public.user" : "FOREIGN KEY (#quot;createdById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.agent_skill_dependency" }o--|| "public.skill" : "FOREIGN KEY (#quot;skillId#quot;) REFERENCES skill(id) ON DELETE CASCADE"
"public.agent_version_skill_dependency" }o--|| "public.skill" : "FOREIGN KEY (#quot;skillId#quot;) REFERENCES skill(id) ON DELETE CASCADE"
"public.skill_version" }o--|| "public.skill" : "FOREIGN KEY (#quot;skillId#quot;) REFERENCES skill(id) ON DELETE CASCADE"
"public.skill" }o--o| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.skill" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_36_ id
varchar_36_ projectId FK
varchar_16_ source
timestamp_3__with_time_zone updatedAt
}
"public.agents" {
varchar_36_ activeVersionId FK
boolean availableInMCP
timestamp_3__with_time_zone createdAt
varchar_36_ id
json integrations
varchar_128_ name
varchar_255_ projectId FK
integer revision
json schema
varchar_16_ scope
timestamp_3__with_time_zone setupCompletedAt
json skills
json tools
timestamp_3__with_time_zone updatedAt
varchar_36_ versionId
}
"public.user" {
timestamp_3__with_time_zone createdAt
boolean disabled
varchar_255_ email
varchar_32_ firstName
uuid id
date lastActiveAt
varchar_32_ lastName
boolean mfaEnabled
text mfaRecoveryCodes
text mfaSecret
varchar_255_ password
json personalizationAnswers
varchar_128_ roleSlug FK
json settings
timestamp_3__with_time_zone updatedAt
}
"public.agent_skill_dependency" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
varchar_36_ skillId FK
uuid skillVersionId FK
}
"public.agent_version_skill_dependency" {
varchar_36_ agentVersionId FK
timestamp_3__with_time_zone createdAt
varchar_36_ skillId FK
uuid skillVersionId FK
}
"public.skill_version" {
varchar_64_ contentHash
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_1024_ description
json frontmatter
uuid id
text instructions
varchar_128_ name
varchar_36_ skillId FK
timestamp_3__with_time_zone updatedAt
integer version
}
"public.project" {
timestamp_3__with_time_zone createdAt
uuid creatorId FK
json customTelemetryTags
varchar_512_ description
json icon
varchar_36_ id
varchar_255_ name
varchar_36_ type
timestamp_3__with_time_zone updatedAt
}
```
---
> Generated by [tbls](https://github.com/k1LoW/tbls)

View File

@ -1,62 +0,0 @@
# public.skill_file
## Columns
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| content | text | | false | | | |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| path | varchar(512) | | false | | | Relative path, references/*.md in v1 |
| skillVersionId | uuid | | false | | [public.skill_version](public.skill_version.md) | |
| updatedAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
## Constraints
| Name | Type | Definition |
| ---- | ---- | ---------- |
| FK_e9ab50b795ec8858702b7333d13 | FOREIGN KEY | FOREIGN KEY ("skillVersionId") REFERENCES skill_version(id) ON DELETE CASCADE |
| PK_160721f9e4c22026c16138af2a1 | PRIMARY KEY | PRIMARY KEY ("skillVersionId", path) |
| skill_file_content_not_null | n | NOT NULL content |
| skill_file_createdAt_not_null | n | NOT NULL "createdAt" |
| skill_file_path_not_null | n | NOT NULL path |
| skill_file_skillVersionId_not_null | n | NOT NULL "skillVersionId" |
| skill_file_updatedAt_not_null | n | NOT NULL "updatedAt" |
## Indexes
| Name | Definition |
| ---- | ---------- |
| PK_160721f9e4c22026c16138af2a1 | CREATE UNIQUE INDEX "PK_160721f9e4c22026c16138af2a1" ON public.skill_file USING btree ("skillVersionId", path) |
## Relations
```mermaid
erDiagram
"public.skill_file" }o--|| "public.skill_version" : "FOREIGN KEY (#quot;skillVersionId#quot;) REFERENCES skill_version(id) ON DELETE CASCADE"
"public.skill_file" {
text content
timestamp_3__with_time_zone createdAt
varchar_512_ path
uuid skillVersionId FK
timestamp_3__with_time_zone updatedAt
}
"public.skill_version" {
varchar_64_ contentHash
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_1024_ description
json frontmatter
uuid id
text instructions
varchar_128_ name
varchar_36_ skillId FK
timestamp_3__with_time_zone updatedAt
integer version
}
```
---
> Generated by [tbls](https://github.com/k1LoW/tbls)

View File

@ -1,118 +0,0 @@
# public.skill_version
## Columns
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| contentHash | varchar(64) | | false | | | sha256 of name, description, instructions, frontmatter and files. Save creates no version when the content matches the latest one |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| createdById | uuid | | true | | [public.user](public.user.md) | Author. NULL after the author is deleted |
| description | varchar(1024) | | false | | | |
| frontmatter | json | | true | | | SKILL.md frontmatter fields other than name and description, e.g. allowed-tools |
| id | uuid | | false | [public.agent_skill_dependency](public.agent_skill_dependency.md) [public.agent_version_skill_dependency](public.agent_version_skill_dependency.md) [public.skill_file](public.skill_file.md) | | |
| instructions | text | | false | | | |
| name | varchar(128) | | false | | | Free-text skill name, as it was when this version was saved |
| skillId | varchar(36) | | false | | [public.skill](public.skill.md) | |
| updatedAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| version | integer | | false | | | 1..n per skill. A Save that changes the content adds one; none ever changes |
## Constraints
| Name | Type | Definition |
| ---- | ---- | ---------- |
| CHK_skill_version_version | CHECK | CHECK ((version > 0)) |
| FK_9565d0fbf32cd463f9b47c7adab | FOREIGN KEY | FOREIGN KEY ("createdById") REFERENCES "user"(id) ON DELETE SET NULL |
| FK_f87064c0a29efd2d5195328d91a | FOREIGN KEY | FOREIGN KEY ("skillId") REFERENCES skill(id) ON DELETE CASCADE |
| PK_05167d59ac7599128e22400172d | PRIMARY KEY | PRIMARY KEY (id) |
| UQ_93bb78a1eb4e0890fac6b69df95 | UNIQUE | UNIQUE ("skillId", version) |
| skill_version_contentHash_not_null | n | NOT NULL "contentHash" |
| skill_version_createdAt_not_null | n | NOT NULL "createdAt" |
| skill_version_description_not_null | n | NOT NULL description |
| skill_version_id_not_null | n | NOT NULL id |
| skill_version_instructions_not_null | n | NOT NULL instructions |
| skill_version_name_not_null | n | NOT NULL name |
| skill_version_skillId_not_null | n | NOT NULL "skillId" |
| skill_version_updatedAt_not_null | n | NOT NULL "updatedAt" |
| skill_version_version_not_null | n | NOT NULL version |
## Indexes
| Name | Definition |
| ---- | ---------- |
| PK_05167d59ac7599128e22400172d | CREATE UNIQUE INDEX "PK_05167d59ac7599128e22400172d" ON public.skill_version USING btree (id) |
| UQ_93bb78a1eb4e0890fac6b69df95 | CREATE UNIQUE INDEX "UQ_93bb78a1eb4e0890fac6b69df95" ON public.skill_version USING btree ("skillId", version) |
## Relations
```mermaid
erDiagram
"public.skill_version" }o--o| "public.user" : "FOREIGN KEY (#quot;createdById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.agent_skill_dependency" }o--o| "public.skill_version" : "FOREIGN KEY (#quot;skillVersionId#quot;) REFERENCES skill_version(id)"
"public.agent_version_skill_dependency" }o--|| "public.skill_version" : "FOREIGN KEY (#quot;skillVersionId#quot;) REFERENCES skill_version(id)"
"public.skill_file" }o--|| "public.skill_version" : "FOREIGN KEY (#quot;skillVersionId#quot;) REFERENCES skill_version(id) ON DELETE CASCADE"
"public.skill_version" }o--|| "public.skill" : "FOREIGN KEY (#quot;skillId#quot;) REFERENCES skill(id) ON DELETE CASCADE"
"public.skill_version" {
varchar_64_ contentHash
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_1024_ description
json frontmatter
uuid id
text instructions
varchar_128_ name
varchar_36_ skillId FK
timestamp_3__with_time_zone updatedAt
integer version
}
"public.user" {
timestamp_3__with_time_zone createdAt
boolean disabled
varchar_255_ email
varchar_32_ firstName
uuid id
date lastActiveAt
varchar_32_ lastName
boolean mfaEnabled
text mfaRecoveryCodes
text mfaSecret
varchar_255_ password
json personalizationAnswers
varchar_128_ roleSlug FK
json settings
timestamp_3__with_time_zone updatedAt
}
"public.agent_skill_dependency" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
varchar_36_ skillId FK
uuid skillVersionId FK
}
"public.agent_version_skill_dependency" {
varchar_36_ agentVersionId FK
timestamp_3__with_time_zone createdAt
varchar_36_ skillId FK
uuid skillVersionId FK
}
"public.skill_file" {
text content
timestamp_3__with_time_zone createdAt
varchar_512_ path
uuid skillVersionId FK
timestamp_3__with_time_zone updatedAt
}
"public.skill" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_36_ id
varchar_36_ projectId FK
varchar_16_ source
timestamp_3__with_time_zone updatedAt
}
```
---
> Generated by [tbls](https://github.com/k1LoW/tbls)

View File

@ -7,14 +7,11 @@
| config | text | | false | | | |
| configVersion | integer | | false | | | |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| discoveryClaimToken | varchar(36) | | true | | | |
| discoveryClaimedAt | timestamp(3) with time zone | | true | | | |
| id | varchar(36) | | false | [public.trusted_source_identity](public.trusted_source_identity.md) | | |
| issuer | varchar | | false | | | |
| lastCheckedAt | timestamp(3) with time zone | | true | | | |
| lastError | text | | true | | | |
| managedBy | varchar(16) | | false | | | |
| metadata | text | | true | | | |
| name | varchar(128) | | false | | | |
| status | varchar(16) | | false | | | |
| type | varchar(32) | | false | | | |
@ -55,14 +52,11 @@ erDiagram
text config
integer configVersion
timestamp_3__with_time_zone createdAt
varchar_36_ discoveryClaimToken
timestamp_3__with_time_zone discoveryClaimedAt
varchar_36_ id
varchar issuer
timestamp_3__with_time_zone lastCheckedAt
text lastError
varchar_16_ managedBy
text metadata
varchar_128_ name
varchar_16_ status
varchar_32_ type

View File

@ -57,14 +57,11 @@ erDiagram
text config
integer configVersion
timestamp_3__with_time_zone createdAt
varchar_36_ discoveryClaimToken
timestamp_3__with_time_zone discoveryClaimedAt
varchar_36_ id
varchar issuer
timestamp_3__with_time_zone lastCheckedAt
text lastError
varchar_16_ managedBy
text metadata
varchar_128_ name
varchar_16_ status
varchar_32_ type

View File

@ -8,7 +8,7 @@
| disabled | boolean | false | false | | | |
| email | varchar(255) | | true | | | |
| firstName | varchar(32) | | true | | | |
| id | uuid | gen_random_uuid() | false | [public.activity_event](public.activity_event.md) [public.agent_eval_dataset](public.agent_eval_dataset.md) [public.agent_eval_rating](public.agent_eval_rating.md) [public.agent_eval_run](public.agent_eval_run.md) [public.agent_execution_threads](public.agent_execution_threads.md) [public.agent_history](public.agent_history.md) [public.ai_preference](public.ai_preference.md) [public.auth_identity](public.auth_identity.md) [public.chat_hub_agents](public.chat_hub_agents.md) [public.chat_hub_sessions](public.chat_hub_sessions.md) [public.chat_hub_tools](public.chat_hub_tools.md) [public.dynamic_credential_user_entry](public.dynamic_credential_user_entry.md) [public.evaluation_collection](public.evaluation_collection.md) [public.idempotency_key](public.idempotency_key.md) [public.instance_ai_mcp_registry_connections](public.instance_ai_mcp_registry_connections.md) [public.instance_ai_pending_confirmations](public.instance_ai_pending_confirmations.md) [public.instance_ai_thread_grants](public.instance_ai_thread_grants.md) [public.instance_ai_thread_tabs](public.instance_ai_thread_tabs.md) [public.migration_workflow_owner](public.migration_workflow_owner.md) [public.oauth_access_tokens](public.oauth_access_tokens.md) [public.oauth_authorization_codes](public.oauth_authorization_codes.md) [public.oauth_refresh_tokens](public.oauth_refresh_tokens.md) [public.oauth_user_consents](public.oauth_user_consents.md) [public.project](public.project.md) [public.project_relation](public.project_relation.md) [public.promotion_review](public.promotion_review.md) [public.promotion_run](public.promotion_run.md) [public.self_healing_result](public.self_healing_result.md) [public.skill](public.skill.md) [public.skill_version](public.skill_version.md) [public.trusted_source_identity](public.trusted_source_identity.md) [public.user_api_keys](public.user_api_keys.md) [public.user_favorites](public.user_favorites.md) [public.workflow_builder_session](public.workflow_builder_session.md) [public.workflow_publish_history](public.workflow_publish_history.md) [public.workflow_review_activity](public.workflow_review_activity.md) [public.workflow_review_activity_comment](public.workflow_review_activity_comment.md) [public.workflow_review_request](public.workflow_review_request.md) [public.workflow_review_request_authors](public.workflow_review_request_authors.md) [public.workflow_review_request_reviewers](public.workflow_review_request_reviewers.md) [public.workflow_suggestion](public.workflow_suggestion.md) [public.workflow_suggestion_activity](public.workflow_suggestion_activity.md) | | |
| id | uuid | gen_random_uuid() | false | [public.activity_event](public.activity_event.md) [public.agent_eval_dataset](public.agent_eval_dataset.md) [public.agent_eval_rating](public.agent_eval_rating.md) [public.agent_eval_run](public.agent_eval_run.md) [public.agent_execution_threads](public.agent_execution_threads.md) [public.agent_history](public.agent_history.md) [public.ai_preference](public.ai_preference.md) [public.auth_identity](public.auth_identity.md) [public.chat_hub_agents](public.chat_hub_agents.md) [public.chat_hub_sessions](public.chat_hub_sessions.md) [public.chat_hub_tools](public.chat_hub_tools.md) [public.dynamic_credential_user_entry](public.dynamic_credential_user_entry.md) [public.evaluation_collection](public.evaluation_collection.md) [public.instance_ai_mcp_registry_connections](public.instance_ai_mcp_registry_connections.md) [public.instance_ai_pending_confirmations](public.instance_ai_pending_confirmations.md) [public.instance_ai_thread_grants](public.instance_ai_thread_grants.md) [public.instance_ai_thread_tabs](public.instance_ai_thread_tabs.md) [public.oauth_access_tokens](public.oauth_access_tokens.md) [public.oauth_authorization_codes](public.oauth_authorization_codes.md) [public.oauth_refresh_tokens](public.oauth_refresh_tokens.md) [public.oauth_user_consents](public.oauth_user_consents.md) [public.project](public.project.md) [public.project_relation](public.project_relation.md) [public.trusted_source_identity](public.trusted_source_identity.md) [public.user_api_keys](public.user_api_keys.md) [public.user_favorites](public.user_favorites.md) [public.workflow_builder_session](public.workflow_builder_session.md) [public.workflow_publish_history](public.workflow_publish_history.md) [public.workflow_review_activity](public.workflow_review_activity.md) [public.workflow_review_activity_comment](public.workflow_review_activity_comment.md) [public.workflow_review_request](public.workflow_review_request.md) [public.workflow_review_request_authors](public.workflow_review_request_authors.md) [public.workflow_review_request_reviewers](public.workflow_review_request_reviewers.md) [public.workflow_suggestion](public.workflow_suggestion.md) | | |
| lastActiveAt | date | | true | | | |
| lastName | varchar(32) | | true | | | |
| mfaEnabled | boolean | false | false | | | |
@ -61,26 +61,16 @@ erDiagram
"public.chat_hub_tools" }o--|| "public.user" : "FOREIGN KEY (#quot;ownerId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.dynamic_credential_user_entry" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.evaluation_collection" }o--o| "public.user" : "FOREIGN KEY (#quot;createdById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.idempotency_key" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.instance_ai_mcp_registry_connections" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.instance_ai_pending_confirmations" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.instance_ai_thread_grants" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.instance_ai_thread_tabs" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.migration_workflow_owner" }o--o| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.migration_workflow_owner" }o--o| "public.user" : "FOREIGN KEY (#quot;assignedById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.oauth_access_tokens" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.oauth_authorization_codes" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.oauth_refresh_tokens" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.oauth_user_consents" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.project" }o--o| "public.user" : "FOREIGN KEY (#quot;creatorId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.project_relation" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.promotion_review" }o--o| "public.user" : "FOREIGN KEY (#quot;approvedById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.promotion_review" }o--o| "public.user" : "FOREIGN KEY (#quot;createdById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.promotion_run" }o--o| "public.user" : "FOREIGN KEY (#quot;createdById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.self_healing_result" }o--|| "public.user" : "FOREIGN KEY (#quot;backgroundUserId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.self_healing_result" }o--o| "public.user" : "FOREIGN KEY (#quot;dismissedById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.skill" }o--o| "public.user" : "FOREIGN KEY (#quot;createdById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.skill_version" }o--o| "public.user" : "FOREIGN KEY (#quot;createdById#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.trusted_source_identity" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.user_api_keys" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.user_favorites" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
@ -94,7 +84,6 @@ erDiagram
"public.workflow_review_request_authors" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.workflow_review_request_reviewers" }o--|| "public.user" : "FOREIGN KEY (#quot;userId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.workflow_suggestion" }o--|| "public.user" : "FOREIGN KEY (#quot;backgroundUserId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.workflow_suggestion_activity" }o--o| "public.user" : "FOREIGN KEY (#quot;actorId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.user" }o--|| "public.role" : "FOREIGN KEY (#quot;roleSlug#quot;) REFERENCES role(slug)"
"public.user" {
@ -274,17 +263,6 @@ erDiagram
timestamp_3__with_time_zone updatedAt
varchar_36_ workflowId FK
}
"public.idempotency_key" {
timestamp_3__with_time_zone createdAt
text fingerprint
varchar_16_ id
varchar_128_ idempotencyKey
json responseBody
smallint responseStatus
varchar_16_ status
timestamp_3__with_time_zone updatedAt
uuid userId FK
}
"public.instance_ai_mcp_registry_connections" {
timestamp_3__with_time_zone createdAt
varchar_36_ credentialId FK
@ -322,15 +300,6 @@ erDiagram
timestamp_3__with_time_zone updatedAt
uuid userId FK
}
"public.migration_workflow_owner" {
timestamp_3__with_time_zone assignedAt
uuid assignedById FK
timestamp_3__with_time_zone createdAt
varchar_16_ source
timestamp_3__with_time_zone updatedAt
uuid userId FK
varchar_36_ workflowId FK
}
"public.oauth_access_tokens" {
varchar clientId FK
varchar token
@ -386,67 +355,6 @@ erDiagram
timestamp_3__with_time_zone updatedAt
uuid userId FK
}
"public.promotion_review" {
timestamp_3__with_time_zone approvedAt
uuid approvedById FK
varchar_36_ connectionId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
uuid id
timestamp_3__with_time_zone lastStateChangeAt
varchar_255_ remoteReviewId
varchar_32_ state
varchar_16_ type
}
"public.promotion_run" {
varchar_36_ configId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
json details
varchar_16_ direction
uuid id
uuid reviewId FK
varchar_16_ type
}
"public.self_healing_result" {
uuid backgroundUserId FK
timestamp_3__with_time_zone completedAt
timestamp_3__with_time_zone createdAt
timestamp_3__with_time_zone dismissedAt
uuid dismissedById FK
varchar_36_ executionId
varchar_36_ id
varchar_16_ outcome
varchar_36_ projectId FK
text report
varchar_36_ suggestionId FK
text summary
timestamp_3__with_time_zone updatedAt
json usage
varchar_36_ workflowId FK
}
"public.skill" {
varchar_36_ agentId FK
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_36_ id
varchar_36_ projectId FK
varchar_16_ source
timestamp_3__with_time_zone updatedAt
}
"public.skill_version" {
varchar_64_ contentHash
timestamp_3__with_time_zone createdAt
uuid createdById FK
varchar_1024_ description
json frontmatter
uuid id
text instructions
varchar_128_ name
varchar_36_ skillId FK
timestamp_3__with_time_zone updatedAt
integer version
}
"public.trusted_source_identity" {
timestamp_3__with_time_zone createdAt
timestamp_3__with_time_zone lastSeenAt
@ -535,10 +443,6 @@ erDiagram
varchar_36_ workflowReviewRequestId FK
}
"public.workflow_suggestion" {
varchar_32_ appliedAction
uuid appliedActorId
varchar_64_ appliedChecksum
varchar_36_ appliedVersionId
uuid backgroundUserId FK
timestamp_3__with_time_zone closedAt
varchar_16_ closedReason
@ -547,20 +451,10 @@ erDiagram
varchar_36_ id
json payload
varchar_36_ projectId FK
varchar_16_ resultKind
varchar_16_ state
timestamp_3__with_time_zone updatedAt
varchar_36_ workflowId FK
}
"public.workflow_suggestion_activity" {
varchar_16_ action
uuid actorId FK
varchar_16_ author
timestamp_3__with_time_zone createdAt
varchar_36_ id
varchar_36_ suggestionId FK
timestamp_3__with_time_zone updatedAt
}
"public.role" {
timestamp_3__with_time_zone createdAt
text description

View File

@ -9,7 +9,7 @@
| connections | json | | false | | | |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| description | text | | true | | | |
| id | varchar(36) | | false | [public.agent_workflow_dependency](public.agent_workflow_dependency.md) [public.ai_builder_temporary_workflow](public.ai_builder_temporary_workflow.md) [public.chat_hub_messages](public.chat_hub_messages.md) [public.chat_hub_sessions](public.chat_hub_sessions.md) [public.evaluation_collection](public.evaluation_collection.md) [public.evaluation_config](public.evaluation_config.md) [public.execution_entity](public.execution_entity.md) [public.insights_metadata](public.insights_metadata.md) [public.migration_finding](public.migration_finding.md) [public.migration_workflow_owner](public.migration_workflow_owner.md) [public.poller_state](public.poller_state.md) [public.processed_data](public.processed_data.md) [public.self_healing_result](public.self_healing_result.md) [public.shared_workflow](public.shared_workflow.md) [public.test_run](public.test_run.md) [public.webhook_entity](public.webhook_entity.md) [public.workflow_builder_session](public.workflow_builder_session.md) [public.workflow_dependency](public.workflow_dependency.md) [public.workflow_history](public.workflow_history.md) [public.workflow_publication_retry_state](public.workflow_publication_retry_state.md) [public.workflow_publication_trigger_status](public.workflow_publication_trigger_status.md) [public.workflow_publish_history](public.workflow_publish_history.md) [public.workflow_published_version](public.workflow_published_version.md) [public.workflow_review_request_workflow](public.workflow_review_request_workflow.md) [public.workflow_suggestion](public.workflow_suggestion.md) [public.workflows_tags](public.workflows_tags.md) | | |
| id | varchar(36) | | false | [public.agent_workflow_dependency](public.agent_workflow_dependency.md) [public.ai_builder_temporary_workflow](public.ai_builder_temporary_workflow.md) [public.chat_hub_messages](public.chat_hub_messages.md) [public.chat_hub_sessions](public.chat_hub_sessions.md) [public.evaluation_collection](public.evaluation_collection.md) [public.evaluation_config](public.evaluation_config.md) [public.execution_entity](public.execution_entity.md) [public.insights_metadata](public.insights_metadata.md) [public.migration_finding](public.migration_finding.md) [public.poller_state](public.poller_state.md) [public.processed_data](public.processed_data.md) [public.shared_workflow](public.shared_workflow.md) [public.test_run](public.test_run.md) [public.webhook_entity](public.webhook_entity.md) [public.workflow_builder_session](public.workflow_builder_session.md) [public.workflow_dependency](public.workflow_dependency.md) [public.workflow_history](public.workflow_history.md) [public.workflow_publication_retry_state](public.workflow_publication_retry_state.md) [public.workflow_publication_trigger_status](public.workflow_publication_trigger_status.md) [public.workflow_publish_history](public.workflow_publish_history.md) [public.workflow_published_version](public.workflow_published_version.md) [public.workflow_review_request_workflow](public.workflow_review_request_workflow.md) [public.workflow_suggestion](public.workflow_suggestion.md) [public.workflows_tags](public.workflows_tags.md) | | |
| isArchived | boolean | false | false | | | |
| meta | json | | true | | | |
| name | varchar(128) | | false | | | |
@ -75,10 +75,8 @@ erDiagram
"public.execution_entity" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.insights_metadata" }o--o| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE SET NULL"
"public.migration_finding" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.migration_workflow_owner" |o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.poller_state" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.processed_data" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.self_healing_result" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.shared_workflow" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.test_run" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.webhook_entity" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
@ -239,15 +237,6 @@ erDiagram
timestamp_3__with_time_zone updatedAt
varchar_36_ workflowId FK
}
"public.migration_workflow_owner" {
timestamp_3__with_time_zone assignedAt
uuid assignedById FK
timestamp_3__with_time_zone createdAt
varchar_16_ source
timestamp_3__with_time_zone updatedAt
uuid userId FK
varchar_36_ workflowId FK
}
"public.poller_state" {
timestamp_3__with_time_zone backoffUntil
integer consecutiveErrors
@ -264,23 +253,6 @@ erDiagram
text value
varchar_36_ workflowId FK
}
"public.self_healing_result" {
uuid backgroundUserId FK
timestamp_3__with_time_zone completedAt
timestamp_3__with_time_zone createdAt
timestamp_3__with_time_zone dismissedAt
uuid dismissedById FK
varchar_36_ executionId
varchar_36_ id
varchar_16_ outcome
varchar_36_ projectId FK
text report
varchar_36_ suggestionId FK
text summary
timestamp_3__with_time_zone updatedAt
json usage
varchar_36_ workflowId FK
}
"public.shared_workflow" {
timestamp_3__with_time_zone createdAt
varchar_36_ projectId FK
@ -374,10 +346,6 @@ erDiagram
varchar_36_ workflowVersionId FK
}
"public.workflow_suggestion" {
varchar_32_ appliedAction
uuid appliedActorId
varchar_64_ appliedChecksum
varchar_36_ appliedVersionId
uuid backgroundUserId FK
timestamp_3__with_time_zone closedAt
varchar_16_ closedReason
@ -386,7 +354,6 @@ erDiagram
varchar_36_ id
json payload
varchar_36_ projectId FK
varchar_16_ resultKind
varchar_16_ state
timestamp_3__with_time_zone updatedAt
varchar_36_ workflowId FK

View File

@ -4,19 +4,14 @@
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| appliedAction | varchar(32) | | true | | | Action that saved the reviewed fix |
| appliedActorId | uuid | | true | | | Human actor ID retained after the user is deleted |
| appliedChecksum | varchar(64) | | true | | | SHA-256 checksum of the saved workflow |
| appliedVersionId | varchar(36) | | true | | | Saved version ID retained after its history is deleted |
| backgroundUserId | uuid | | false | | [public.user](public.user.md) | User who enabled the investigation |
| closedAt | timestamp(3) with time zone | | true | | | |
| closedReason | varchar(16) | | true | | | Reason the suggestion closed |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| expectedBaseline | json | | false | | | savedVersionId, publishedVersionId, and checksum captured from the original workflow |
| id | varchar(36) | | false | [public.self_healing_result](public.self_healing_result.md) [public.workflow_suggestion_activity](public.workflow_suggestion_activity.md) | | |
| id | varchar(36) | | false | [public.workflow_suggestion_activity](public.workflow_suggestion_activity.md) | | |
| payload | json | | false | | | Original workflow snapshot, candidate nodes and connections, explanation, and error context |
| projectId | varchar(36) | | false | | [public.project](public.project.md) | Original owner project |
| resultKind | varchar(16) | | false | | | Investigation outcome; only fix_ready permits Apply |
| state | varchar(16) | | false | | | Suggestion lifecycle state |
| updatedAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| workflowId | varchar(36) | | false | | [public.workflow_entity](public.workflow_entity.md) | Target workflow |
@ -25,9 +20,7 @@
| Name | Type | Definition |
| ---- | ---- | ---------- |
| CHK_workflow_suggestion_appliedAction | CHECK | CHECK ((("appliedAction")::text = ANY ((ARRAY['apply'::character varying, 'approve-and-publish'::character varying])::text[]))) |
| CHK_workflow_suggestion_closedReason | CHECK | CHECK ((("closedReason")::text = ANY ((ARRAY['outdated'::character varying, 'applied'::character varying, 'discarded'::character varying])::text[]))) |
| CHK_workflow_suggestion_resultKind | CHECK | CHECK ((("resultKind")::text = ANY ((ARRAY['fix_ready'::character varying, 'needs_you'::character varying])::text[]))) |
| CHK_workflow_suggestion_state | CHECK | CHECK (((state)::text = ANY ((ARRAY['pending'::character varying, 'closed'::character varying])::text[]))) |
| FK_0f273c2cd9e1a097a8ba044fe9a | FOREIGN KEY | FOREIGN KEY ("projectId") REFERENCES project(id) ON DELETE CASCADE |
| FK_b415d749769e092f51575def2d2 | FOREIGN KEY | FOREIGN KEY ("backgroundUserId") REFERENCES "user"(id) ON DELETE CASCADE |
@ -39,7 +32,6 @@
| workflow_suggestion_id_not_null | n | NOT NULL id |
| workflow_suggestion_payload_not_null | n | NOT NULL payload |
| workflow_suggestion_projectId_not_null | n | NOT NULL "projectId" |
| workflow_suggestion_resultKind_not_null | n | NOT NULL "resultKind" |
| workflow_suggestion_state_not_null | n | NOT NULL state |
| workflow_suggestion_updatedAt_not_null | n | NOT NULL "updatedAt" |
| workflow_suggestion_workflowId_not_null | n | NOT NULL "workflowId" |
@ -60,16 +52,11 @@
erDiagram
"public.workflow_suggestion" }o--|| "public.user" : "FOREIGN KEY (#quot;backgroundUserId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE CASCADE"
"public.self_healing_result" }o--o| "public.workflow_suggestion" : "FOREIGN KEY (#quot;suggestionId#quot;) REFERENCES workflow_suggestion(id) ON DELETE CASCADE"
"public.workflow_suggestion_activity" }o--|| "public.workflow_suggestion" : "FOREIGN KEY (#quot;suggestionId#quot;) REFERENCES workflow_suggestion(id) ON DELETE CASCADE"
"public.workflow_suggestion" }o--|| "public.project" : "FOREIGN KEY (#quot;projectId#quot;) REFERENCES project(id) ON DELETE CASCADE"
"public.workflow_suggestion" }o--|| "public.workflow_entity" : "FOREIGN KEY (#quot;workflowId#quot;) REFERENCES workflow_entity(id) ON DELETE CASCADE"
"public.workflow_suggestion" {
varchar_32_ appliedAction
uuid appliedActorId
varchar_64_ appliedChecksum
varchar_36_ appliedVersionId
uuid backgroundUserId FK
timestamp_3__with_time_zone closedAt
varchar_16_ closedReason
@ -78,7 +65,6 @@ erDiagram
varchar_36_ id
json payload
varchar_36_ projectId FK
varchar_16_ resultKind
varchar_16_ state
timestamp_3__with_time_zone updatedAt
varchar_36_ workflowId FK
@ -100,26 +86,8 @@ erDiagram
json settings
timestamp_3__with_time_zone updatedAt
}
"public.self_healing_result" {
uuid backgroundUserId FK
timestamp_3__with_time_zone completedAt
timestamp_3__with_time_zone createdAt
timestamp_3__with_time_zone dismissedAt
uuid dismissedById FK
varchar_36_ executionId
varchar_36_ id
varchar_16_ outcome
varchar_36_ projectId FK
text report
varchar_36_ suggestionId FK
text summary
timestamp_3__with_time_zone updatedAt
json usage
varchar_36_ workflowId FK
}
"public.workflow_suggestion_activity" {
varchar_16_ action
uuid actorId FK
varchar_16_ author
timestamp_3__with_time_zone createdAt
varchar_36_ id

View File

@ -5,7 +5,6 @@
| Name | Type | Default | Nullable | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
| action | varchar(16) | | false | | | Proposal activity action |
| actorId | uuid | | true | | [public.user](public.user.md) | Human who took the action; null for Assistant and system activity |
| author | varchar(16) | | false | | | Authorship, separate from the background user |
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
| id | varchar(36) | | false | | | |
@ -19,7 +18,6 @@
| CHK_workflow_suggestion_activity_action | CHECK | CHECK (((action)::text = ANY ((ARRAY['submitted'::character varying, 'applied'::character varying, 'discarded'::character varying, 'outdated'::character varying, 'published'::character varying, 'publish_failed'::character varying])::text[]))) |
| CHK_workflow_suggestion_activity_author | CHECK | CHECK (((author)::text = ANY ((ARRAY['assistant'::character varying, 'human'::character varying, 'system'::character varying])::text[]))) |
| FK_c9a28e6f7349dc4950aeb858692 | FOREIGN KEY | FOREIGN KEY ("suggestionId") REFERENCES workflow_suggestion(id) ON DELETE CASCADE |
| FK_workflow_suggestion_activity_actor | FOREIGN KEY | FOREIGN KEY ("actorId") REFERENCES "user"(id) ON DELETE SET NULL |
| PK_382a74180d2539b68f5990db193 | PRIMARY KEY | PRIMARY KEY (id) |
| workflow_suggestion_activity_action_not_null | n | NOT NULL action |
| workflow_suggestion_activity_author_not_null | n | NOT NULL author |
@ -33,7 +31,6 @@
| Name | Definition |
| ---- | ---------- |
| IDX_a8ffa8017c56cb2920a47cc92a | CREATE UNIQUE INDEX "IDX_a8ffa8017c56cb2920a47cc92a" ON public.workflow_suggestion_activity USING btree ("suggestionId", action) |
| IDX_workflow_suggestion_activity_actorId | CREATE INDEX "IDX_workflow_suggestion_activity_actorId" ON public.workflow_suggestion_activity USING btree ("actorId") |
| PK_382a74180d2539b68f5990db193 | CREATE UNIQUE INDEX "PK_382a74180d2539b68f5990db193" ON public.workflow_suggestion_activity USING btree (id) |
## Relations
@ -41,40 +38,17 @@
```mermaid
erDiagram
"public.workflow_suggestion_activity" }o--o| "public.user" : "FOREIGN KEY (#quot;actorId#quot;) REFERENCES #quot;user#quot;(id) ON DELETE SET NULL"
"public.workflow_suggestion_activity" }o--|| "public.workflow_suggestion" : "FOREIGN KEY (#quot;suggestionId#quot;) REFERENCES workflow_suggestion(id) ON DELETE CASCADE"
"public.workflow_suggestion_activity" {
varchar_16_ action
uuid actorId FK
varchar_16_ author
timestamp_3__with_time_zone createdAt
varchar_36_ id
varchar_36_ suggestionId FK
timestamp_3__with_time_zone updatedAt
}
"public.user" {
timestamp_3__with_time_zone createdAt
boolean disabled
varchar_255_ email
varchar_32_ firstName
uuid id
date lastActiveAt
varchar_32_ lastName
boolean mfaEnabled
text mfaRecoveryCodes
text mfaSecret
varchar_255_ password
json personalizationAnswers
varchar_128_ roleSlug FK
json settings
timestamp_3__with_time_zone updatedAt
}
"public.workflow_suggestion" {
varchar_32_ appliedAction
uuid appliedActorId
varchar_64_ appliedChecksum
varchar_36_ appliedVersionId
uuid backgroundUserId FK
timestamp_3__with_time_zone closedAt
varchar_16_ closedReason
@ -83,7 +57,6 @@ erDiagram
varchar_36_ id
json payload
varchar_36_ projectId FK
varchar_16_ resultKind
varchar_16_ state
timestamp_3__with_time_zone updatedAt
varchar_36_ workflowId FK

View File

@ -19,7 +19,7 @@ Auto-generated from the SQLite migrations in @n8n/db. Do not edit by hand.
| [agent_credential_dependency](agent_credential_dependency.md) | 3 | | table |
| [agent_eval_dataset](agent_eval_dataset.md) | 10 | | table |
| [agent_eval_rating](agent_eval_rating.md) | 8 | | table |
| [agent_eval_result](agent_eval_result.md) | 16 | | table |
| [agent_eval_result](agent_eval_result.md) | 15 | | table |
| [agent_eval_run](agent_eval_run.md) | 14 | | table |
| [agent_execution](agent_execution.md) | 23 | | table |
| [agent_execution_message_links](agent_execution_message_links.md) | 5 | | table |
@ -29,14 +29,12 @@ Auto-generated from the SQLite migrations in @n8n/db. Do not edit by hand.
| [agent_message_queue](agent_message_queue.md) | 10 | | table |
| [agent_plan](agent_plan.md) | 8 | | table |
| [agent_plan_history](agent_plan_history.md) | 6 | | table |
| [agent_skill_dependency](agent_skill_dependency.md) | 4 | | table |
| [agent_task_definition](agent_task_definition.md) | 8 | | table |
| [agent_task_run_lock](agent_task_run_lock.md) | 6 | | table |
| [agent_task_snapshot](agent_task_snapshot.md) | 9 | | table |
| [agent_thread_grants](agent_thread_grants.md) | 4 | | table |
| [agent_version_skill_dependency](agent_version_skill_dependency.md) | 4 | | table |
| [agent_workflow_dependency](agent_workflow_dependency.md) | 3 | | table |
| [agents](agents.md) | 15 | | table |
| [agents](agents.md) | 14 | | table |
| [agents_memory_entries](agents_memory_entries.md) | 13 | | table |
| [agents_memory_entry_candidates](agents_memory_entry_candidates.md) | 14 | | table |
| [agents_memory_entry_locks](agents_memory_entry_locks.md) | 6 | | table |
@ -77,7 +75,6 @@ Auto-generated from the SQLite migrations in @n8n/db. Do not edit by hand.
| [execution_metadata](execution_metadata.md) | 4 | | table |
| [folder](folder.md) | 6 | | table |
| [folder_tag](folder_tag.md) | 2 | | table |
| [idempotency_key](idempotency_key.md) | 9 | | table |
| [insights_by_period](insights_by_period.md) | 6 | | table |
| [insights_metadata](insights_metadata.md) | 5 | | table |
| [insights_raw](insights_raw.md) | 5 | | table |
@ -105,7 +102,6 @@ Auto-generated from the SQLite migrations in @n8n/db. Do not edit by hand.
| [mcp_registry_server](mcp_registry_server.md) | 7 | | table |
| [migration_finding](migration_finding.md) | 10 | | table |
| [migration_finding_sync](migration_finding_sync.md) | 3 | | table |
| [migration_workflow_owner](migration_workflow_owner.md) | 7 | | table |
| [oauth_access_tokens](oauth_access_tokens.md) | 3 | | table |
| [oauth_authorization_codes](oauth_authorization_codes.md) | 13 | | table |
| [oauth_clients](oauth_clients.md) | 10 | | table |
@ -121,30 +117,24 @@ Auto-generated from the SQLite migrations in @n8n/db. Do not edit by hand.
| [promotion_connection](promotion_connection.md) | 7 | | table |
| [promotion_connection_project](promotion_connection_project.md) | 4 | | table |
| [promotion_provider](promotion_provider.md) | 8 | | table |
| [promotion_review](promotion_review.md) | 10 | | table |
| [promotion_run](promotion_run.md) | 8 | | table |
| [role](role.md) | 7 | | table |
| [role_mapping_rule](role_mapping_rule.md) | 7 | | table |
| [role_mapping_rule_project](role_mapping_rule_project.md) | 2 | | table |
| [role_scope](role_scope.md) | 2 | | table |
| [scheduled_job](scheduled_job.md) | 25 | | table |
| [scheduled_task](scheduled_task.md) | 19 | | table |
| [scheduled_job](scheduled_job.md) | 24 | | table |
| [scheduled_task](scheduled_task.md) | 18 | | table |
| [scope](scope.md) | 3 | | table |
| [secrets_provider_connection](secrets_provider_connection.md) | 7 | | table |
| [self_healing_result](self_healing_result.md) | 15 | | table |
| [settings](settings.md) | 3 | | table |
| [shared_credentials](shared_credentials.md) | 5 | | table |
| [shared_workflow](shared_workflow.md) | 5 | | table |
| [skill](skill.md) | 7 | | table |
| [skill_file](skill_file.md) | 5 | | table |
| [skill_version](skill_version.md) | 11 | | table |
| [tag_entity](tag_entity.md) | 4 | | table |
| [test_case_execution](test_case_execution.md) | 16 | | table |
| [test_run](test_run.md) | 16 | | table |
| [token_exchange_jti](token_exchange_jti.md) | 3 | | table |
| [trusted_key](trusted_key.md) | 4 | | table |
| [trusted_key_source](trusted_key_source.md) | 8 | | table |
| [trusted_source](trusted_source.md) | 15 | | table |
| [trusted_source](trusted_source.md) | 12 | | table |
| [trusted_source_identity](trusted_source_identity.md) | 8 | | table |
| [type_availability_policy](type_availability_policy.md) | 7 | | table |
| [type_availability_policy_attachment](type_availability_policy_attachment.md) | 6 | | table |
@ -170,8 +160,8 @@ Auto-generated from the SQLite migrations in @n8n/db. Do not edit by hand.
| [workflow_review_request_reviewers](workflow_review_request_reviewers.md) | 2 | | table |
| [workflow_review_request_workflow](workflow_review_request_workflow.md) | 5 | | table |
| [workflow_statistics](workflow_statistics.md) | 7 | | table |
| [workflow_suggestion](workflow_suggestion.md) | 16 | | table |
| [workflow_suggestion_activity](workflow_suggestion_activity.md) | 7 | | table |
| [workflow_suggestion](workflow_suggestion.md) | 11 | | table |
| [workflow_suggestion_activity](workflow_suggestion_activity.md) | 6 | | table |
| [workflows_tags](workflows_tags.md) | 2 | | table |
## Relations
@ -212,19 +202,13 @@ erDiagram
"agent_message_queue" }o--o| "agent_execution" : "FOREIGN KEY (steeringExecutionId) REFERENCES agent_execution (id) ON UPDATE NO ACTION ON DELETE NO ACTION MATCH NONE"
"agent_plan" }o--|| "agent_execution_threads" : "FOREIGN KEY (threadId) REFERENCES agent_execution_threads (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agent_plan_history" |o--|| "agent_plan" : "FOREIGN KEY (planId) REFERENCES agent_plan (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agent_skill_dependency" }o--o| "skill_version" : "FOREIGN KEY (skillVersionId) REFERENCES skill_version (id) ON UPDATE NO ACTION ON DELETE NO ACTION MATCH NONE"
"agent_skill_dependency" |o--|| "skill" : "FOREIGN KEY (skillId) REFERENCES skill (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agent_skill_dependency" |o--|| "agents" : "FOREIGN KEY (agentId) REFERENCES agents (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agent_task_definition" }o--|| "agents" : "FOREIGN KEY (agentId) REFERENCES agents (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agent_task_run_lock" |o--|| "agents" : "FOREIGN KEY (agentId) REFERENCES agents (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agent_task_snapshot" |o--|| "agent_history" : "FOREIGN KEY (versionId) REFERENCES agent_history (versionId) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agent_thread_grants" |o--|| "agent_execution_threads" : "FOREIGN KEY (threadId) REFERENCES agent_execution_threads (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agent_version_skill_dependency" }o--|| "skill_version" : "FOREIGN KEY (skillVersionId) REFERENCES skill_version (id) ON UPDATE NO ACTION ON DELETE NO ACTION MATCH NONE"
"agent_version_skill_dependency" |o--|| "skill" : "FOREIGN KEY (skillId) REFERENCES skill (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agent_version_skill_dependency" |o--|| "agent_history" : "FOREIGN KEY (agentVersionId) REFERENCES agent_history (versionId) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agent_workflow_dependency" |o--|| "workflow_entity" : "FOREIGN KEY (workflowId) REFERENCES workflow_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agent_workflow_dependency" |o--|| "agents" : "FOREIGN KEY (agentId) REFERENCES agents (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agents" }o--o| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agents" }o--|| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"agents" }o--o| "agent_history" : "FOREIGN KEY (activeVersionId) REFERENCES agent_history (versionId) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"agents_memory_entries" }o--o| "agents_memory_entries" : "FOREIGN KEY (supersededBy) REFERENCES agents_memory_entries (id) ON UPDATE NO ACTION ON DELETE NO ACTION MATCH NONE"
"agents_memory_entries" }o--|| "agents_resources" : "FOREIGN KEY (resourceId) REFERENCES agents_resources (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
@ -296,7 +280,6 @@ erDiagram
"folder" }o--|| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"folder_tag" |o--|| "tag_entity" : "FOREIGN KEY (tagId) REFERENCES tag_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"folder_tag" |o--|| "folder" : "FOREIGN KEY (folderId) REFERENCES folder (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"idempotency_key" }o--|| "user" : "FOREIGN KEY (userId) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"insights_by_period" }o--|| "insights_metadata" : "FOREIGN KEY (metaId) REFERENCES insights_metadata (metaId) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"insights_metadata" }o--o| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"insights_metadata" }o--o| "workflow_entity" : "FOREIGN KEY (workflowId) REFERENCES workflow_entity (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
@ -325,9 +308,6 @@ erDiagram
"instance_ai_threads" }o--|| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"instance_credential_assignment" }o--|| "credentials_entity" : "FOREIGN KEY (credentialId) REFERENCES credentials_entity (id) ON UPDATE NO ACTION ON DELETE RESTRICT MATCH NONE"
"migration_finding" }o--|| "workflow_entity" : "FOREIGN KEY (workflowId) REFERENCES workflow_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"migration_workflow_owner" }o--o| "user" : "FOREIGN KEY (assignedById) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"migration_workflow_owner" }o--o| "user" : "FOREIGN KEY (userId) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"migration_workflow_owner" |o--|| "workflow_entity" : "FOREIGN KEY (workflowId) REFERENCES workflow_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"oauth_access_tokens" }o--|| "user" : "FOREIGN KEY (userId) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"oauth_access_tokens" }o--|| "oauth_clients" : "FOREIGN KEY (clientId) REFERENCES oauth_clients (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"oauth_authorization_codes" }o--|| "oauth_clients" : "FOREIGN KEY (clientId) REFERENCES oauth_clients (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
@ -349,33 +329,16 @@ erDiagram
"promotion_connection" }o--|| "promotion_provider" : "FOREIGN KEY (providerId) REFERENCES promotion_provider (id) ON UPDATE NO ACTION ON DELETE RESTRICT MATCH NONE"
"promotion_connection_project" }o--|| "promotion_connection" : "FOREIGN KEY (connectionId) REFERENCES promotion_connection (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"promotion_connection_project" |o--|| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"promotion_review" }o--o| "user" : "FOREIGN KEY (approvedById) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"promotion_review" }o--o| "user" : "FOREIGN KEY (createdById) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"promotion_review" }o--o| "promotion_connection" : "FOREIGN KEY (connectionId) REFERENCES promotion_connection (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"promotion_run" }o--o| "promotion_review" : "FOREIGN KEY (reviewId) REFERENCES promotion_review (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"promotion_run" }o--o| "user" : "FOREIGN KEY (createdById) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"promotion_run" }o--o| "promotion_config" : "FOREIGN KEY (configId) REFERENCES promotion_config (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"role_mapping_rule" }o--|| "role" : "FOREIGN KEY (role) REFERENCES role (slug) ON UPDATE CASCADE ON DELETE CASCADE MATCH NONE"
"role_mapping_rule_project" |o--|| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"role_mapping_rule_project" |o--|| "role_mapping_rule" : "FOREIGN KEY (roleMappingRuleId) REFERENCES role_mapping_rule (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"role_scope" |o--|| "scope" : "FOREIGN KEY (scopeSlug) REFERENCES scope (slug) ON UPDATE CASCADE ON DELETE CASCADE MATCH NONE"
"role_scope" |o--|| "role" : "FOREIGN KEY (roleSlug) REFERENCES role (slug) ON UPDATE CASCADE ON DELETE CASCADE MATCH NONE"
"scheduled_task" }o--|| "scheduled_job" : "FOREIGN KEY (jobId) REFERENCES scheduled_job (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"self_healing_result" }o--o| "user" : "FOREIGN KEY (dismissedById) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"self_healing_result" }o--o| "workflow_suggestion" : "FOREIGN KEY (suggestionId) REFERENCES workflow_suggestion (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"self_healing_result" }o--|| "user" : "FOREIGN KEY (backgroundUserId) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"self_healing_result" }o--|| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"self_healing_result" }o--|| "workflow_entity" : "FOREIGN KEY (workflowId) REFERENCES workflow_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"shared_credentials" |o--|| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"shared_credentials" |o--|| "credentials_entity" : "FOREIGN KEY (credentialsId) REFERENCES credentials_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"shared_workflow" |o--|| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"shared_workflow" |o--|| "workflow_entity" : "FOREIGN KEY (workflowId) REFERENCES workflow_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"skill" }o--o| "user" : "FOREIGN KEY (createdById) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"skill" }o--o| "agents" : "FOREIGN KEY (agentId) REFERENCES agents (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"skill" }o--o| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"skill_file" |o--|| "skill_version" : "FOREIGN KEY (skillVersionId) REFERENCES skill_version (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"skill_version" }o--o| "user" : "FOREIGN KEY (createdById) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"skill_version" }o--|| "skill" : "FOREIGN KEY (skillId) REFERENCES skill (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"test_case_execution" }o--|| "test_run" : "FOREIGN KEY (testRunId) REFERENCES test_run (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"test_case_execution" }o--o| "execution_entity" : "FOREIGN KEY (pastExecutionId) REFERENCES execution_entity (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"test_case_execution" }o--o| "execution_entity" : "FOREIGN KEY (executionId) REFERENCES execution_entity (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
@ -426,10 +389,9 @@ erDiagram
"workflow_review_request_workflow" }o--|| "workflow_review_request" : "FOREIGN KEY (workflowReviewRequestId) REFERENCES workflow_review_request (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"workflow_review_request_workflow" }o--|| "workflow_entity" : "FOREIGN KEY (workflowId) REFERENCES workflow_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"workflow_review_request_workflow" }o--o| "workflow_history" : "FOREIGN KEY (workflowVersionId) REFERENCES workflow_history (versionId) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"workflow_suggestion" }o--|| "workflow_entity" : "FOREIGN KEY (workflowId) REFERENCES workflow_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"workflow_suggestion" }o--|| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"workflow_suggestion" }o--|| "user" : "FOREIGN KEY (backgroundUserId) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"workflow_suggestion_activity" }o--o| "user" : "FOREIGN KEY (actorId) REFERENCES user (id) ON UPDATE NO ACTION ON DELETE SET NULL MATCH NONE"
"workflow_suggestion" }o--|| "project" : "FOREIGN KEY (projectId) REFERENCES project (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"workflow_suggestion" }o--|| "workflow_entity" : "FOREIGN KEY (workflowId) REFERENCES workflow_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"workflow_suggestion_activity" }o--|| "workflow_suggestion" : "FOREIGN KEY (suggestionId) REFERENCES workflow_suggestion (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"workflows_tags" |o--|| "tag_entity" : "FOREIGN KEY (tagId) REFERENCES tag_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
"workflows_tags" |o--|| "workflow_entity" : "FOREIGN KEY (workflowId) REFERENCES workflow_entity (id) ON UPDATE NO ACTION ON DELETE CASCADE MATCH NONE"
@ -566,7 +528,6 @@ erDiagram
varchar status
TEXT toolCalls
datetime_3_ updatedAt
JSON verdict
}
"agent_eval_run" {
varchar_36_ agentVersionId
@ -690,12 +651,6 @@ erDiagram
varchar planId PK
INTEGER revision PK
}
"agent_skill_dependency" {
varchar_36_ agentId PK
datetime_3_ createdAt
varchar_36_ skillId PK
varchar skillVersionId FK
}
"agent_task_definition" {
varchar_36_ agentId FK
datetime_3_ createdAt
@ -731,12 +686,6 @@ erDiagram
varchar_128_ threadId PK
datetime_3_ updatedAt
}
"agent_version_skill_dependency" {
varchar_36_ agentVersionId PK
datetime_3_ createdAt
varchar_36_ skillId PK
varchar skillVersionId FK
}
"agent_workflow_dependency" {
varchar_36_ agentId PK
datetime_3_ createdAt
@ -752,7 +701,6 @@ erDiagram
varchar_255_ projectId FK
INTEGER revision
TEXT schema
varchar_16_ scope
datetime_3_ setupCompletedAt
TEXT skills
TEXT tools
@ -1149,17 +1097,6 @@ erDiagram
varchar_36_ folderId PK
varchar_36_ tagId PK
}
"idempotency_key" {
datetime_3_ createdAt
TEXT fingerprint
varchar_16_ id PK
varchar_128_ idempotencyKey
TEXT responseBody
smallint responseStatus
varchar_16_ status
datetime_3_ updatedAt
varchar userId FK
}
"insights_by_period" {
INTEGER id
INTEGER metaId FK
@ -1412,15 +1349,6 @@ erDiagram
datetime_3_ syncedAt
varchar_16_ targetVersion PK
}
"migration_workflow_owner" {
datetime_3_ assignedAt
varchar assignedById FK
datetime_3_ createdAt
varchar_16_ source
datetime_3_ updatedAt
varchar userId FK
varchar_36_ workflowId PK
}
"oauth_access_tokens" {
varchar clientId FK
varchar token PK
@ -1551,28 +1479,6 @@ erDiagram
varchar_32_ type
datetime_3_ updatedAt
}
"promotion_review" {
datetime_3_ approvedAt
varchar approvedById FK
varchar_36_ connectionId FK
datetime_3_ createdAt
varchar createdById FK
varchar id PK
datetime_3_ lastStateChangeAt
varchar_255_ remoteReviewId
varchar_32_ state
varchar_16_ type
}
"promotion_run" {
varchar_36_ configId FK
datetime_3_ createdAt
varchar createdById FK
TEXT details
varchar_16_ direction
varchar id PK
varchar reviewId FK
varchar_16_ type
}
"role" {
datetime_3_ createdAt
TEXT description
@ -1622,7 +1528,6 @@ erDiagram
INT recurrenceSize
varchar_16_ recurrenceUnit
varchar_128_ taskType
INT timeoutSeconds
varchar_64_ timezone
datetime_3_ updatedAt
}
@ -1645,7 +1550,6 @@ erDiagram
datetime_3_ startedAt
varchar_16_ status
varchar_128_ taskType
INT timeoutSeconds
}
"scope" {
TEXT description
@ -1661,23 +1565,6 @@ erDiagram
varchar_36_ type
datetime_3_ updatedAt
}
"self_healing_result" {
varchar backgroundUserId FK
datetime_3_ completedAt
datetime_3_ createdAt
datetime_3_ dismissedAt
varchar dismissedById FK
varchar_36_ executionId
varchar_36_ id PK
varchar_16_ outcome
varchar_36_ projectId FK
TEXT report
varchar_36_ suggestionId FK
TEXT summary
datetime_3_ updatedAt
TEXT usage
varchar_36_ workflowId FK
}
"settings" {
TEXT key PK
boolean loadOnStartup
@ -1697,35 +1584,6 @@ erDiagram
datetime_3_ updatedAt
varchar_36_ workflowId PK
}
"skill" {
varchar_36_ agentId FK
datetime_3_ createdAt
varchar createdById FK
varchar_36_ id PK
varchar_36_ projectId FK
varchar_16_ source
datetime_3_ updatedAt
}
"skill_file" {
TEXT content
datetime_3_ createdAt
varchar_512_ path PK
varchar skillVersionId PK
datetime_3_ updatedAt
}
"skill_version" {
varchar_64_ contentHash
datetime_3_ createdAt
varchar createdById FK
varchar_1024_ description
TEXT frontmatter
varchar id PK
TEXT instructions
varchar_128_ name
varchar_36_ skillId FK
datetime_3_ updatedAt
INTEGER version
}
"tag_entity" {
datetime_3_ createdAt
varchar_36_ id PK
@ -1793,14 +1651,11 @@ erDiagram
TEXT config
INTEGER configVersion
datetime_3_ createdAt
varchar_36_ discoveryClaimToken
datetime_3_ discoveryClaimedAt
varchar_36_ id PK
varchar issuer
datetime_3_ lastCheckedAt
TEXT lastError
varchar_16_ managedBy
TEXT metadata
varchar_128_ name
varchar_16_ status
varchar_32_ type
@ -2047,10 +1902,6 @@ erDiagram
VARCHAR_128_ workflowName
}
"workflow_suggestion" {
varchar_32_ appliedAction
varchar appliedActorId
varchar_64_ appliedChecksum
varchar_36_ appliedVersionId
varchar backgroundUserId FK
datetime_3_ closedAt
varchar_16_ closedReason
@ -2059,14 +1910,12 @@ erDiagram
varchar_36_ id PK
TEXT payload
varchar_36_ projectId FK
varchar_16_ resultKind
varchar_16_ state
datetime_3_ updatedAt
varchar_36_ workflowId FK
}
"workflow_suggestion_activity" {
varchar_16_ action
varchar actorId FK
varchar_16_ author
datetime_3_ createdAt
varchar_36_ id PK

View File

@ -40,7 +40,6 @@ CREATE TABLE "activity_event" ("id" integer PRIMARY KEY NOT NULL, "category" var
| Name | Definition |
| ---- | ---------- |
| IDX_activity_event_project | CREATE INDEX "IDX_activity_event_project" ON "activity_event" ("projectId", "id") |
| IDX_activity_event_resource | CREATE INDEX "IDX_activity_event_resource" ON "activity_event" ("resourceId", "id") |
| IDX_activity_event_user | CREATE INDEX "IDX_activity_event_user" ON "activity_event" ("userId", "id") |
## Relations

View File

@ -97,7 +97,6 @@ erDiagram
varchar_255_ projectId FK
INTEGER revision
TEXT schema
varchar_16_ scope
datetime_3_ setupCompletedAt
TEXT skills
TEXT tools

Some files were not shown because too many files have changed in this diff Show More