---
name: create-process
description: >
    Use when creating or modifying .processflow.xml files for CG Mobile modeler flows.
    A process orchestrates BO/LO loading, decision logic, UI display, BL calls, and sub-process
    invocation. A process often pairs with a UI in the same folder (see create-ui-page).
    Invokes create-business-object, create-list-object, or create-lookup-object first if any
    BO/LO/LU referenced in Declarations does not yet exist.
    Trigger phrases: "process for X", "workflow for X", ".processflow.xml", "DECISION flow",
    "wizard for X", "dialog process for X", "CONFIRM dialog for X", "process that loads X",
    "create a process that", "process file for X".
---

# Create Process — CG Mobile Modeler

A `.processflow.xml` file is the orchestration layer of the mobile app. It coordinates loading
and saving BOs/LOs, executing BL methods, displaying UI screens, and making conditional decisions.
Every process lives under `src/<Module>/PR/<FlowName>/` and may optionally be paired with a sibling
`.userinterface.xml` in the same folder.

## When to Use This Skill

| Invoked by      | Phrase                                                                                    |
| --------------- | ----------------------------------------------------------------------------------------- |
| User directly   | "process for X", "workflow for X", ".processflow.xml", "DECISION flow", "wizard for X"    |
| Workflow skills | `add-detail-screen` (creates the backing process), `add-list-screen`, `add-calendar-view` |
| create-ui-page  | When a UI needs a process to drive it                                                     |

NOT for:

-   Writing `.bl.js` business logic — use `create-business-logic`
-   Writing `.userinterface.xml` screen layouts — use `create-ui-page`
-   DataSource query design — use `create-datasource`
-   Build errors in an existing process — use `build-and-simulate`

---

## Prerequisites

1. **Confirm all BOs/LOs/LUs referenced in `<Declarations>` exist.** If any are missing, invoke
   `create-business-object`, `create-list-object`, or `create-lookup-object` first and return here
   after they are created.

2. **Confirm any companion UI exists (or will be created).** If the process uses a VIEW action,
   the UI must exist in the same `PR/<FlowName>/` folder. Create the UI with `create-ui-page`
   before or after writing the process — whichever order avoids circular dependency.

3. **Identify all ProcessContext variables.** Every `ProcessContext::X` reference in actions,
   DECISION parameters, and UI bindings must be declared in the `<Declarations>` block. Missing
   declarations cause runtime failures with no build error.

---

## Mandatory Checklist

-   [ ] `<Process name>` follows `<Module>::<FlowName>Process` with `::` scoping (not `_` or `/`)
-   [ ] File lives in `src/<Module>/PR/<FlowName>/<FlowName>Process.processflow.xml`
-   [ ] `schemaVersion="0.0.0.5"` on the root `<Process>` element
-   [ ] `<Entry>` block contains `<ProcessContext>` followed by `<EntryActions>` as a **sibling**
        (not a child of `<ProcessContext>`). `<EntryActions>` is **mandatory** even when the
        process has no entry actions — use the self-closing form `<EntryActions/>`. Omitting it
        fails the build with `Element 'Entry': Missing child element(s). Expected is ( EntryActions )`.
-   [ ] Every `<TransitionTo action="X">`, `<Case action="X">`, and `<Event action="X">` points
        to an `<Action name="X">` that exists in `<Body><Actions>`
-   [ ] `defaultAction="X"` on `<Process>` matches an existing Body action name
-   [ ] Every flow path terminates at an `<Action actionType="END">` action
-   [ ] If paired with a UI, the sibling `.userinterface.xml` exists (create via `create-ui-page`)

---

## Failure Modes

### Failure mode 0: Build fails with "Missing child element(s). Expected is ( EntryActions )"

**Symptom:** `sf mdl build` fails on the new process file with validator code `00000001`:
`Element 'Entry': Missing child element(s). Expected is ( EntryActions )`.
**Diagnosis:** The `<Entry>` block contains `<ProcessContext>` but no `<EntryActions>`. The
schema requires `<EntryActions>` as a **sibling of `<ProcessContext>` inside `<Entry>`**, even
when the process has no entry actions.
**Fix:** Add a self-closing `<EntryActions/>` immediately after `</ProcessContext>`:

