@salesforce/afv-skills 1.49.0 → 1.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/field-service-data-capture-form-deployer-configure/SKILL.md +180 -0
- package/skills/field-service-data-capture-form-deployer-configure/examples/inventory-transfer-spec.json +135 -0
- package/skills/field-service-data-capture-form-deployer-configure/examples/sample-spec.json +140 -0
- package/skills/field-service-data-capture-form-deployer-configure/examples/sectioned-spec.json +64 -0
- package/skills/field-service-data-capture-form-deployer-configure/references/field-types.md +297 -0
- package/skills/field-service-data-capture-form-deployer-configure/references/flow-metadata-json.md +243 -0
- package/skills/field-service-data-capture-form-deployer-configure/references/post-screen-automation.md +127 -0
- package/skills/field-service-data-capture-form-designer-configure/SKILL.md +110 -0
- package/skills/field-service-data-capture-form-designer-configure/references/extraction-from-image.md +244 -0
- package/skills/field-service-data-capture-form-designer-configure/references/extraction-from-prompt.md +222 -0
- package/skills/field-service-data-capture-form-editor-configure/SKILL.md +134 -0
- package/skills/field-service-data-capture-reference-configure/SKILL.md +762 -0
- package/skills/field-service-data-capture-reference-configure/examples/DataCapture_Showcase.flow-meta.xml +2022 -0
- package/skills/field-service-data-capture-reference-configure/examples/Data_Capture_All_Components.flow-meta.xml +2170 -0
- package/skills/field-service-data-capture-reference-configure/examples/Repeater_with_prepopulation.flow-meta.xml +231 -0
- package/skills/field-service-foundation-setup-designer-get/SKILL.md +135 -0
- package/skills/field-service-mobile-branding-configure/SKILL.md +133 -0
- package/skills/field-service-mobile-branding-configure/examples/dark-blue-scheme.json +16 -0
- package/skills/field-service-mobile-branding-configure/examples/salesforce-default-scheme.json +16 -0
- package/skills/field-service-mobile-branding-configure/references/color-fields.md +66 -0
- package/skills/field-service-mobile-branding-configure/references/contrast-validation.md +55 -0
- package/skills/field-service-mobile-branding-configure/references/derivation-methodology.md +83 -0
- package/skills/field-service-objective-designer-configure/SKILL.md +342 -0
- package/skills/field-service-prework-brief-deployer-configure/SKILL.md +83 -0
- package/skills/field-service-scheduling-policy-designer-query/SKILL.md +121 -0
- package/skills/field-service-setup-orchestrator-get/SKILL.md +48 -0
- package/skills/field-service-sobject-create-configure/SKILL.md +56 -0
- package/skills/field-service-voice-to-form-configure/SKILL.md +650 -0
- package/skills/field-service-work-rule-designer-configure/SKILL.md +303 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: field-service-data-capture-form-designer-configure
|
|
3
|
+
description: "Design a Field Service Mobile Data Capture Flow from either a natural-language description OR a PDF/image of an existing paper form. Extracts field labels, types, required-state, and section structure into an intermediate JSON spec, confirms the plan with the user, then hands off to fs-data-capture-form-deployer for compile + deploy. Handles both input modes in one skill — prose ('build a Field Service form for asset inspection', 'make a DataCaptureFlow that asks the technician to…', 'create an inventory transfer form') and visual sources ('convert this PDF to a Data Capture Flow', 'make a Field Service form from this image', 'turn this paper form into a DataCaptureFlow'). Detects the input mode automatically from a .pdf/.png/.jpg/.jpeg path, else extracts from the prose. Do NOT use this skill to patch an already-deployed flow — that's fs-data-capture-form-editor."
|
|
4
|
+
user-invocable: false
|
|
5
|
+
metadata:
|
|
6
|
+
version: "1.0"
|
|
7
|
+
domains: ["Field Service"]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Design a Data Capture Form (from prose or from an image / PDF)
|
|
11
|
+
|
|
12
|
+
This skill produces an intermediate JSON spec from the user's input — a
|
|
13
|
+
natural-language description **or** a PDF/image of an existing form — gets the
|
|
14
|
+
user's approval on the plan, and then invokes `fs-data-capture-form-deployer` to
|
|
15
|
+
compile and deploy.
|
|
16
|
+
|
|
17
|
+
## When this skill fires
|
|
18
|
+
|
|
19
|
+
The user asks for a Data Capture Flow / Field Service Mobile form. The input
|
|
20
|
+
arrives in one of two modes:
|
|
21
|
+
|
|
22
|
+
- **Prose mode** — the user describes the form in plain text with no attached file. Examples:
|
|
23
|
+
- "Create a data capture form for asset inspection that asks for asset id, condition rating, photos, and remarks."
|
|
24
|
+
- "Build a Field Service form for inventory transfer with parts repeater, source location, and destination dropdown."
|
|
25
|
+
- "Generate a DataCaptureFlow that captures three things: site name, contact info, and a notes field."
|
|
26
|
+
- **Image / PDF mode** — the user supplies a path to a `.pdf`, `.png`, `.jpg`, or `.jpeg` file. Examples:
|
|
27
|
+
- "Convert /tmp/inspection.pdf to a Data Capture Flow"
|
|
28
|
+
- "Build a Field Service form from this image: ~/Downloads/site-visit.png"
|
|
29
|
+
- "Turn this paper form into a DataCaptureFlow" (with attached image)
|
|
30
|
+
|
|
31
|
+
Detect the mode from the input: **if the user supplied a `.pdf` / `.png` / `.jpg` / `.jpeg` path, use image/PDF mode; otherwise use prose mode.** Everything after extraction (steps 2-6) is identical for both.
|
|
32
|
+
|
|
33
|
+
## Workflow
|
|
34
|
+
|
|
35
|
+
### 1. Read the source (mode-dependent)
|
|
36
|
+
|
|
37
|
+
**Prose mode — read the description carefully; don't fabricate fields.**
|
|
38
|
+
Extract only the fields the user actually mentioned. Don't invent extra fields based on what "usually goes on" an inspection form. If the user says "asks for asset id, condition rating, photos, and remarks", emit four fields, not eight.
|
|
39
|
+
|
|
40
|
+
If the user's description is too vague to produce a usable form ("build a form that captures stuff about a service appointment"), ask one or two targeted questions before extracting — what fields they want, whether there's a parent record, what should happen on submit. Don't guess.
|
|
41
|
+
|
|
42
|
+
Then apply the prose-evidence rules in [reference/extraction-from-prompt.md](reference/extraction-from-prompt.md).
|
|
43
|
+
|
|
44
|
+
**Image / PDF mode — read the file.**
|
|
45
|
+
Use the `Read` tool on the path the user gave you. PDFs and images are natively supported. If the PDF is more than 10 pages, ask the user which pages contain the form (the `Read` tool requires a `pages` parameter for large PDFs).
|
|
46
|
+
|
|
47
|
+
Then apply the control-evidence rules in [reference/extraction-from-image.md](reference/extraction-from-image.md).
|
|
48
|
+
|
|
49
|
+
### 2. Extract the intermediate JSON
|
|
50
|
+
|
|
51
|
+
Apply every rule in the mode-appropriate extraction reference (from step 1). The output schema is defined by the **input contract of the build skill**:
|
|
52
|
+
- [field-types.md](../fs-data-capture-form-deployer/reference/field-types.md) — field type → component mapping, required Flow boilerplate, choice/repeater shapes, visibility rules.
|
|
53
|
+
- [post-screen-automation.md](../fs-data-capture-form-deployer/reference/post-screen-automation.md) — schema for the optional `postScreen` block.
|
|
54
|
+
|
|
55
|
+
Write the JSON to `/tmp/data-capture-spec.json`.
|
|
56
|
+
|
|
57
|
+
### 3. Determine the desired outcome
|
|
58
|
+
|
|
59
|
+
A data capture form is a means, not an end. Before asking for approval, decide what should happen in Salesforce when the user submits the form:
|
|
60
|
+
|
|
61
|
+
- If the user explicitly says what to create/update ("create a ProductTransfer for each part"), OR the source/filename strongly implies an outcome (Inventory Transfer → ProductTransfer; Asset Inspection → WorkOrderLineItem) — emit a `postScreen` block with the named (or best-guess) object and field API names. When it's a best guess, list every `valueRef` / `field` in the confirmation step so the user can correct names.
|
|
62
|
+
- If the outcome is ambiguous AND the user gave no hint — surface the question in the confirmation step ("What should happen when this form is submitted?") with concrete options drawn from the form's domain.
|
|
63
|
+
- A screens-only flow with no `postScreen` is valid, but you must say so explicitly in the confirmation step.
|
|
64
|
+
|
|
65
|
+
See the mode-appropriate extraction reference for the full outcome-elicitation rules.
|
|
66
|
+
|
|
67
|
+
### 4. Confirm with the user (mandatory gate)
|
|
68
|
+
|
|
69
|
+
Show the user what you plan to build before deploying. Use `AskUserQuestion` to gate the handoff to Build.
|
|
70
|
+
|
|
71
|
+
In the question body or surrounding text, plainly state:
|
|
72
|
+
|
|
73
|
+
1. **The desired outcome.** What the flow does after the last screen — e.g. "Submitting the form will create a ProductTransfer per row in the Parts repeater" or "This flow only captures data — admin will wire up automation in Flow Builder." If a `postScreen` block was generated, list every Salesforce object name and every `field` API name it references. Object/field API names are the most common source of post-deploy errors.
|
|
74
|
+
2. The `formTitle` and the proposed `<FlowApiName>` (PascalCase, no spaces).
|
|
75
|
+
3. The number of screens and total fields (count repeater children too).
|
|
76
|
+
4. Any visibility rules generated and the choice values they key off of.
|
|
77
|
+
5. **Every field type, especially specialized ones, and the evidence it's based on.** For each `Signature`, `UploadFile`, `UploadImage`, `Images`, `Matrix`, `Address`, `Lookup`, `FileView`, or `Repeater` in the spec, name the field and the evidence — in prose mode the prose evidence ("user said 'parts repeater'", "user described a sign-here pad"); in image mode the visual evidence ("`damagePhoto` → UploadImage because the source has a camera-icon button"). These deploy as **real functional components** (`dcSignature`, `dcUpImage`, etc.) — so emitting them when the user only meant a text field (prose) or when you can only point to the field's *label* (image) is the most common extraction bug. If the matching control vocabulary / visual control isn't present, downgrade to `ShortText`/`LongText`/`Numeric` and call it out.
|
|
78
|
+
6. **Lookup objects and FileView filenames.** For every `Lookup`, list the `lookupObject` (Salesforce object API name) and `lookupSearchFields` you chose. For every `FileView`, list the `fileName`. These names are common sources of post-deploy errors — surface them so the user can correct.
|
|
79
|
+
7. Any fields that fell back to a labeled `dcTextInput` placeholder (only happens for `Lookup` with no `lookupObject` and `FileView` with no `fileName`).
|
|
80
|
+
|
|
81
|
+
Offer the user clear options:
|
|
82
|
+
- **Approve and deploy** — proceed to step 5.
|
|
83
|
+
- **Edit the spec first** — let them edit `/tmp/data-capture-spec.json` directly, then re-run from step 4.
|
|
84
|
+
- **Cancel** — stop without deploying.
|
|
85
|
+
|
|
86
|
+
Do not proceed to step 5 without explicit approval.
|
|
87
|
+
|
|
88
|
+
### 5. Hand off to Build
|
|
89
|
+
|
|
90
|
+
Once approved, hand the approved spec to `fs-data-capture-form-deployer`. Pick a `<FlowApiName>` matching `^[A-Z][A-Za-z0-9_]*$` (default: PascalCase of `formTitle`), then follow that skill's workflow — it runs entirely over REST through the Codey runtime, with **no `sf` CLI, no scripts, and no `.flow-meta.xml`**:
|
|
91
|
+
|
|
92
|
+
1. **Verify org auth** — [fs-data-capture-form-deployer/SKILL.md](../fs-data-capture-form-deployer/SKILL.md) §1 (a cheap `SELECT Id FROM Organization LIMIT 1` REST probe; the runtime resolves the connected org — this family does not manage aliases).
|
|
93
|
+
2. **Build the Flow Metadata JSON inline** from the approved spec — deployer §3 + [reference/flow-metadata-json.md](../fs-data-capture-form-deployer/reference/flow-metadata-json.md). The agent assembles the `Metadata` object directly; there is no XML compile step.
|
|
94
|
+
3. **Deploy** with a single `POST /services/data/vXX.0/tooling/sobjects/Flow` carrying `{ "FullName": "<FlowApiName>", "Metadata": { ... } }` — deployer §4.
|
|
95
|
+
|
|
96
|
+
After deploy, follow the reporting + error-handling steps in [fs-data-capture-form-deployer/SKILL.md](../fs-data-capture-form-deployer/SKILL.md) §5.
|
|
97
|
+
|
|
98
|
+
### 6. Offer to attach the form to a parent record
|
|
99
|
+
|
|
100
|
+
After a successful deploy, the flow exists but is invisible from the Forms tab on any Service Appointment / Work Order. Ask the user whether they want it attached to a specific parent (the canonical "pending form" pattern). If yes, follow the attach steps in [fs-data-capture-form-deployer/SKILL.md](../fs-data-capture-form-deployer/SKILL.md) §6 — a single `POST /services/data/vXX.0/sobjects/DynamicDataCapture` (no scripts). For SA-context testing, attach to the SA's parent Work Order, not the SA itself — FSL Mobile reads Forms from the parent Work Order.
|
|
101
|
+
|
|
102
|
+
## Out of scope
|
|
103
|
+
|
|
104
|
+
- Patching an already-deployed flow → `fs-data-capture-form-editor`.
|
|
105
|
+
- Hand-authoring patterns the converter doesn't generate (visual polish HTML, real `dcSignature`/`dcUpImage`, master-detail child records, supporting CustomObjects) → `fs-data-capture-reference` library skill.
|
|
106
|
+
|
|
107
|
+
## Files in this skill
|
|
108
|
+
|
|
109
|
+
- `reference/extraction-from-prompt.md` — prose-evidence rules for picking field types from user descriptions, screen grouping, visibility rules, outcome-elicitation, validation checklist. Used in **prose mode**.
|
|
110
|
+
- `reference/extraction-from-image.md` — control-evidence rules for picking field types from rendered widgets, repeater extraction rules, screen grouping, visibility rules, outcome-elicitation, validation checklist. Used in **image / PDF mode**.
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# Extraction rules — visual sources (PDF / image)
|
|
2
|
+
|
|
3
|
+
These are the rules to follow when given a `.pdf`, `.png`, `.jpg`, or `.jpeg` and asked to produce the intermediate JSON spec for a Data Capture Flow.
|
|
4
|
+
|
|
5
|
+
The spec schema is the input contract of the build skill — see [field-types.md](../../fs-data-capture-form-deployer/reference/field-types.md) and [post-screen-automation.md](../../fs-data-capture-form-deployer/reference/post-screen-automation.md). This file covers extraction *behavior*; that file covers what the converter accepts.
|
|
6
|
+
|
|
7
|
+
## Output schema
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"formTitle": "string",
|
|
12
|
+
"formType": "string",
|
|
13
|
+
"screens": {
|
|
14
|
+
"PascalCaseScreenName1": [ /* fields */ ],
|
|
15
|
+
"PascalCaseScreenName2": [ /* fields */ ]
|
|
16
|
+
},
|
|
17
|
+
"postScreen": { /* optional — see post-screen-automation.md */ }
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Each field has these properties (only `fieldName`, `fieldLabel`, and `fieldType` are required):
|
|
22
|
+
|
|
23
|
+
| Property | Type | Notes |
|
|
24
|
+
|----------|------|-------|
|
|
25
|
+
| `fieldName` | string | camelCase or PascalCase, English, unique across the form, valid Salesforce API name. |
|
|
26
|
+
| `fieldLabel` | string | Exact label from the source. Preserve original language, units, special characters. Strip required indicators (`*`, `(required)`). |
|
|
27
|
+
| `fieldType` | string | One of the supported types in `field-types.md`. Case-sensitive. |
|
|
28
|
+
| `isRequired` | boolean | true if the source had `*`, "required", "mandatory", "Pflichtfeld", "obligatoire", etc. |
|
|
29
|
+
| `defaultValue` | string \| null | null for input fields; for `DisplayText`, the static body text. |
|
|
30
|
+
| `options` | array \| null | Required for `Radio`, `Picklist`, `CheckboxGroup`, `Matrix` (column choices). null otherwise. |
|
|
31
|
+
| `repeaterFields` | array | Required for `Repeater`. List of nested field objects with the same shape. |
|
|
32
|
+
| `matrixRows` | array | Required for `Matrix`. List of row labels. |
|
|
33
|
+
| `min` / `max` / `value` | number | Optional for `Counter` — initial/min/max for the +/- counter. |
|
|
34
|
+
| `visibility` | object | Optional. `{ "field": "<fieldName>", "operator": "EqualTo", "value": "<choice display>" }` — show this field only when the referenced choice is selected. |
|
|
35
|
+
| `lookupObject` | string | Required for `Lookup`. Salesforce object API name (e.g. `"Asset"`, `"WorkOrder"`). |
|
|
36
|
+
| `lookupSearchFields` | string | Optional for `Lookup`. Comma-separated field API names searched by typeahead (e.g. `"Name, SerialNumber"`). |
|
|
37
|
+
| `lookupMulti` | boolean | Optional for `Lookup`. true to allow selecting multiple records. |
|
|
38
|
+
| `fileName` | string | Required for `FileView`. Static-asset filename without extension. |
|
|
39
|
+
|
|
40
|
+
## Output requirements
|
|
41
|
+
|
|
42
|
+
1. Output **only** the JSON object.
|
|
43
|
+
2. No markdown, no code fences, no explanation before or after.
|
|
44
|
+
3. Use `null` for null, `true`/`false` for booleans, double-quoted strings.
|
|
45
|
+
4. Stop immediately after the closing `}`.
|
|
46
|
+
|
|
47
|
+
## Field-type classification — control evidence over labels
|
|
48
|
+
|
|
49
|
+
Pick a field type from what the *control* does, not from what the *label* says. A field labeled "Signature" that's just a text line is `ShortText`, not `Signature`. A field labeled "Photo of damage" that's a description box is `LongText`, not `UploadImage`. The label is a hint; the rendered UI control is the answer.
|
|
50
|
+
|
|
51
|
+
Use the **most specific** type the visual evidence supports. Default to `ShortText` when in doubt.
|
|
52
|
+
|
|
53
|
+
| Type | Control evidence required (PDF/image) |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `Name` | A text input whose label is an unambiguous person role: Inspector, Operator, Technician, Employee, Customer Name, Reported By. Plain "Name" alone is fine. **A dropdown control with a person-role label (e.g. "--Select Inspector--", "Choose Operator ▼") is still `Name`, not `Picklist`** — the data captured is a person, and the runtime treatment of person fields is what matters. |
|
|
56
|
+
| `Email` | Text input with `@` placeholder, label "Email", or input attribute hints. |
|
|
57
|
+
| `Phone` | Text input with phone formatting, label "Phone", "Tel", "Mobile". |
|
|
58
|
+
| `Numeric` | Numeric input, often with units (°C, mm, kg, bar, %). |
|
|
59
|
+
| `Counter` | A `+` / `-` stepper widget *or* explicit "Quantity" with stepper UI. Default `min: 1, value: 1`. |
|
|
60
|
+
| `Date` | A date picker (calendar icon, `MM/DD/YYYY` placeholder). |
|
|
61
|
+
| `DateTime` | A date+time picker. |
|
|
62
|
+
| `Checkbox` | A single standalone checkbox with one label. |
|
|
63
|
+
| `CheckboxGroup` | Multiple checkboxes under one heading or "select all that apply". |
|
|
64
|
+
| `Radio` | Radio buttons / "(circle one)" / mutually exclusive options visible on the form. |
|
|
65
|
+
| `Picklist` | A combo box / dropdown indicator (▼ ▾ ⌄, "Select…"). For person-name dropdowns, prefer `Name`. Supply 3–5 sample options. |
|
|
66
|
+
| `Toggle` | An on/off switch UI element (rounded slider). |
|
|
67
|
+
| `UploadFile` | A file-picker control: "Choose file", paperclip icon, drag-drop zone, attachment slot. **Not** a label that mentions a file. |
|
|
68
|
+
| `UploadImage` | An image-upload control: camera icon, "Add photo" button, image drop zone. **Not** a label like "Photo" on a text line. |
|
|
69
|
+
| `FileView` | A read-only image preview / pre-attached image. |
|
|
70
|
+
| `Signature` | A signature pad (a labeled empty box sized for handwriting, with "Sign here" / "Signature" inside the box, often with an X-line). **Not** a one-line text field labeled "Signature". |
|
|
71
|
+
| `Matrix` | A grid where each row asks the same question with shared answer columns (e.g. row=item, columns=OK/NOK/N/A). ONE field with `matrixRows` + `options`. |
|
|
72
|
+
| `Repeater` | A table with input columns where the user adds N rows (e.g. Part Number / Quantity / Description). ONE field with `repeaterFields`. |
|
|
73
|
+
| `Address` | A compound address widget with separate sub-inputs (street + city + state + zip + country). |
|
|
74
|
+
| `LongText` | A multi-line text box (textarea, ≥3 lines tall, "Notes" / "Comments" / "Remarks"). |
|
|
75
|
+
| `ShortText` | A single-line text input. **This is the default** when no other evidence applies. |
|
|
76
|
+
| `DisplayText` | Static instructional text with no input control. Set `defaultValue` to the body. |
|
|
77
|
+
| `Lookup` | A typeahead/record-search input bound to a Salesforce object (search-as-you-type that resolves to a record). Requires `lookupObject` (the Salesforce object API name) supplied via the spec. |
|
|
78
|
+
|
|
79
|
+
**Multi-part fields** (e.g. "D0: ___ Ref.-Dim.: ___") → extract each part as its own field with its own classification.
|
|
80
|
+
|
|
81
|
+
### Repeater extraction rules
|
|
82
|
+
|
|
83
|
+
A `Repeater` is for tables where each row is a **user-added item** with **input columns** (the user types/picks per cell). Distinct from `Matrix`, which is a fixed set of rows that share **selection columns** (OK / NOK / N/A — pick one).
|
|
84
|
+
|
|
85
|
+
| Pattern | Type |
|
|
86
|
+
|---|---|
|
|
87
|
+
| Table: `Parameter \| Old Value \| New Value` (user types in each cell) | `Repeater` |
|
|
88
|
+
| Table: `Component \| OK \| NOK \| N/A \| Repair` (user picks one per row) | `Matrix` |
|
|
89
|
+
|
|
90
|
+
When emitting a `Repeater`, populate `repeaterFields` with one nested field per **input column**, classified using the same evidence rules above. Skip any selection-only "OK/NOK" columns — those mean it's a `Matrix`.
|
|
91
|
+
|
|
92
|
+
**Merge side-by-side / stacked repeaters with the same columns.** If the source visually splits one logical table into two blocks (top half / bottom half, left / right) because of page-space constraints, but both blocks have the same column structure — emit **one** Repeater. Two Repeater fields with identical `repeaterFields` is almost always a mistake.
|
|
93
|
+
|
|
94
|
+
**Dedupe columns with the same label.** If a table has the same column label appearing twice and the data captured is the same kind of thing, include the column **once** in `repeaterFields`.
|
|
95
|
+
|
|
96
|
+
**Skip symbol-only columns.** Single-character or symbol headers (`Δ`, `Σ`, `→`, blank) are typically separators or change indicators, not data inputs.
|
|
97
|
+
|
|
98
|
+
### Anti-patterns (do NOT do these)
|
|
99
|
+
|
|
100
|
+
- ❌ Label contains "signature" → automatically `Signature`. The control might be a single-line text field where the inspector types their name. Only emit `Signature` if you can see a sign-here pad.
|
|
101
|
+
- ❌ Label contains "photo" / "image" / "picture" → automatically `UploadImage`. The control might be a description text box. Only emit `UploadImage` when you see a camera/upload widget.
|
|
102
|
+
- ❌ Label contains "attach" / "file" / "document" → automatically `UploadFile`. Same rule — needs an actual file picker.
|
|
103
|
+
- ❌ Label contains "address" → automatically `Address`. A single text line for address is `ShortText` or `LongText`. Only emit `Address` for a compound widget with separate sub-inputs.
|
|
104
|
+
- ❌ Any table → `Repeater`. A table where each row is a fixed inspection point (with shared OK/NOK columns) is `Matrix`, not `Repeater`.
|
|
105
|
+
- ❌ Any list of options → `Picklist`. If the source explicitly shows radio buttons or "circle one", use `Radio`.
|
|
106
|
+
|
|
107
|
+
When the evidence is ambiguous, **fall back to the simplest type** (`ShortText`, `LongText`, `Numeric`) and call it out in the confirmation step so the user can correct it before deploy.
|
|
108
|
+
|
|
109
|
+
## Conditional fields
|
|
110
|
+
|
|
111
|
+
If a field on the form is preceded by something like "If Work Order, also fill: WO#" or only makes sense given a previous answer, attach a `visibility` block:
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"fieldName": "WorkOrderNumber",
|
|
116
|
+
"fieldLabel": "WO#",
|
|
117
|
+
"fieldType": "ShortText",
|
|
118
|
+
"isRequired": true,
|
|
119
|
+
"visibility": { "field": "To", "operator": "EqualTo", "value": "Work Order" }
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The `value` must match one of the parent field's `options` exactly (display text, not the api-sanitized name).
|
|
124
|
+
|
|
125
|
+
## Naming rules
|
|
126
|
+
|
|
127
|
+
- `fieldName`: camelCase or PascalCase, English even if the label is in another language. No spaces, no special characters (underscore allowed). Unique within the form. ≤ 80 chars.
|
|
128
|
+
- Screen keys: `PascalCase` describing the section (`HeaderInformation`, `OperatingParameters`, `VisualInspection`). Never `Screen1`, `Screen2`.
|
|
129
|
+
- `formTitle`: human-readable, original language allowed. The Flow's API name is derived from this by the deploy step.
|
|
130
|
+
- `formType`: short descriptor (e.g. `Inspection Report`, `Service Log`, `Inventory Transfer`).
|
|
131
|
+
|
|
132
|
+
## Label rules
|
|
133
|
+
|
|
134
|
+
- **Preserve** original language, umlauts/accents, units, bilingual text exactly as shown (`"Kennwort: / Job name:"`).
|
|
135
|
+
- **Strip** leading `*`, `(required)`, `(mandatory)`, `Pflichtfeld` from the label and set `isRequired: true` instead.
|
|
136
|
+
- **Do not** translate or rephrase.
|
|
137
|
+
|
|
138
|
+
## Screen grouping
|
|
139
|
+
|
|
140
|
+
- 8–12 fields per screen, max.
|
|
141
|
+
- A form with a single section and a repeater can be a single screen — don't fabricate sections.
|
|
142
|
+
- Group by logical sections in the source (header info, measurements, inspection, attachments, signatures…).
|
|
143
|
+
- Use the source's section breaks where they exist.
|
|
144
|
+
- Use descriptive PascalCase screen names — never `Screen1`.
|
|
145
|
+
|
|
146
|
+
## Sections within a screen
|
|
147
|
+
|
|
148
|
+
A Section is a *visual grouping inside one screen* — distinct from splitting fields across multiple screens. Emit a section **only when the source visibly shows a labeled group header** (a banner/heading like "Asset Details", "Inspection Notes", a colored separator with a title, or a visibly bordered group).
|
|
149
|
+
|
|
150
|
+
When you emit a section, insert a `{ "section": "Header Label" }` item into the screen's field list before the fields belonging to that group:
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"screens": {
|
|
155
|
+
"AssetInspection": [
|
|
156
|
+
{ "section": "Asset Details" },
|
|
157
|
+
{ "fieldName": "AssetName", "fieldLabel": "Asset Name", "fieldType": "ShortText" },
|
|
158
|
+
{ "fieldName": "Manufacturer", "fieldLabel": "Manufacturer", "fieldType": "Picklist", "options": ["Demag","Konecranes"] },
|
|
159
|
+
|
|
160
|
+
{ "section": "Inspection" },
|
|
161
|
+
{ "fieldName": "Condition", "fieldLabel": "Condition", "fieldType": "Picklist", "options": ["Pass","Fail"] }
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**When NOT to use sections:**
|
|
168
|
+
- The source has no visible group headers — emit a flat field list.
|
|
169
|
+
- The source uses one heading per screen (these are *screen names*, not within-screen sections).
|
|
170
|
+
- You'd be inventing groupings the source doesn't show.
|
|
171
|
+
|
|
172
|
+
**One-section screens are usually wrong.** A single section spanning the whole screen is just a screen with a redundant header bar. Either emit no sections, or emit ≥ 2 sections per screen.
|
|
173
|
+
|
|
174
|
+
## Post-screen automation — determine the desired outcome
|
|
175
|
+
|
|
176
|
+
A data capture form is rarely just a form. The captured data almost always needs to **do** something in Salesforce: create a record, update a record, look something up. That "do something" is the desired outcome.
|
|
177
|
+
|
|
178
|
+
You **must** determine the desired outcome before finalizing the spec. A form that captures perfect data but never writes anything to Salesforce is a broken flow.
|
|
179
|
+
|
|
180
|
+
### Outcome-elicitation rules
|
|
181
|
+
|
|
182
|
+
For every form, ask yourself:
|
|
183
|
+
|
|
184
|
+
1. **What Salesforce object should be created or updated when the user finishes the form?** (e.g. ProductTransfer, WorkOrderLineItem, Case, Asset, ServiceAppointment.)
|
|
185
|
+
2. **Are any rows in a Repeater supposed to become individual records?** If yes, you need a `loop` over `<Repeater>.AddedItems` and a `recordCreate` per iteration.
|
|
186
|
+
3. **Does any captured value need to be resolved to a record Id before writing?** If yes, you need a `recordLookup`.
|
|
187
|
+
4. **Is the user picking a branch that determines which lookup or write to do?** If yes, you need a `decision`.
|
|
188
|
+
5. **Is there a parent record passed in via `parentRecordId` / `parentObjectType` that should be referenced or updated?** This is the standard Field Service entry-point pattern.
|
|
189
|
+
|
|
190
|
+
### How to decide whether to emit `postScreen`
|
|
191
|
+
|
|
192
|
+
| Signal | Action |
|
|
193
|
+
|---|---|
|
|
194
|
+
| The form's name or purpose strongly implies a single object — Inventory Transfer, Work Order Completion, Asset Inspection, Damage Report, Time Entry | **Emit `postScreen`** with your best-guess object/field mapping AND list every `valueRef` / `field` in the confirmation step so the user can correct names. |
|
|
195
|
+
| The form has a Repeater whose rows obviously become rows in Salesforce (parts, line items, time entries, photos with metadata) | **Emit `postScreen`** with a loop + recordCreate. State the assumption explicitly. |
|
|
196
|
+
| You're refining an existing flow the user pointed you at | **Mirror the existing flow's `postScreen`** (same object, same field shape). |
|
|
197
|
+
| You truly cannot infer what the data should do | Surface a question to the user in the confirmation step ("What should happen when this form is submitted?") and emit no `postScreen` until they answer. |
|
|
198
|
+
|
|
199
|
+
### Common outcome patterns
|
|
200
|
+
|
|
201
|
+
- **Inventory Transfer** (form has a parts repeater) → loop over `Part.AddedItems` → create one `ProductTransfer` per row, mapping `Product2Id`, `QuantitySent`, `QuantityReceived`, `DestinationLocationId`.
|
|
202
|
+
- **Inspection / Checklist** → create one `WorkOrderLineItem` or `Asset__History` record summarizing the inspection.
|
|
203
|
+
- **Time Entry** → create a `ResourceAbsence` or custom time-entry record tied to `parentRecordId`.
|
|
204
|
+
- **Damage Report** → update the parent Work Order and/or create child Case records.
|
|
205
|
+
|
|
206
|
+
### Validation for `postScreen`
|
|
207
|
+
|
|
208
|
+
When you emit a `postScreen` block, every reference must point at a real thing:
|
|
209
|
+
|
|
210
|
+
- Every `valueRef` is either: a `<fieldName>.value` from a screen field, a `<RepeaterName>.<ChildName>.value` inside a loop, a non-input variable you declared, or a global like `$User.Id`.
|
|
211
|
+
- Every `field` in `inputAssignments` and `outputAssignments` is the API name of a field on the named `object`. If you don't know the exact API name, use your best guess and list it in the confirmation step.
|
|
212
|
+
- Every `next` connector targets the name of an element you actually defined.
|
|
213
|
+
- The decision's branch `when.field` is a screen field, and `when.value` exactly matches one of that field's `options`.
|
|
214
|
+
|
|
215
|
+
## Validation checklist
|
|
216
|
+
|
|
217
|
+
Before returning, verify:
|
|
218
|
+
|
|
219
|
+
- [ ] Every screen key is PascalCase.
|
|
220
|
+
- [ ] Every `fieldName` is a valid API name, unique across the form (including inside repeaters).
|
|
221
|
+
- [ ] Every `fieldType` is one of the supported types in [field-types.md](../../fs-data-capture-form-deployer/reference/field-types.md) (case-sensitive).
|
|
222
|
+
- [ ] `Radio`, `Picklist`, `CheckboxGroup` have non-empty `options`.
|
|
223
|
+
- [ ] `Matrix` has both `options` (columns) and `matrixRows`.
|
|
224
|
+
- [ ] `Repeater` has `repeaterFields` (each child has its own valid `fieldType`).
|
|
225
|
+
- [ ] Any `visibility.value` exactly matches one of the referenced field's `options`.
|
|
226
|
+
- [ ] No required indicators (`*`, "(required)") left in any label.
|
|
227
|
+
- [ ] No translations of original labels.
|
|
228
|
+
- [ ] No fabricated fields the source doesn't have.
|
|
229
|
+
- [ ] **Outcome is determined.** Either a `postScreen` block is emitted, or the confirmation step will explicitly ask the user what to do with the data.
|
|
230
|
+
- [ ] If `postScreen` is emitted: every `valueRef` resolves, every `field` belongs to the named `object` (or is flagged for user review), every `next` connector targets a defined element, and decision branch `value`s match a parent field's `options`.
|
|
231
|
+
- [ ] **Specialized types are evidence-backed.** For every `Signature`, `UploadFile`, `UploadImage`, `Images`, `FileView`, `Address`, `Matrix`, `Lookup`, and `Repeater` in the output, name the visual evidence (camera-icon button, sign-here pad, +/- stepper, table with row-add button, typeahead picker). If you can only point to the field's *label*, downgrade the type per the table above. (These deploy as **real functional components** — `dcSignature`, `dcUpImage`, `dcMatrix`, etc. — so emitting them when the source only shows a text line is the most common extraction bug.)
|
|
232
|
+
- [ ] **Lookup has `lookupObject`.** Every `Lookup` field has a `lookupObject` (Salesforce object API name). If the source doesn't make it explicit, pick a best-guess and flag it in the confirmation step.
|
|
233
|
+
- [ ] **FileView has `fileName`.** Every `FileView` field has a `fileName` (static asset filename, no extension). If unknown, surface a question.
|
|
234
|
+
- [ ] **Repeaters are not duplicated.** No two `Repeater` fields have identical `repeaterFields` (merge side-by-side or stacked tables that share columns). No `repeaterFields` entries for symbol-only headers (`Δ`, `Σ`).
|
|
235
|
+
- [ ] **Sections only where the source shows them.** Every `{ "section": "..." }` item corresponds to a visible group header in the source. No invented sections, and no screens with exactly one section.
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Source design docs
|
|
240
|
+
|
|
241
|
+
This rule sheet is informed by two upstream design docs. Don't paste the full prompts from those docs into the user-facing flow — they're internal source-of-truth references.
|
|
242
|
+
|
|
243
|
+
- **Form-To-Flow AI HLD** ([doc](https://docs.google.com/document/d/1XlDRQE1gVrux8Iyz5LDupN9xV7i1IKpczLbsvMq5Tc4)) — the Flow Builder team's architecture for PDF-to-DC-Flow generation.
|
|
244
|
+
- **Field Service POC HLD** ([doc](https://docs.google.com/document/d/10TO6CC983AcclXY7Ixp3I3hY5R7TagUMWP9VRqXOFoc)) — Field Service team's Apex+Agentforce POC. Source for the intermediate JSON contract and the extraction prompt rules.
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Extraction rules — natural-language sources
|
|
2
|
+
|
|
3
|
+
These are the rules to follow when given a prose description of a form (no PDF or image) and asked to produce the intermediate JSON spec for a Data Capture Flow.
|
|
4
|
+
|
|
5
|
+
The spec schema is the input contract of the build skill — see [field-types.md](../../fs-data-capture-form-deployer/reference/field-types.md) and [post-screen-automation.md](../../fs-data-capture-form-deployer/reference/post-screen-automation.md). This file covers extraction *behavior*; that file covers what the converter accepts.
|
|
6
|
+
|
|
7
|
+
## Output schema
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"formTitle": "string",
|
|
12
|
+
"formType": "string",
|
|
13
|
+
"screens": {
|
|
14
|
+
"PascalCaseScreenName1": [ /* fields */ ],
|
|
15
|
+
"PascalCaseScreenName2": [ /* fields */ ]
|
|
16
|
+
},
|
|
17
|
+
"postScreen": { /* optional — see post-screen-automation.md */ }
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Each field has these properties (only `fieldName`, `fieldLabel`, and `fieldType` are required):
|
|
22
|
+
|
|
23
|
+
| Property | Type | Notes |
|
|
24
|
+
|----------|------|-------|
|
|
25
|
+
| `fieldName` | string | camelCase or PascalCase, English, unique across the form, valid Salesforce API name. |
|
|
26
|
+
| `fieldLabel` | string | The label the user gave (or a faithful summary if they didn't give an explicit label). Strip required indicators (`*`, `(required)`). |
|
|
27
|
+
| `fieldType` | string | One of the supported types in `field-types.md`. Case-sensitive. |
|
|
28
|
+
| `isRequired` | boolean | true if the user said "required", "mandatory", "must enter", etc. |
|
|
29
|
+
| `defaultValue` | string \| null | null for input fields; for `DisplayText`, the static body text. |
|
|
30
|
+
| `options` | array \| null | Required for `Radio`, `Picklist`, `CheckboxGroup`, `Matrix` (column choices). null otherwise. |
|
|
31
|
+
| `repeaterFields` | array | Required for `Repeater`. List of nested field objects with the same shape. |
|
|
32
|
+
| `matrixRows` | array | Required for `Matrix`. List of row labels. |
|
|
33
|
+
| `min` / `max` / `value` | number | Optional for `Counter` — initial/min/max for the +/- counter. |
|
|
34
|
+
| `visibility` | object | Optional. `{ "field": "<fieldName>", "operator": "EqualTo", "value": "<choice display>" }` — show this field only when the referenced choice is selected. |
|
|
35
|
+
| `lookupObject` | string | Required for `Lookup`. Salesforce object API name (e.g. `"Asset"`, `"WorkOrder"`). |
|
|
36
|
+
| `lookupSearchFields` | string | Optional for `Lookup`. Comma-separated field API names searched by typeahead (e.g. `"Name, SerialNumber"`). |
|
|
37
|
+
| `lookupMulti` | boolean | Optional for `Lookup`. true to allow selecting multiple records. |
|
|
38
|
+
| `fileName` | string | Required for `FileView`. Static-asset filename without extension. |
|
|
39
|
+
|
|
40
|
+
## Output requirements
|
|
41
|
+
|
|
42
|
+
1. Output **only** the JSON object.
|
|
43
|
+
2. No markdown, no code fences, no explanation before or after.
|
|
44
|
+
3. Use `null` for null, `true`/`false` for booleans, double-quoted strings.
|
|
45
|
+
4. Stop immediately after the closing `}`.
|
|
46
|
+
|
|
47
|
+
## Field-type classification — explicit vocabulary required
|
|
48
|
+
|
|
49
|
+
For prose input (no visual reference), only choose specialized types (`Signature`, `UploadFile`, `UploadImage`, `FileView`, `Matrix`, `Address`, `Repeater`) when the user **explicitly** describes that control. The user saying "captures the inspector's signature" with no other context isn't enough — that could be a typed name or a real signature pad. Default to the simpler text/number/date type unless the user uses control vocabulary.
|
|
50
|
+
|
|
51
|
+
Use the **most specific** type the prose evidence supports. Default to `ShortText` when in doubt.
|
|
52
|
+
|
|
53
|
+
| Type | Prose evidence required |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `Name` | User says the field captures a person's name (inspector, operator, technician, customer, employee). |
|
|
56
|
+
| `Email` | User says "email". |
|
|
57
|
+
| `Phone` | User says "phone", "phone number", "mobile", "contact number". |
|
|
58
|
+
| `Numeric` | User says "number", "count", or gives a numeric measurement (pressure, temperature, weight). |
|
|
59
|
+
| `Counter` | User says "counter", "stepper", "+/- quantity", "quantity field". |
|
|
60
|
+
| `Date` | User says "date". |
|
|
61
|
+
| `DateTime` | User says "date and time", "timestamp". |
|
|
62
|
+
| `Checkbox` | User says "checkbox" (singular). |
|
|
63
|
+
| `CheckboxGroup` | User says "select multiple", "all that apply", "checkbox group". |
|
|
64
|
+
| `Radio` | User says "radio", "single choice", "pick one", "select one". |
|
|
65
|
+
| `Picklist` | User says "dropdown", "picklist", "select from a list". For person-name dropdowns, prefer `Name`. |
|
|
66
|
+
| `Toggle` | User says "toggle" or "on/off switch". |
|
|
67
|
+
| `UploadFile` | User says "upload a file" / "attach a document" / explicitly describes a file picker. |
|
|
68
|
+
| `UploadImage` | User says "upload an image" / "add a photo" / "camera capture" / explicitly describes an image picker. |
|
|
69
|
+
| `FileView` | User explicitly asks for a read-only image viewer. |
|
|
70
|
+
| `Signature` | User says "signature pad" / "captures a signature" / explicitly describes a sign-here widget. |
|
|
71
|
+
| `Matrix` | User explicitly describes a same-question-per-row table (rows share OK/NOK columns). |
|
|
72
|
+
| `Repeater` | User says "add multiple rows" / "list of parts" / "repeat for each item" / "repeater". |
|
|
73
|
+
| `Address` | User explicitly says "compound address" or lists street/city/state/zip as a single block. |
|
|
74
|
+
| `LongText` | User says "notes", "comments", "long text", "description", "remarks". |
|
|
75
|
+
| `ShortText` | User just lists a label with no other vocabulary. **This is the default.** |
|
|
76
|
+
| `DisplayText` | User explicitly says "show static text" / "instructions". |
|
|
77
|
+
| `Lookup` | User says "lookup", "select a record", "pick an existing X". Requires `lookupObject` (the Salesforce object API name). |
|
|
78
|
+
|
|
79
|
+
### Anti-patterns (do NOT do these)
|
|
80
|
+
|
|
81
|
+
- ❌ User mentions "signature" → automatically `Signature`. They might mean a typed name. Only emit `Signature` when they say "signature pad", "sign-here widget", or similar control vocabulary.
|
|
82
|
+
- ❌ User mentions "photo" / "image" → automatically `UploadImage`. They might mean a description field. Only emit `UploadImage` when they say "upload an image", "add a photo", "camera capture".
|
|
83
|
+
- ❌ User mentions "address" → automatically `Address`. Single text line is fine for most addresses. Only emit `Address` for an explicit compound widget.
|
|
84
|
+
- ❌ User says "table" → automatically `Repeater` or `Matrix`. Ask for clarification: rows-the-user-adds (Repeater) vs. fixed-rows-with-shared-columns (Matrix).
|
|
85
|
+
- ❌ Inventing fields the user didn't mention. If the user says "asset id, condition rating, photos, and remarks", emit four fields. Don't add an "Inspector" or "Date Inspected" field just because forms usually have those.
|
|
86
|
+
|
|
87
|
+
When the evidence is ambiguous, **fall back to the simplest type** (`ShortText`, `LongText`, `Numeric`) and call it out in the confirmation step so the user can correct it before deploy.
|
|
88
|
+
|
|
89
|
+
## Conditional fields
|
|
90
|
+
|
|
91
|
+
If the user describes a field that depends on a previous answer ("if they pick Work Order, then ask for the WO number"), attach a `visibility` block:
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"fieldName": "WorkOrderNumber",
|
|
96
|
+
"fieldLabel": "WO Number",
|
|
97
|
+
"fieldType": "ShortText",
|
|
98
|
+
"isRequired": true,
|
|
99
|
+
"visibility": { "field": "To", "operator": "EqualTo", "value": "Work Order" }
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The `value` must match one of the parent field's `options` exactly (display text, not the api-sanitized name).
|
|
104
|
+
|
|
105
|
+
## Naming rules
|
|
106
|
+
|
|
107
|
+
- `fieldName`: camelCase or PascalCase, English. No spaces, no special characters (underscore allowed). Unique within the form. ≤ 80 chars.
|
|
108
|
+
- Screen keys: `PascalCase` describing the section (`HeaderInformation`, `OperatingParameters`, `VisualInspection`). Never `Screen1`, `Screen2`.
|
|
109
|
+
- `formTitle`: human-readable. The Flow's API name is derived from this by the deploy step.
|
|
110
|
+
- `formType`: short descriptor (e.g. `Inspection Report`, `Service Log`, `Inventory Transfer`).
|
|
111
|
+
|
|
112
|
+
## Label rules
|
|
113
|
+
|
|
114
|
+
- Use the user's words verbatim where possible. If the user gave a label, keep it. If they only described the field ("the inspector's name"), summarize concisely as the label ("Inspector Name").
|
|
115
|
+
- **Strip** any `*`, `(required)`, `(mandatory)` from the label and set `isRequired: true` instead.
|
|
116
|
+
|
|
117
|
+
## Screen grouping
|
|
118
|
+
|
|
119
|
+
- 8–12 fields per screen, max.
|
|
120
|
+
- A small form (≤ 8 fields) can be a single screen — don't fabricate sections.
|
|
121
|
+
- If the user described multiple sections ("first ask for header info, then measurements, then the parts list"), respect their grouping.
|
|
122
|
+
- If the user just listed fields with no sections, group them into one screen unless there are more than 12 fields. Then split logically.
|
|
123
|
+
- Use descriptive PascalCase screen names — never `Screen1`.
|
|
124
|
+
|
|
125
|
+
## Sections within a screen
|
|
126
|
+
|
|
127
|
+
A Section is a *visual grouping inside one screen* — distinct from splitting fields across multiple screens. **Default to a flat field list.** Emit sections only when the user explicitly describes named sub-groups within a single screen ("on the inspection screen, group fields under 'Asset Details' and 'Inspection Notes'"). Don't infer sections from a list of field topics — a list of fields is just a list of fields.
|
|
128
|
+
|
|
129
|
+
When you emit a section, insert a `{ "section": "Header Label" }` item into the screen's field list before the fields belonging to that group:
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"screens": {
|
|
134
|
+
"AssetInspection": [
|
|
135
|
+
{ "section": "Asset Details" },
|
|
136
|
+
{ "fieldName": "AssetName", "fieldLabel": "Asset Name", "fieldType": "ShortText" },
|
|
137
|
+
{ "fieldName": "Manufacturer", "fieldLabel": "Manufacturer", "fieldType": "Picklist", "options": ["Demag","Konecranes"] },
|
|
138
|
+
|
|
139
|
+
{ "section": "Inspection" },
|
|
140
|
+
{ "fieldName": "Condition", "fieldLabel": "Condition", "fieldType": "Picklist", "options": ["Pass","Fail"] }
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**When NOT to use sections:**
|
|
147
|
+
- The user didn't explicitly name within-screen sub-groups.
|
|
148
|
+
- The user described separate steps (those become separate *screens*, not sections).
|
|
149
|
+
- You'd be inventing groupings the user didn't describe.
|
|
150
|
+
|
|
151
|
+
**Single-column only.** Sections render as full-width single-column groups. Don't try to express multi-column layouts.
|
|
152
|
+
|
|
153
|
+
**One-section screens are usually wrong.** A single section spanning the whole screen is just a screen with a redundant header bar. Either emit no sections, or emit ≥ 2 sections per screen.
|
|
154
|
+
|
|
155
|
+
## Post-screen automation — determine the desired outcome
|
|
156
|
+
|
|
157
|
+
A data capture form is rarely just a form. The captured data almost always needs to **do** something in Salesforce: create a record, update a record, look something up.
|
|
158
|
+
|
|
159
|
+
You **must** determine the desired outcome before finalizing the spec. A form that captures perfect data but never writes anything to Salesforce is a broken flow.
|
|
160
|
+
|
|
161
|
+
### Outcome-elicitation rules
|
|
162
|
+
|
|
163
|
+
For every form, ask yourself:
|
|
164
|
+
|
|
165
|
+
1. **What Salesforce object should be created or updated when the user finishes?** (e.g. ProductTransfer, WorkOrderLineItem, Case, Asset, ServiceAppointment.)
|
|
166
|
+
2. **Are any rows in a Repeater supposed to become individual records?** If yes, you need a `loop` over `<Repeater>.AddedItems` and a `recordCreate` per iteration.
|
|
167
|
+
3. **Does any captured value need to be resolved to a record Id before writing?** If yes, you need a `recordLookup`.
|
|
168
|
+
4. **Is the user picking a branch that determines which lookup or write to do?** If yes, you need a `decision`.
|
|
169
|
+
5. **Is there a parent record passed in via `parentRecordId` / `parentObjectType`?** This is the standard Field Service entry-point pattern.
|
|
170
|
+
|
|
171
|
+
### How to decide whether to emit `postScreen`
|
|
172
|
+
|
|
173
|
+
| Signal | Action |
|
|
174
|
+
|---|---|
|
|
175
|
+
| The user explicitly says what to create/update ("create a ProductTransfer for each part") | **Emit `postScreen`** with the named object and field mappings. |
|
|
176
|
+
| The user gives a form name or purpose that strongly implies a single object — Inventory Transfer, Work Order Completion, Asset Inspection, Damage Report, Time Entry | **Emit `postScreen`** with your best-guess object/field mapping AND list every `valueRef` / `field` in the confirmation step so the user can correct names. |
|
|
177
|
+
| The user describes a Repeater whose rows obviously become rows in Salesforce | **Emit `postScreen`** with a loop + recordCreate. State the assumption explicitly. |
|
|
178
|
+
| You truly cannot infer what the data should do, AND the user gave no hint | Surface a question in the confirmation step ("What should happen when this form is submitted?") with concrete options. Don't deploy a screens-only flow without flagging that the data goes nowhere. |
|
|
179
|
+
|
|
180
|
+
### Common outcome patterns
|
|
181
|
+
|
|
182
|
+
- **Inventory Transfer** (form has a parts repeater) → loop over `Part.AddedItems` → create one `ProductTransfer` per row, mapping `Product2Id`, `QuantitySent`, `QuantityReceived`, `DestinationLocationId`.
|
|
183
|
+
- **Inspection / Checklist** → create one `WorkOrderLineItem` or `Asset__History` record summarizing the inspection.
|
|
184
|
+
- **Time Entry** → create a `ResourceAbsence` or custom time-entry record tied to `parentRecordId`.
|
|
185
|
+
- **Damage Report** → update the parent Work Order and/or create child Case records.
|
|
186
|
+
|
|
187
|
+
### Validation for `postScreen`
|
|
188
|
+
|
|
189
|
+
When you emit a `postScreen` block, every reference must point at a real thing:
|
|
190
|
+
|
|
191
|
+
- Every `valueRef` is either: a `<fieldName>.value` from a screen field, a `<RepeaterName>.<ChildName>.value` inside a loop, a non-input variable you declared, or a global like `$User.Id`.
|
|
192
|
+
- Every `field` in `inputAssignments` and `outputAssignments` is the API name of a field on the named `object`. If you don't know the exact API name, use your best guess and list it in the confirmation step.
|
|
193
|
+
- Every `next` connector targets the name of an element you actually defined.
|
|
194
|
+
- The decision's branch `when.field` is a screen field, and `when.value` exactly matches one of that field's `options`.
|
|
195
|
+
|
|
196
|
+
## Validation checklist
|
|
197
|
+
|
|
198
|
+
Before returning, verify:
|
|
199
|
+
|
|
200
|
+
- [ ] Every screen key is PascalCase.
|
|
201
|
+
- [ ] Every `fieldName` is a valid API name, unique across the form (including inside repeaters).
|
|
202
|
+
- [ ] Every `fieldType` is one of the supported types in [field-types.md](../../fs-data-capture-form-deployer/reference/field-types.md) (case-sensitive).
|
|
203
|
+
- [ ] `Radio`, `Picklist`, `CheckboxGroup` have non-empty `options` (use 3–5 plausible options if the user didn't list specific ones, and surface that you guessed).
|
|
204
|
+
- [ ] `Matrix` has both `options` (columns) and `matrixRows`.
|
|
205
|
+
- [ ] `Repeater` has `repeaterFields` (each child has its own valid `fieldType`).
|
|
206
|
+
- [ ] Any `visibility.value` exactly matches one of the referenced field's `options`.
|
|
207
|
+
- [ ] **No fabricated fields the user didn't mention.** This is the most common prose-extraction bug — don't pad the form with "usual" fields.
|
|
208
|
+
- [ ] **Outcome is determined.** Either a `postScreen` block is emitted, or the confirmation step will explicitly ask the user what to do with the data.
|
|
209
|
+
- [ ] If `postScreen` is emitted: every `valueRef` resolves, every `field` belongs to the named `object` (or is flagged for user review), every `next` connector targets a defined element.
|
|
210
|
+
- [ ] **Specialized types are evidence-backed.** For every `Signature`, `UploadFile`, `UploadImage`, `Images`, `Matrix`, `Address`, `Lookup`, `FileView`, and `Repeater` in the output, name the prose evidence ("user said 'add multiple parts'"). If the user only used the *label* not the *control vocabulary*, downgrade the type per the table above. (These are real components that deploy as functional widgets — emitting them when the user only meant a text field is the most common bug.)
|
|
211
|
+
- [ ] **Lookup has `lookupObject`.** Every `Lookup` field has a `lookupObject` (Salesforce object API name). If the user didn't say which object, surface a question in the confirmation step or pick a best-guess and flag it.
|
|
212
|
+
- [ ] **FileView has `fileName`.** Every `FileView` field has a `fileName` (static asset filename, no extension). If unknown, surface a question.
|
|
213
|
+
- [ ] **Sections only where the user described them.** Every `{ "section": "..." }` item corresponds to a named sub-group the user actually mentioned. No invented sections, and no screens with exactly one section.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Source design docs
|
|
218
|
+
|
|
219
|
+
This rule sheet is informed by two upstream design docs. Don't paste the full prompts from those docs into the user-facing flow — they're internal source-of-truth references.
|
|
220
|
+
|
|
221
|
+
- **Form-To-Flow AI HLD** ([doc](https://docs.google.com/document/d/1XlDRQE1gVrux8Iyz5LDupN9xV7i1IKpczLbsvMq5Tc4)) — the Flow Builder team's architecture for prose/PDF-to-DC-Flow generation.
|
|
222
|
+
- **Field Service POC HLD** ([doc](https://docs.google.com/document/d/10TO6CC983AcclXY7Ixp3I3hY5R7TagUMWP9VRqXOFoc)) — Field Service team's Apex+Agentforce POC. Source for the intermediate JSON contract and the extraction prompt rules.
|