Schools automate communication across the admission journey — Enquiry → Application → Review → Decision → Enrolment → Payment. This prototype defines the forms, the status model, the node set, and nine workflows that cover the full journey. Small workflows chained by status changes, instead of one giant flow.
Enquiry and Application are school-configurable dynamic forms (solution design 01) — the data entry points whose fields feed triggers, conditions and personalization. Offer and Student are fixed-schema records, identical for every school, created only by workflows via the Create record node with field mappings. An Application is only created when a parent actually starts one (via a tokenized link carrying the enquiry id) — never auto-created — so an application's existence always means real intent.
First touch. Creates a Contact + Enquiry record.
Prefilled from the enquiry. Converts the enquiry on submit.
Prefilled from the application via field mappings. The family responds through the offer link — their decision and payment write back to this record.
The enrolled child. Created when the offer is accepted and paid; its status change fires the welcome workflow.
Status changes are what chain the nine workflows together — and they are the only thing that can trigger one. Status fields are dropdown-backed, so triggers, branch conditions and Update-field actions always reference these exact values.
Five node categories, numbered below. Trigger, Branch, Loop and End are single nodes; Action is one category with six subtypes. Loops are deliberately constrained: max iterations and an exit condition are mandatory.
Every workflow is a straight line with at most one split — loops handle repeated reminders, status changes hand off to the next workflow. Click any node for its full configuration.
The creation experience is a separate canvas page: a workflow starts as Trigger → End, the + icon on an edge opens the node panel, and every node's configuration is edited in place.
Open workflow builder →Decisions locked for this round, and what is deliberately out of scope.
Exit condition is checked at the start of every iteration and acts as a live interrupt during delays — if the parent pays on day 2 of a 5-day wait, the run exits immediately. After max iterations the flow falls through to the next node.
Every workflow starts the same way: a form's field reaches a value (submission is just field = status, value = Submitted). "Nothing happened yet" is expressed inside the flow as Delay + Branch — one mental model, no hidden timers outside the canvas.
One active run per workflow per applicant. Re-triggering while a run is active does nothing. A duplicate enquiry from a known email/phone attaches to the existing contact.
The team makes the money decision by setting application status = Accepted. The workflow then creates the offer record itself (Create record node) — prefilled from the application via field mappings, amount derived from the fee structure — and the offer-delivery workflow takes over from offer.status = Created. The team never creates or sends offers manually.
A run executes against a family's linked record chain: enquiry → application → offer → student. Every field reference (conditions, updates, recipients, mappings) is scoped to the trigger's form and its upstream forms — they're guaranteed to exist. Downstream references are illegal; records downstream are reached by creating them (Create record) and letting their triggers fire.
For now an email or SMS/WhatsApp message is a plain title + description, sent only inside its configured send window (queued otherwise). Later: dynamic fields via tokens like {{application.name}} resolved per family at send time, and a rich text editor for email bodies (formatting, links, images).