Add note_lock_webhook plugin - #412
Open
hardylt wants to merge 1 commit into
Open
Conversation
Watches note state changes and POSTs the note id and patient id to an external endpoint when a note is signed (state == "SGN"). The payload is deliberately minimal: the two identifiers are enough to make follow-up calls to the Canvas FHIR API for whatever else a downstream system needs. The webhook URL and an optional bearer token are read from plugin secrets (WEBHOOK_URL, AUTH_TOKEN), following the convention used by task_webhook_notification. Non-signed state changes return early without making a request, so the plugin is inert for the majority of note events. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jul 20, 2026
Author
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.
What this plugin does
note_lock_webhookwatches note state changes in Canvas and POSTs to an external endpoint the moment a note is signed (state == "SGN").The payload is deliberately minimal:
{ "state": "SGN", "note_id": "<note id>", "patient_id": "<patient id>" }Those two identifiers are enough to make follow-up calls to the Canvas FHIR API for the full note, the encounter, or the patient chart — so the webhook stays fast and carries no PHI beyond identifiers.
Why
A signed note is the point at which clinical documentation becomes final, and it's the natural trigger for downstream work: billing and coding review, care-coordination handoffs, quality reporting, warehouse sync, patient follow-up.
Without a push signal, external systems have to poll the FHIR API on a timer and diff results to notice a note was signed — wasteful when nothing changed, and slow exactly when latency matters. This inverts that.
Implementation notes
NOTE_STATE_CHANGE_EVENT_UPDATED. Canvas emits this for every transition; the protocol returns early on anything that isn'tSGN, so it's inert for the majority of note events.WEBHOOK_URL(required) andAUTH_TOKEN(optional bearer) are plugin secrets, following the convention intask_webhook_notification. Nothing needs editing in the source to install it.SIGNED_STATEconstant, so pointing it atLKDor another state is a one-line change.Structure
Follows the
billing-dashboardlayout:README.md,LICENSE(MIT),pyproject.toml, anote_lock_webhook/code folder withCANVAS_MANIFEST.jsoninside it, andtests/.Tests
11 tests covering payload shape, target URL, bearer header present/absent, error logging on non-2xx, and no-request behavior across
NEW/LKD/ULK/DEL/None.One thing worth a maintainer's eye: I could not install
canvas_sdkin my dev environment, so I verified these against stub modules rather than the real SDK. The branching logic and test wiring are exercised, but a run against the actual SDK would be a useful check.🤖 Generated with Claude Code