```xml
<!-- WRONG — build error 00000001 -->
<Entry>
  <ProcessContext>
    <Declarations/>
  </ProcessContext>
</Entry>

<!-- CORRECT -->
<Entry>
  <ProcessContext>
    <Declarations/>
  </ProcessContext>
  <EntryActions/>
</Entry>
```

Verify with a quick grep before building: every `.processflow.xml` in the workspace must
contain `<EntryActions`. Rule of thumb: if a process has zero entry actions (common for pure
VIEW-then-route chooser/menu processes), use `<EntryActions/>`; otherwise list the actions
inside `<EntryActions>...</EntryActions>`.

---

### Failure mode 1: Flow hangs after the first action

**Symptom:** The process starts, the first action fires, then nothing happens. No error in console.
**Diagnosis:** A `<TransitionTo action="X">` target does not exist — either the action name is
misspelled or it was renamed without updating all references.
**Fix:** Grep for the missing action name across the file. Every `action="X"` attribute in any
`<TransitionTo>`, `<Case>`, or `<Event>` must have a matching `<Action name="X">` in `<Body>`.

```xml
<!-- WRONG: no action named "PersistRecord" exists -->
<TransitionTo action="PersistRecord" />

<!-- CORRECT: action "SaveRecord" exists in Body -->
<TransitionTo action="SaveRecord" />
```

---

### Failure mode 2: "Variable undefined" or null crash at runtime

**Symptom:** Simulator console shows `Cannot read properties of null` or `undefined` immediately
after the process starts or after a UI field is populated.
**Diagnosis:** A ProcessContext variable is referenced before it has been populated. Common causes:

-   Declaration exists but no LOAD/CREATE/LOGIC action writes to it before it is read.
-   UI binds to a variable populated after the VIEW action (too late).
    **Fix:** Move all LOAD/CREATE actions for UI-bound variables into `<EntryActions>`. Ensure every
    variable appears in `<Declarations>` and is written before any action that reads it.

---

### Failure mode 3: DECISION always falls through to CaseElse

**Symptom:** A DECISION that should branch on a known value always takes the `CaseElse` path.
**Diagnosis:** The `parameter` value at runtime does not match any `<Case value="X">` string.
Common causes: (a) the value is not yet populated (still `undefined`), (b) the string differs
by case (`"completed"` vs `"Completed"`), (c) a boolean is `true` not `"1"`.
**Fix:** Log `ProcessContext::<VarName>` before the DECISION to see its runtime value. Add or
correct `<Case>` elements. Add `<CaseEmpty>` to handle the uninitialized case separately.

---

### Failure mode 4: Sub-process call fails with "parameter not found"

**Symptom:** A PROCESS action triggers a child process, which crashes because a required Input
parameter is missing.
**Diagnosis:** The `<Input name="X">` in the parent's PROCESS action does not match the child
process's `<Input name="X">` in its `<Parameters>` block. Names must match exactly.
**Fix:** Open both process files. Align `<Input name="...">` in the parent's PROCESS action with
the child's `<Parameters><Input name="...">` declarations. Case-sensitive match required.

---

### Failure mode 5: UI shows blank fields after VIEW action fires

