Skip to content

Add data-access-strategy skill: SDK vs FHIR, existing vs custom data - #93

Open
beaugunderson wants to merge 2 commits into
mainfrom
bg-data-access-strategy
Open

Add data-access-strategy skill: SDK vs FHIR, existing vs custom data#93
beaugunderson wants to merge 2 commits into
mainfrom
bg-data-access-strategy

Conversation

@beaugunderson

@beaugunderson beaugunderson commented Jun 8, 2026

Copy link
Copy Markdown
Member

Closes one of the two open review items JP reassigned on the CPB Plugin Development and Release Process doc: a CPA skill that guides when to default to FHIR vs the SDK and when to use existing Canvas data models vs Custom Data, and that captures the reasoning in the plugin spec. (The other open item, making the final UAT an explicit manual review, is a Notion doc edit and is not part of this PR.)

What this adds

New skill data-access-strategy encoding two decisions, both defaulting to the SDK / existing Canvas models and escalating only when the default genuinely can't do the job:

  • SDK vs FHIR. Grounded in the SDK's own constraint that its data models are read-only and mutations happen via Effects or the FHIR API. Reads use the SDK data module unless the data isn't exposed there; writes use an SDK Effect when one exists. FHIR is used only when there is no Effect for the write you need. The choice is independent of handler type: BaseHandler, CronTask (execute() -> list[Effect]), and SimpleAPI (route -> list[Response | Effect]) can all return effects, so a scheduled job or API endpoint writes via Effects just like an event handler. Includes a quick-reference table and the security obligations that apply once FHIR is chosen.

  • Existing models vs Custom Data. Existing Canvas models by default; Custom Data (CustomModel / AttributeHub) only for data Canvas does not model, such as plugin state or external-system id mappings.

How it's wired in

  • plugin-brainstorm agent gains a step to make the data-access decision before the spec is written, so CPA actually consults the skill.

  • The plugin-spec.md template gains a Data Access Strategy section with one line per decision and the reason, so CPA communicates why it took its approach — this is where JP asked for the rationale to live (his June 7 comment supersedes the older tradeoff.md idea still in the doc body).

  • README skill list updated; plugin.json bumped to 1.30.0.

Note for reviewers

The doc body and JP's May comment reference a standalone tradeoff.md; JP's June 7 comment says fold the rationale into plugin-spec.md. This PR follows the June 7 comment (one artifact, rationale in the spec). Easy to switch to a separate tradeoff.md if preferred.

@djantzen

djantzen commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

@beaugunderson When someone chooses FHIR over SDK due to feature unavailability, it would be good for us in Eng to know so that we can consider adding it to the SDK. As an example, there was the Brigade panel dashboard plugin that was using FHIR to obtain staff and patient photos because the SDK didn't expose patient photos. The result was 2 seconds latency just fetching the photos. From a performance perspective, we'd do well to steer people away from FHIR entirely when writing plugins.

@beaugunderson

Copy link
Copy Markdown
Member Author

Yes... I'm curious about how people might feel about telemetry like that in CPA...

@djantzen

djantzen commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Yes... I'm curious about how people might feel about telemetry like that in CPA...

Maybe it could have a feature request skill? It could search Jira for relevant submissions, and if lacking, create a new one. Tricky part is authentication to Jira since CPA could be running anywhere. Maybe Studio Server is the right place for this. Do you anticipate CPA usage going down as we ramp up Studio?

@beaugunderson

Copy link
Copy Markdown
Member Author

I would say usage will decrease but not entirely (you can see this with Investigator... local claude and/or support-stack usage goes down, but there are still scenarios local claude will deliver a faster or better result)

@beaugunderson
beaugunderson requested a review from djantzen June 9, 2026 16:07
- Determine complexity: Simple (1-2 files), Medium (API needed), Complex (UI app)
3. **Write the spec file immediately** - don't ask more questions
3. **Decide the data access strategy** using the **data-access-strategy** skill:
- For every read and write, choose **SDK vs FHIR** — default to the SDK, use FHIR only when the SDK can't do it (data not in the data module, or a write with no matching Effect).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case that FHIR is the only option, it would be hugely valuable for folks in Eng and Product to know that the decision has been made, so that we can prioritize adding the capability to the SDK. FHIR calls from plugins should be avoided. I don't know how to do this though. Can CPA open a ticket in the repo maybe?

@djantzen djantzen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left one comment, otherwise makes sense

beaugunderson and others added 2 commits August 31, 2026 18:31
CPA now has explicit guidance for two data-access decisions, both
defaulting to the SDK/existing models and escalating only when needed:

- SDK vs FHIR: SDK data module for reads, Effects for writes; FHIR only
  when data is not exposed in the SDK or a write has no matching Effect
  (or runs outside an event context).
- Existing Canvas models vs Custom Data: existing models by default,
  Custom Data only when nothing in Canvas represents the data.

Wired into plugin-brainstorm so the decision happens before the spec is
written, and the plugin-spec.md template gains a Data Access Strategy
section so CPA records why it chose its approach.

Co-Authored-By: Claude <noreply@anthropic.com>
The SDK-vs-FHIR write rule incorrectly claimed writes from CronTask,
SimpleAPI, or webhooks require FHIR because they run 'outside an event
context.' They don't: CronTask.execute() returns list[Effect] and
SimpleAPI routes return list[Response | Effect], so both write via
Effects just like a BaseHandler. The only question is whether an Effect
exists for the write; handler type is irrelevant.
@canvas-sisyphus

Copy link
Copy Markdown

Rebased bg-data-access-strategy onto main (resolved conflicts locally) and force-pushed, preserving the branch's individual commits. Force-pushed rebased bg-data-access-strategy to 40a1cdd (2 commits, 8 file changes)

@canvas-sisyphus
canvas-sisyphus Bot force-pushed the bg-data-access-strategy branch from 2036d8b to 40a1cdd Compare September 1, 2026 01:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants