The Visit Confirmed plugin for Canvas Medical, built on the Canvas SDK. It forwards appointment lifecycle events to Visit Confirmed, which runs AI-driven SMS/voice confirmation and rebooking.
This is a standalone, public, open-source package — separate from the main
(private) Visit Confirmed Django application. It targets the Canvas runtime
(Python 3.11/3.12) and is intended for submission to the Canvas extensions
catalog via a PR to Medical-Software-Foundation/canvas.
The published listing's description lives in visit_confirmed/README.md;
this file is developer/build notes.
visit_confirmed/ # the plugin package (matches CANVAS_MANIFEST name)
CANVAS_MANIFEST.json # components, variables, FHIR scopes -> feeds the catalog
README.md # public catalog listing (publishing-checklist compliant)
docs/ # images embedded by the listing README
handlers/
appointment_events.py # BaseHandler: forwards APPOINTMENT_* events to VC
tests/
test_appointment_events.py # behavior tests (reconcile with `canvas init` scaffold)
pyproject.toml
pip install canvas # Canvas CLI (Python 3.11 or 3.12)
canvas init # OPTIONAL: regenerate the official scaffold, then
# overlay this handler/manifest/README + reconcile tests
canvas install visit_confirmed
Then set VISIT_CONFIRMED_API_URL and VISIT_CONFIRMED_API_KEY on the plugin
settings page.
Submission target: extensions/visit-confirmed/ in
Medical-Software-Foundation/canvas,
per its CONTRIBUTING.md
(fork and PR). Review criteria are in that repo's REVIEW.md.
- Optional: swap in a real product screenshot if one exists that does not show stale or identifiable data. The current image is an illustration.
Resolved:
-
sdk_versionstays0.1.4. It tracks the manifest schema, not the CLI version, and is whatcanvas initemits and what every merged reference plugin declares. -
Reviewed against the catalog repo's
CLAUDE.mdplugin checklist, not justREVIEW.md. That surfaced the missingentered_in_errorfilter and the missingselect_related, both now fixed. -
The listing screenshot is
visit_confirmed/docs/canvas-appointment-confirmation.png, rendered from the committed.source.htmlbeside it via headless Chrome:chrome --headless=new --force-device-scale-factor=2 --window-size=1000,700 --screenshot=.... It reuses the SMS copy already vetted on the/integrations/canvas/landing page, so it carries no write-back claim and keeps the practice (never Visit Confirmed) as the visible sender. No logo is embedded: the publishing checklist does not count one, and the compliant reference plugin (missed-appointment-notifications) ships a screenshot only. -
Tests run against the real SDK: mypy clean under
mypy.ini, 6 tests passing, 100% branch coverage,canvas validateloading the handler in the sandbox. -
data_access.readnow declaresStaff, which the handler needs forappointment.provider.id. Scope/code mismatch is a blocking review finding. -
components.handlersandvariables(withsensitive: true) replacecomponents.protocolsand the deprecatedsecretskey. Both validated against the CLI's officialmanifest_schema.py. -
Repo home is this public repo. Branded vendor listings are accepted in
Medical-Software-Foundation/canvas: seeextensions/nabla, which carries vendor logo, marketing copy, and a vendor-account requirement. Thegtm-extensionsquestion is moot.