Skip to content

Insights route→loader map (which workflow fills the grid, per form)

Status: VERIFIED in the Dev app (2026-06-05). The model below was confirmed end-to-end by building and importing packages and watching the panel in Aareon Mobile. First proof point: Unvented Hot Water Storage v9 is Active in Dev with the insights panel populating from the Repair Works Order. Read insights-piece.md for anatomy and insights-rollout-plan.md for the recipes.

The model (confirmed)

A form's insights grid populates only if the task the form runs in has its GenBPInsight group filled (via $QL_Property_Insights$ / [Versaa].[usp_all_insights], keyed on GenBP_Key_PropertyId). There are three ways that happens — the third was discovered during in-app testing and is the most important correction:

Pattern How the group gets filled Recipe for the form
Loader-route the launch/load workflow runs the insight query into the task display + switch (data already there)
Inherited (sub-task of a loaded master) the form runs inside a parent task (e.g. an RWO) whose loader already filled GenBPInsight; the sub-task shares/inherits that group display + switch ONLY — do NOT add a self-loader
Self-trigger the form fires *.AppendPropertyInsights itself (a RequestPropertyInsights request + an autoSend RequestButtonElement) display + switch + self-loader

⚠️ The duplication rule (learned the hard way)

The Append Property Insights handler appends rows; it does not replace. So if a task receives insights from two sources, you get duplicate rows. This is exactly what happened on the Unvented Hot Water Storage pilot: it is a sub-task opened inside the Repair Works Order task (note the form header still reads "Repair Works Order"), the RWO already loaded insights, and adding the self-loader appended a second copy. Neither autoSendOnceOnly=True nor hiding the trigger button fixed it, because the two copies came from two different sources. Fix: for inherited sub-tasks, ship display-only (no loader).

So the decisive question per form is not "which loader" but: does the task this form runs in already have insights? If yes → display-only. If no → add the self-loader.

Loader inventory — workflows that DO load insights (XML-confirmed)

Each runs a GetTableDataWorkflowStep with queryData="$QL_Property_Insights$" into GenBPInsight:

Loader workflow Launch route it serves
Property+Search_57 generic Property Search launches (gated by $Insights_OnSwitch$ == true)
FRA+Property+Search_20 / _23 FRA property search
Repair+Works+Order+QL+Data_16 the RWO master task's data load — feeds its sub-tasks (UvHWS, NIBE, Damp & Mould) by inheritance
ClientVisitBasicLoad_13 / _17 the Client Visit master task's data load
Estate+Search_40 estate search (explicitly maps Tap Flushing Check)
Order+Appointment_9 appointment-ordered tasks ("Get Insight Data" step)
Append+Property+Insights_15 the reusable handler — message-start *.AppendPropertyInsights, needs only GenBP_Key_PropertyId. Target of the self-trigger.

Launchers that do NOT load insights: Create+Jobs_3 (creates Void Survey, Void Post Inspection, Repair Post Inspection), Property+Check+Appoint+LoadDat_30 (PCA data load — PCA itself does not push insights; the appointment path does via Order+Appointment_9).

Worklist — category per form (corrected after testing)

Form Dev v Runs in / launched by Task already has insights? Recipe Status
Unvented Hot Water Storage 9 (Active, Dev) sub-task inside RWO Yes (inherits) display + switch only ✅ verified in app 2026-06-05
NIBE 4 sub-task inside RWO Yes (inherits) display + switch only to build (same as UvHWS)
Damp & Mould Inspection 60 sub-task inside RWO Yes (inherits) display + switch only to build (same as UvHWS)
Void Survey 30 Create Jobs (own task, no insight loader) No display + switch + self-loader to build/verify (confirm property id present)
Tap Flushing Check 40 Estate Search (loads insights) likely yes display + switch (verify) later
Succession Inspection 4 separate task from Client Visit unknown — verify likely self-loader later
Relinquishment Inspection 4 separate task from Client Visit, no property context n/a C — skip / standalone Insights later
Mobility Scooter Assessment 6 separate task from Client Visit (11 uses/5 yrs) n/a C — skip (negligible) Peter: "probably not"
Complaint 13 QL worktray (own task) verify property context self-loader or C later
EAI ×5 Estate process Estate Search loads insights — verify maybe display-only; else C later

Corrections this testing made to the earlier (XML-only) prediction

  1. RWO sub-tasks (UvHWS, NIBE, Damp & Mould) are NOT "Category B data-push". They run inside the RWO task and inherit its insights → display-only. The earlier map predicted they'd need a master→sub-task push or a self-loader; in-app testing showed the data is already there and a self-loader duplicates it.
  2. The injector was missing the on-screen Show/Hide switch. The toggle data item z_Insights_Switch was added but no display control, so the panel showed unconditionally with no toggle. Fixed by adding switch_control.frag (an OptionsListRadioButtonElement).
  3. The insights grid must have showAdd=False (no Add button — users can't add insight rows) and showEdit=True (users can tap a row to view detail). Per Mark in the catch-up: "we don't need the show ad… not going to be adding anything to it" and "they want to edit because it allows them to go into it and have a look inside."
  4. Management Studio assigns its own sequential version on import — the manifest version number in the .ftpackage is cosmetic; MS takes the next number. (Five pilot imports of a "v5" package became Dev versions 5→9.)

Build recipe (what goes in each package)

Built with versaa-rag/insights_injector/ against a fresh Dev pull:

  • Inheriting forms (RWO sub-tasks): inject.py "<Form>_<v>" (no flag) → display group + grid (showAdd=False, showEdit=True) + z_Insights* toggle items + switch control.
  • Non-inheriting forms (e.g. Void Survey): inject.py "<Form>_<v>" --with-trigger → all of the above plus the RequestPropertyInsights request + an autoSend RequestButtonElement. (The auto-fire must be configured like Mark's Asbestos Data button — fire once, self-hide after load — to avoid the append-duplicate trap; settle this in-app for Void Survey.)
  • Wrap with build_package.py; import to Dev as a new version; test in app; then activate and migrate Dev→Test→Live.

Reference DONE forms (for templates)

Form Populates via
Repair Works Order v74 RWO QL Data loader — the master feeding UvHWS / NIBE / Damp & Mould
Routine Tenancy Visit Property Search loader (canonical source of the display fragments)
Family Survey 2 MW v73/74 the form-side AppendPropertyInsights self-trigger pattern
Asbestos Data v42 the autoSend (fire-on-open, self-hiding) button pattern