Summary
Enhance the parties DSL on Instance resources to support multiplicity, graph storage strategy, and live calculated parties. The existing party :role, Type form is not broken — this adds new capabilities on top.
Proposed DSL
parties do
party :provider, Provider, calculate: :provider_calculation
parties :installer, Installer
parties :technician, Technician, constraints: [min: 1, max: 3]
party :managed_by, Engineer, reference: true
end
Concepts
Multiplicity — follows the Ash relationship naming pattern:
party — singular, at most one party in this role
parties — plural, unbounded by default
constraints: [min:, max:] — bounds on a parties declaration; party implies max: 1 without needing to say so
Reference — reference: true means no direct PartyRef edge is created. The party exists in the graph and is reachable by traversal through the party hierarchy. Used to manage graph density when direct edges per party instance would be expensive.
Calculated party — calculate: :calculation_name references an Ash calculation declared on the resource. This is not a default or fallback — it is the live definition of how that party is always derived at build time. The calculation must return the declared party type. The calculation is a black box — it can derive, load, hardcode, or look up the party however the domain needs.
This is where the DSL moves beyond structure into behaviour: a party declaration can encode not just what roles an instance plays, but how those parties are computed — live, from context, at build time.
Compile-time — all declarations are compile-time, introspectable via InstanceInfo.parties/1. Role names are domain-specific atoms; the framework does not interpret them.
Notes
reference: true and calculate: are independent options and can be combined.
- The same pattern should be considered for
Party.Extension instance do / party do blocks.
Summary
Enhance the
partiesDSL on Instance resources to support multiplicity, graph storage strategy, and live calculated parties. The existingparty :role, Typeform is not broken — this adds new capabilities on top.Proposed DSL
Concepts
Multiplicity — follows the Ash relationship naming pattern:
party— singular, at most one party in this roleparties— plural, unbounded by defaultconstraints: [min:, max:]— bounds on apartiesdeclaration;partyimpliesmax: 1without needing to say soReference —
reference: truemeans no directPartyRefedge is created. The party exists in the graph and is reachable by traversal through the party hierarchy. Used to manage graph density when direct edges per party instance would be expensive.Calculated party —
calculate: :calculation_namereferences an Ash calculation declared on the resource. This is not a default or fallback — it is the live definition of how that party is always derived at build time. The calculation must return the declared party type. The calculation is a black box — it can derive, load, hardcode, or look up the party however the domain needs.This is where the DSL moves beyond structure into behaviour: a
partydeclaration can encode not just what roles an instance plays, but how those parties are computed — live, from context, at build time.Compile-time — all declarations are compile-time, introspectable via
InstanceInfo.parties/1. Role names are domain-specific atoms; the framework does not interpret them.Notes
reference: trueandcalculate:are independent options and can be combined.Party.Extensioninstance do/party doblocks.