Workflows: placeholders that follow a reference and loop over related entries
- Dominant language
- C#
- Stars
- 6
- Forks
- 7
- Avg merge
- 4h 42m
- Merged PRs (30d)
- 307
Description
Found by simulating a Claude Code build of Color Me Fun 2026 through the barako CLI (epic #801) on 14 September 2026; the event registration app for the Rotary Club of Koronadal is the acceptance test. Simulation page: https://claude.ai/code/artifact/05afda1a-6461-431d-aff0-50b30d3b0778
Workflow placeholders resolve `{{id}}`, `{{contentType}}`, `{{status}}`, `{{createdAt}}`, `{{updatedAt}}` and `{{data.Field}}` against the triggering entry only (`TemplateVariableExtractor.cs`). `{{data.Supplier.Email}}` is looked up as a field literally named `Supplier.Email` and left in the output unreplaced. So an email cannot reach a referenced supplier, and a group leader's summary cannot list the batch's runners.
## Change
- **Follow a reference:** `{{data.Supplier.Email}}` loads the referenced entry and reads its field, through the same sensitivity rules delivery applies, to a fixed depth.
- **Loop over related entries:** a block such as `{{#each related registration.GroupBatch}}{{data.FirstName}} {{data.BibNumber}}{{/each}}`, bounded in count.
- An unresolvable placeholder in a live run is recorded on the run as an error rather than sent as raw text.
Keeps the single-pass rule that stops a field value injecting another placeholder.
## Done when
- A workflow on an order emails `{{data.Supplier.Email}}` and uses the supplier's address in the body.
- A batch summary lists every runner in the batch, and a hidden field of a runner never appears.
Contributor guide
Research direction
Start with TemplateVariableExtractor.cs and trace how workflow placeholders resolve against the triggering entry and how delivery applies sensitivity rules. Use the barako CLI simulation and the Color Me Fun 2026 registration app as the acceptance context. Done means referenced fields resolve, bounded related-entry loops list runners without exposing hidden fields, and unresolved placeholders are recorded as run errors rather than sent.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend, content
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100