Add pipeline draft CRUD endpoints for RDI instances - #6467
Conversation
Code Coverage - Backend unit tests
Test suite run success3829 tests passing in 328 suites. Report generated by 🧪jest coverage report action from e20ca94 |
Code Coverage - Integration Tests
|
477b475 to
d40b4db
Compare
d40b4db to
0d3bf38
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0d3bf38753
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
0d3bf38 to
c4db648
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c4db648d2f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
c4db648 to
7aabd35
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0d988a4dfe
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 39afac0654
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 39afac0. Configure here.
39afac0 to
ae0e0c1
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ae0e0c1955
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Adds a pipeline_draft table and list/get/create/update/delete endpoints under rdi/:id/pipeline-drafts, so RDI pipeline work-in- progress can be persisted per instance. Drafts are orphan-removed via a DB-level ON DELETE CASCADE FK to the rdi table (mirroring the query-library module's FK pattern), and data is encrypted at rest via the existing ModelEncryptor. The data column is stored as a JSON string (required since encryption only operates on strings) but exposed as a real object at the API model layer via the existing DataAsJsonString decorator, the same mechanism already used by AiQueryMessageEntity.steps.
Enables ValidationPipe whitelisting on the pipeline-draft controller so an unexpected id field on a create/update body can no longer overwrite an unrelated draft via TypeORM's upsert-on-save behavior. Fixes update() double-encoding the persisted data column when a PATCH omits data: the already-JSON-stringified value was being routed back through @DataAsJsonString(), stringifying it a second time.
Rejects null data on PATCH instead of silently treating it as omitted (PartialType's IsOptional skips validation for null the same as undefined). Validates the parent RDI instance exists before creating a draft, translating a missing/deleted instance into a 404 instead of an uncaught foreign-key constraint error. Declares the entity's index to match the migration so schema-diff tooling doesn't see it as extraneous. Stops tolerating decrypt failures in update(), since silently swallowing them would overwrite valid ciphertext with null.
Excludes drafts whose data decrypt returned null due to an encryption strategy mismatch, rather than only handling decrypt exceptions - the plain strategy returns null instead of throwing when the stored value was encrypted with a different strategy. Uses the existence-only RDI lookup for the parent check in create(), so a draft can still be created even if the RDI instance's stored credentials can no longer be decrypted.
ae0e0c1 to
e20ca94
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e20ca94fb7
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

What
Third PR in the rdi-ui integration chain (stacked on #6465, which is stacked on #6464).
Adds a
pipeline_drafttable and CRUD endpoints underrdi/:id/pipeline-drafts(list/get/create/update/delete), so RDI pipeline work-in-progress can be persisted per instance ahead of the realrdi-uicomponent being wired in.Key points:
pipeline_draft.rdiInstanceId -> rdi.idwithON DELETE CASCADEat the DB level, mirroring thequery-librarymodule's existing FK-to-parent pattern. No manual cleanup code needed when an RDI instance is deleted.datais encrypted at rest via the existingModelEncryptor, same mechanism asRdiEntity.passwordandQueryLibraryEntity's fields.text/string column (encryption only operates on strings), but it's decorated with the existing@DataAsJsonString()decorator so every layer above the entity (API model, DTOs, controllers) works with a real JSON object, not a string — same mechanism already used byAiQueryMessageEntity.steps. Structure of the JSON itself is intentionally not validated/typed.RdiPipelineController's existingrdi/:id/...nesting convention andquery-library's repository/service/controller layering as templates.Testing
npm run lint:apiandnpm run type-check --prefix redisinsight/api(0 new errors) pass.dataas JSON string internally while exposing a real object externally), service, and controller.rdimodule test suite (286 tests) still passes.No ticket yet.
Note
Medium Risk
New encrypted persistence and CRUD surface for RDI draft data; repository edge cases around decrypt failures affect data visibility and updates, but patterns match existing RDI/query-library modules.
Overview
Adds persisted RDI pipeline drafts so in-progress pipeline JSON can be saved per instance before the UI is wired up.
A new
pipeline_drafttable (migration + TypeORM entity) stores encrypted draftdatakeyed byrdiInstanceId, with ON DELETE CASCADE when an RDI instance is removed. The API exposes full CRUD atrdi/:id/pipeline-drafts, using the existingRequestRdiClientMetadatanesting and validation (create whitelists body fields; update rejects explicitnullfordata). Create verifies the parent RDI exists viaRdiRepository.get(..., true)without decrypting credentials.Persistence goes through
LocalPipelineDraftRepository, which encryptsdatawithModelEncryptor, exposes JSON objects via@DataAsJsonString(), skips undecryptable rows on list, and avoids overwriting ciphertext on failed decrypt during update.RdiModuleand ORM config register the new stack; controller/service/repository specs cover the behavior.Reviewed by Cursor Bugbot for commit e20ca94. Bugbot is set up for automated code reviews on this repo. Configure here.