Support channels in the provisioner API#4757
Merged
Merged
Conversation
GET /api/provision/:id and POST /api/provision now round-trip channels alongside workflows and collections. JSON exposes destination_credential_id; YAML uses a hyphenated email-credential-name key under destination_credential (matching how jobs reference credentials). Channel deletion is rejected with an actionable error directing the user to the dashboard. channel_requests have a RESTRICT FK that needs draining first, and the dashboard handles that transactionally — the provisioner shouldn't. Channel changes emit the same audits as Channels.create_channel/2 and update_channel/3 (created/updated plus auth_method_added/removed/changed for the destination credential). The provisioner runs a per-channel Multi with Multi.put(:channel, ...) so it reuses Audit.audit_auth_method_changes/3 unchanged. The :channels has_many was moved above :project_credentials on Project so Ecto's reverse-declaration child-processing order inserts project_credentials before channel_auth_methods, letting the destination FK resolve when both are created in the same import.
…ials
Two follow-ups from the channels-in-provisioner review:
1. Cross-project credential validation. maybe_add_project_credentials/2 now
runs inside parse_document/2 so by the time channels and jobs are cast,
the changeset's :project_credentials assoc holds the authoritative set of
PCs for this project. channel_changeset and job_changeset share a
validate_project_credential_in_project/2 helper that rejects any
project_credential_id outside that set. Mirrors the existing Job FK
constraint message ("credential doesn't exist or isn't available in this
project") and closes the gap for the channel destination credential.
2. Batched channel audits. Channels.Audit.audit_auth_method_changes/4 now
takes the channel struct directly (no more :channel Multi-state lookup)
and generates unique step keys via System.unique_integer/1, so it
composes into a larger Multi any number of times. The provisioner folds
every channel's audits into a single Multi and runs one transaction
instead of one per channel. Channels.create_channel/2 keeps the
deferred-id case working via Multi.merge; Channels.update_channel/3
passes the channel directly.
Tests cover cross-project rejection for both channel destination
credentials and job credentials.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4757 +/- ##
==========================================
+ Coverage 90.02% 90.04% +0.02%
==========================================
Files 448 448
Lines 22487 22557 +70
==========================================
+ Hits 20243 20312 +69
- Misses 2244 2245 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Security Review ✅
|
3 tasks
elias-ba
approved these changes
May 18, 2026
Contributor
elias-ba
left a comment
There was a problem hiding this comment.
Really nice one dude 👏🏽
…channels-in-provisioner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
GET /api/provision/:id and POST /api/provision now round-trip channels alongside workflows and collections. JSON exposes destination_credential_id; YAML uses a hyphenated email-credential-name key under destination_credential (matching how jobs reference credentials).
Channel deletion is rejected with an actionable error directing the user to the dashboard. channel_requests have a RESTRICT FK that needs draining first, and the dashboard handles that transactionally — the provisioner shouldn't.
Channel changes emit the same audits as
Channels.create_channel/2andupdate_channel/3(created/updatedplusauth_method_added/removed/changedfor the destination credential).The
:channels has_manywas moved above:project_credentialsonProjectsoEcto's reverse-declaration child-processing order insertsproject_credentialsbeforechannel_auth_methods, letting the destination FK resolve when both are created in the same import.Closes #4522
Validation steps
AI Usage
Please disclose whether you've used AI anywhere in this PR (it's cool, we just
want to know!):
You can read more details in our
Responsible AI Policy
Pre-submission checklist
/reviewwith Claude Code)
(e.g.,
:owner,:admin,:editor,:viewer)