**Symptom:** The dialog or detail screen opens but all fields are empty, even though LOAD ran.
**Diagnosis:** The UI binding path `ProcessContext::<VarName>.<prop>` refers to a variable
populated by a Body action that runs AFTER the VIEW, or the variable was loaded into a different
name than what the UI references.
**Fix:** Check that every variable the UI binds to is populated in `<EntryActions>` (before the
Body's `defaultAction`). If a Body action populates a variable, ensure it runs before the VIEW
action that references it via an explicit `<TransitionTo>` chain.

---

## Minimal Template (inline)

Based on `src/Visit/PR/Visit_Reschedule/Visit_RescheduleProcess.processflow.xml`:

```xml
<Process name="Visit::RescheduleProcess" defaultAction="ShowDialog" schemaVersion="0.0.0.5">
  <Entry>
    <ProcessContext>
      <Declarations>
        <Declaration name="VisitBo"          type="BoVisit" />
        <Declaration name="RescheduleVisitBo" type="BoWizardRescheduleVisit" />
      </Declarations>
      <Parameters>
        <Input name="VisitPKey" type="DomPKey" />
      </Parameters>
    </ProcessContext>
    <EntryActions>
      <Action name="LoadVisit" actionType="LOAD" type="BoVisit">
        <Parameters>
          <Input name="pKey" value="ProcessContext::VisitPKey" />
        </Parameters>
        <Return name="ProcessContext::VisitBo" />
      </Action>
    </EntryActions>
  </Entry>
  <Body>
    <Actions>
      <Action name="ShowDialog" actionType="VIEW">
        <UIDescription>Visit::RescheduleUI</UIDescription>
        <Events>
          <Event name="rescheduleVisit" action="ValidateAndSave" />
        </Events>
      </Action>
      <Action name="ValidateAndSave" actionType="LOGIC"
              call="ProcessContext::VisitBo.reschedule">
        <TransitionTo action="End" />
      </Action>
      <Action name="End" actionType="END">
        <ReturnValues>
          <Return name="refreshRequired" type="Literal" value="1" />
        </ReturnValues>
      </Action>
    </Actions>
  </Body>
</Process>
```

Full templates in `templates/`.

---

## Common Variants

### Variant 1 — Simple dialog (collect input, validate, save)

Use when: a single modal form collects structured input, validates it, calls a BL method to
persist, and returns a refresh signal to the caller.

Template: `templates/simple-dialog.processflow.xml.template`

Flow: LOAD main BO → CREATE wizard BO (EntryActions) → VIEW dialog → VALIDATION → DECISION
→ LOGIC (save method) → END.

Real file: `src/Visit/PR/Visit_Reschedule/Visit_RescheduleProcess.processflow.xml`

Key notes:

-   The wizard BO aggregates only the editable fields; the main BO is the persistence target.
-   The VALIDATION action writes to `ProcessContext::validationResult` automatically — the
    downstream DECISION branches on `"validateOk"` vs `"validateDiscard"`.
-   The UI's `<ButtonPressedEvent event="X">` must match the VIEW action's `<Event name="X">`.

---

### Variant 2 — Decision branch (status change / approval)

Use when: the caller passes a target status or action flag; the process loads a BO, runs a
precondition check, confirms with the user, and invokes a BL method.

Template: `templates/decision-branch.processflow.xml.template`

Flow: LOAD BO → DECISION on input param → optional LOGIC (precondition) → CONFIRM (YesNo) →
LOGIC (action method) → END.

Real file: `src/Visit/PR/Visit_ChangeStatusWizard/Visit_ChangeStatusWizardProcess.processflow.xml`

Key notes:

-   No VIEW action — the flow is entirely driven by DECISION and CONFIRM.
-   Every DECISION must have both `<CaseElse>` and `<CaseEmpty>`.
-   `<Message messageId="...">` — no `messageDefault` attribute (build error if present).

---

### Variant 3 — Multi-step wizard

Use when: a guided flow requires two or more sequential form steps with Back navigation.

Template: `templates/wizard.processflow.xml.template`

Flow: LOAD + CREATE (EntryActions) → VIEW Step1 → VIEW Step2 (with Back event) → VALIDATION
→ LOGIC (save) → END.

Key notes:

-   Each step uses its own companion UI file (`Step1UI`, `Step2UI`) in the same folder.
-   The DECISION on `ProcessContext::validationResult` must handle the `"validateDiscard"` case —
    either cancel silently or ask via CONFIRM before discarding.
-   The `<Return>` on the LOGIC save action captures the new record PKey for the END `<ReturnValues>`.

---

### Variant 4 — Load and forward (no UI)

Use when: the process simply loads a BO and calls a child process or navigates to a cockpit.

Real file: `src/Visit/PR/Visit_LoadVisit/Visit_LoadVisitProcess.processflow.xml`

Pattern: LOAD BO (EntryAction) → PROCESS (sub-process invocation, no TransitionTo needed).

```xml
<Process name="Visit::LoadVisitProcess" defaultAction="StartCockpit" schemaVersion="0.0.0.5">
  <Entry>
    <ProcessContext>
      <Declarations>
        <Declaration name="VisitBO" type="BoVisit" />
      </Declarations>
      <Parameters>
        <Input name="VisitPKey" type="String" />
      </Parameters>
    </ProcessContext>
    <EntryActions>
      <Action name="LoadVisitBO" actionType="LOAD" type="BoVisit">
        <Parameters>
          <Input name="pKey" value="ProcessContext::VisitPKey" />
        </Parameters>
        <Return name="ProcessContext::VisitBO" />
      </Action>
    </EntryActions>
  </Entry>
  <Body>
    <Actions>
      <Action name="StartCockpit" actionType="PROCESS"
              process="Visit::RetailStoreCockpitProcess">
        <Parameters>
          <Input name="MainBO"  value="ProcessContext::VisitBO" />
          <Input name="StoreId" value="ProcessContext::VisitBO.StoreId" />
        </Parameters>
      </Action>
    </Actions>
  </Body>
</Process>
```

---

## Decision Table

| User wants...                             | Template           | Has UI?     | Key action types                                       |
| ----------------------------------------- | ------------------ | ----------- | ------------------------------------------------------ |
| Open a form, accept input, save           | `simple-dialog`    | Yes         | LOAD, CREATE, VIEW, VALIDATION, DECISION, LOGIC, END   |
| Decide "do X or Y based on current state" | `decision-branch`  | No          | LOAD, DECISION, CONFIRM, LOGIC, END                    |
| Multi-step guided flow                    | `wizard`           | Yes (2 UIs) | LOAD, CREATE, VIEW×2, VALIDATION, DECISION, LOGIC, END |
| Load BO and hand off to sub-process       | inline (Variant 4) | No          | LOAD, PROCESS                                          |

---

## File and Folder Layout

```
src/<Module>/
└── PR/
    └── <FlowName>/
        ├── <FlowName>Process.processflow.xml   ← this file
        └── <FlowName>UI.userinterface.xml       ← optional companion UI
```

The process and its optional UI always share the same `PR/<FlowName>/` folder. The naming
convention is `<FlowName>Process.processflow.xml`. See `_shared/naming.md`.

The `name` attribute on `<Process>` uses the module-qualified form: `<Module>::<FlowName>Process`.

---

## Real File Reference

**Simple dialog with DECISION + VALIDATION:**

```
src/Visit/PR/Visit_Reschedule/Visit_RescheduleProcess.processflow.xml
```

Structure: 5 Declarations, 7 Input params, 3 EntryActions, ~18 Body actions including
DECISION → LOAD → LOGIC → VALIDATION → DECISION chain.

**Pure logic decision branch:**

```
src/Visit/PR/Visit_ChangeStatusWizard/Visit_ChangeStatusWizardProcess.processflow.xml
```

Structure: 2 Declarations, 3 Input params, empty EntryActions, LOAD → DECISION → CONFIRM chain.
No UI file.

**Load-and-forward (sub-process handoff):**

```
src/Visit/PR/Visit_LoadVisit/Visit_LoadVisitProcess.processflow.xml
```

Structure: 1 Declaration, 1 Input param, 1 EntryAction (LOAD), 1 Body action (PROCESS).
No UI file.

---

## Escape Hatch

When the above isn't enough, consult in order:

1. `references/action-types.md` — every actionType with XML shape, purpose, and real-file examples
2. `references/process-context.md` — Declarations, Parameters, `ProcessContext::` paths, Event.\*,
   sub-process parameter passing, initialization patterns
3. `references/ui-binding.md` — folder layout, VIEW action wiring, ButtonPressedEvent matching,
   event payload params, when NOT to pair a UI
4. `ai-wiki/wiki/processes.md` — full ~461-line wiki covering CONFIRM syntax rules, context menu patterns,
   PRINTV2/NAVIGATION action types, validation rules, and build-critical gotchas

---

## Verify

After writing the process file, run a build:

```bash
# cd to your workspace root
sf mdl build 2>&1 | tail -20
```

Then trigger the flow from a menu item, cockpit card, or parent process in the simulator:

```bash
sf mdl simulate
# Navigate to the trigger point (menu item, card, or parent process)
# Check: flow reaches the first expected screen or CONFIRM dialog
# Check: DECISION branches route correctly (try each path)
# Check: END actions return refreshRequired=1 when a save occurred
# Open devtools Console: look for "undefined", "null reference", or "action not found" errors
```

A clean build and a fully exercised flow (all branches reaching END) confirms the process is
correctly structured and wired.
