Skip to content

Add documentation and improve dev ex for CE Workflow Templates - #6787

Open
martha wants to merge 6 commits into
mainfrom
mec/8559-docs
Open

Add documentation and improve dev ex for CE Workflow Templates#6787
martha wants to merge 6 commits into
mainfrom
mec/8559-docs

Conversation

@martha

@martha martha commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Merging this PR

  • use the squash-merge strategy for PRs targeting main

Description

  • Add README_FOR_CE_WORKFLOW_BUILDERS.md documenting the two CE workflow builder patterns and trimming the now-redundant "Updates" sections from the PH/Standard per-client READMEs in favor of a single shared doc.
  • Update delete_template_and_associated_data and delete_form_definitions to include soft-deleted (with_deleted) instances/steps/referrals and to destroy associated Hmis::Form::FormProcessor rows before destroying steps/form definitions, so repeated local rebuilds don't leave orphaned records that block form definition deletion.
  • Add a delete_opportunities: option to delete_template_and_associated_data. Set it to false for the AZ direct referral workflow to test/prove the new option. Rebuilding that template no longer wipes associated opportunities.
  • Remove dependent: :nullify from Hmis::WorkflowDefinition::Template#unit_groups / #direct_referral_unit_groups so destroying a template in dev no longer clears unit groups' template identifier references, easing local iteration.
    • Alternative considered: Manually clear the columns in delete_template_and_associated_data unless the new delete_opportunities option is false, in order to maintain the previous behavior except when otherwise specified. I didn't pursue that since I thought it would be more cruft than needed for a low-risk change.

Type of change

  • Documentation
  • Behavior change on template deletion

Checklist before requesting review

  • I performed a self-review of my code
  • I ran the OP review skill
  • I ran the code that is being changed under ideal conditions, and it doesn't fail
  • If adding a new endpoint / exposing data in a new way, I have:
    • ensured the API can't leak data from other data sources
    • ensured this does not introduce N+1s
    • ensured permissions and visibility checks are performed in the right places
  • Any major architectural changes are supported by an approved ADR (Architectural Decision Record)
  • I updated the documentation (or not applicable)
  • I added spec tests (or not applicable)
  • I provided testing instructions in this PR or the related issue (or not applicable)

identifier = 'mc_direct_referral'
template_name = 'Direct Referral'
CeWorkflows::Shared::CeBuilderUtils.delete_template_and_associated_data(identifier, data_source: @data_source) unless @unsafe_run_in_production
CeWorkflows::Shared::CeBuilderUtils.delete_template_and_associated_data(identifier, data_source: @data_source, delete_opportunities: false) unless @unsafe_run_in_production

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added this to test/prove the new behavior locally

template.destroy!
end

def self.delete_form_definitions(form_definition_identifiers, data_source_id)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This method is only called in code by the Standard workflow builder rake task (the non-preferred pattern), but I was still finding it useful to run in dev when iterating on workflow template forms, so I've included the local updates that have been helpful.

@martha
martha requested a review from gigxz July 30, 2026 18:52
@martha
martha marked this pull request as ready for review July 30, 2026 19:03

- In practice, devs used `FORCE_RECREATE` anyway because drafts can't be used for referrals.
- Idempotent `connect_if_not_connected`-style guards add complexity and cruft.
- Implies that we support changing a prod template *without* incrementing the version number, which we don't want to support.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@gigxz in this bullet I was trying to articulate the concern you expressed on our huddle about this pattern, but I'm not sure I quite captured it - let me know if I should rearticulate this, or there is another reason I should add to this list?

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.

I think this makes sense


## Updates

Updates to Workflow Templates fall into two categories. See [https://github.com/open-path/Green-River/issues/8515](https://github.com/open-path/Green-River/issues/8515).

@gigxz gigxz Jul 31, 2026

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.

It's good that we're linking 8515 somewhere, but I'm not sure this is the right place. The issue doesn't explain the two categories. Maybe we can reference this on line 91?

Comment on lines +91 to +92
- We don't yet have an established pattern for handling this in production.
- The non-preferred draft-idempotent pattern was partly built to handle this, but due to the downsides listed above, we're retiring that pattern and will cross this bridge when we re-encounter it.

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.

Suggested change
- We don't yet have an established pattern for handling this in production.
- The non-preferred draft-idempotent pattern was partly built to handle this, but due to the downsides listed above, we're retiring that pattern and will cross this bridge when we re-encounter it.
- We don't yet have an established pattern for handling workflow changes in production. The outstanding ticket for it is https://github.com/open-path/Green-River/issues/8515
- In local development and staging environments, we use a destructive operation to delete all old referrals when we need to update a workflow template. This should never be done in production.

| ------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| **Template lifecycle** | `delete_template_and_associated_data` → `create_template` (published) | `find_or_create_draft_template` → mutate in place → optional `PUBLISH=true` |
| **Strategy for changing existing template** | Wipes existing template and starts anew | Idempotent on hard-coded version while draft; errors once published |
| **Prod setup** | One-time via `UNSAFE_RUN_IN_PRODUCTION=true` (builder + rake guard) | `PUBLISH=true`; no destroy in prod |

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.

This is not an env var that exists

The documented UNSAFE_RUN_IN_PRODUCTION=true env var does not exist anywhere in the codebase. Both AC and AZ rake tasks raise unconditionally in production (ce_define_workflows.rake:8, ce_define_az_workflows.rake:10), and unsafe_run_in_production: is only a Ruby keyword argument on WorkflowBuilder#initialize. Anyone following this doc for initial prod setup would hit the rake guard with no way past it.

def build_my_workflow
identifier = 'my_workflow'
CeWorkflows::Shared::CeBuilderUtils.delete_template_and_associated_data(
identifier, data_source: @data_source, delete_opportunities: false

@gigxz gigxz Jul 31, 2026

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.

So this is suggesting that even when setting up a workflow for the first time in production, we should be passing delete_opportunities: false which could potentially lead to dangling references and opportunities without a workflow template? but it's okay because that's guaranteed not to happen as long as the template identifier name didn't change, because it immediately recreates it right after (and is run in a transaction as long as its invoked via rake task..)?

It might be helpful to add a comment somewhere documenting the reasoning behind the delete_opportunities flag.

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