@salesforce/afv-skills 1.45.0 → 1.47.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.
Files changed (171) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-observe/SKILL.md +32 -4
  3. package/skills/agentforce-observe/references/ahm-alerts.md +719 -0
  4. package/skills/automation-flow-generate/SKILL.md +11 -5
  5. package/skills/consumer-goods-promotion-bo-api-deploy/SKILL.md +275 -0
  6. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/README.md +32 -0
  7. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/SetCommentValue.cls +75 -0
  8. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/SetCommentValue.cls-meta.xml +5 -0
  9. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/interview-answers.json +13 -0
  10. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/copy.json +10 -0
  11. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/create.json +20 -0
  12. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/update.json +16 -0
  13. package/skills/consumer-goods-promotion-bo-api-deploy/references/conventions-and-payload-rules.md +273 -0
  14. package/skills/consumer-goods-promotion-bo-api-deploy/references/generate-and-wire.md +236 -0
  15. package/skills/consumer-goods-promotion-bo-api-deploy/references/reference-example-set-comment-value.md +132 -0
  16. package/skills/consumer-goods-promotion-bo-api-deploy/references/smoke-and-verify.md +211 -0
  17. package/skills/dx-code-analyzer-configure/scripts/validate-config.sh +14 -10
  18. package/skills/dx-code-analyzer-run/scripts/apply-fixes.js +45 -4
  19. package/skills/dx-code-analyzer-run/scripts/describe-rule.js +52 -32
  20. package/skills/dx-devops-project-manage/SKILL.md +197 -0
  21. package/skills/dx-devops-project-manage/examples/common-workflows.md +197 -0
  22. package/skills/dx-devops-project-manage/references/cli-commands.md +295 -0
  23. package/skills/dx-devops-project-manage/scripts/create-project.sh +48 -0
  24. package/skills/dx-devops-project-manage/scripts/list-projects.sh +51 -0
  25. package/skills/dx-devops-project-manage/scripts/update-project.sh +96 -0
  26. package/skills/education-cloud-academic-calendar-generate/SKILL.md +225 -0
  27. package/skills/education-cloud-academic-calendar-generate/examples/quarter-calendar.json +47 -0
  28. package/skills/education-cloud-academic-calendar-generate/examples/sample-output.md +57 -0
  29. package/skills/education-cloud-academic-calendar-generate/examples/semester-calendar.json +54 -0
  30. package/skills/education-cloud-academic-calendar-generate/references/calendar-systems.md +127 -0
  31. package/skills/education-cloud-academic-calendar-generate/references/date-validation.md +222 -0
  32. package/skills/education-cloud-academic-calendar-generate/references/foundation_prerequisites.md +40 -0
  33. package/skills/education-cloud-academic-calendar-generate/scripts/validate_calendar_dates.py +143 -0
  34. package/skills/education-cloud-course-catalog-migrate/SKILL.md +321 -0
  35. package/skills/education-cloud-course-catalog-migrate/references/gotchas-detail.md +16 -0
  36. package/skills/education-cloud-course-catalog-migrate/references/gotchas.md +16 -0
  37. package/skills/education-cloud-course-catalog-migrate/references/large-catalog-handling.md +42 -0
  38. package/skills/education-cloud-course-catalog-migrate/scripts/batch_courses.py +36 -0
  39. package/skills/education-cloud-course-catalog-migrate/scripts/detect_linked_courses.py +51 -0
  40. package/skills/education-cloud-course-catalog-migrate/scripts/detect_modality_variants.py +48 -0
  41. package/skills/education-cloud-course-catalog-migrate/scripts/resolve_api_version.py +43 -0
  42. package/skills/education-cloud-course-catalog-migrate/scripts/split_course_code.py +39 -0
  43. package/skills/education-cloud-course-catalog-migrate/scripts/validate_completeness.py +54 -0
  44. package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md +3 -5
  45. package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +177 -0
  46. package/skills/education-cloud-student-recruitment-agent-configure/references/agent-and-subagents.md +151 -0
  47. package/skills/education-cloud-student-recruitment-agent-configure/references/customer-narration.md +34 -0
  48. package/skills/education-cloud-student-recruitment-agent-configure/references/execution-model.md +54 -0
  49. package/skills/education-cloud-student-recruitment-agent-configure/references/flows.md +82 -0
  50. package/skills/education-cloud-student-recruitment-agent-configure/references/grounding.md +199 -0
  51. package/skills/education-cloud-student-recruitment-agent-configure/references/permissions.md +183 -0
  52. package/skills/education-cloud-student-recruitment-agent-configure/references/platform-enablement.md +82 -0
  53. package/skills/education-cloud-student-recruitment-agent-configure/references/prerequisites.md +158 -0
  54. package/skills/education-cloud-student-recruitment-agent-configure/references/routing.md +141 -0
  55. package/skills/experience-cms-brand-apply/SKILL.md +5 -5
  56. package/skills/experience-cms-brand-create/SKILL.md +2 -2
  57. package/skills/experience-cms-content-generate/SKILL.md +1 -0
  58. package/skills/experience-cms-content-render/SKILL.md +173 -0
  59. package/skills/experience-cms-content-render/assets/angular/DetailPage.component.ts +25 -0
  60. package/skills/experience-cms-content-render/assets/angular/MediaRenderer.component.ts +133 -0
  61. package/skills/experience-cms-content-render/assets/angular/TypeList.component.ts +38 -0
  62. package/skills/experience-cms-content-render/assets/angular/TypeRenderer.component.ts +90 -0
  63. package/skills/experience-cms-content-render/assets/angular/cms-content.component.ts +248 -0
  64. package/skills/experience-cms-content-render/assets/angular/cms-item.service.ts +100 -0
  65. package/skills/experience-cms-content-render/assets/react/DetailPage.tsx +20 -0
  66. package/skills/experience-cms-content-render/assets/react/MediaRenderer.tsx +129 -0
  67. package/skills/experience-cms-content-render/assets/react/TypeList.tsx +40 -0
  68. package/skills/experience-cms-content-render/assets/react/TypeRenderer.tsx +64 -0
  69. package/skills/experience-cms-content-render/assets/react/heuristicRenderer.tsx +310 -0
  70. package/skills/experience-cms-content-render/assets/react/useCmsItem.ts +129 -0
  71. package/skills/experience-cms-content-render/assets/shared/cmsContentType.ts +49 -0
  72. package/skills/experience-cms-content-render/assets/shared/cmsCore.types.ts +96 -0
  73. package/skills/experience-cms-content-render/assets/shared/externalRefs.ts +55 -0
  74. package/skills/experience-cms-content-render/references/bulk-loading.md +60 -0
  75. package/skills/experience-cms-content-render/references/codegen-guardrails.md +111 -0
  76. package/skills/experience-cms-content-render/references/detail-pages.md +87 -0
  77. package/skills/experience-cms-content-render/references/embed-recipes.md +127 -0
  78. package/skills/experience-cms-content-render/references/failure-modes.md +96 -0
  79. package/skills/experience-cms-content-render/references/heuristic-render-rules.md +131 -0
  80. package/skills/experience-cms-content-render/references/init-scaffold.md +122 -0
  81. package/skills/experience-cms-content-render/references/interaction-model.md +173 -0
  82. package/skills/experience-cms-content-render/references/package-api.md +106 -0
  83. package/skills/experience-cms-content-render/references/schema-sync.md +114 -0
  84. package/skills/experience-cms-content-render/references/styling-scopes.md +65 -0
  85. package/skills/experience-cms-content-render/references/verify.md +49 -0
  86. package/skills/experience-cms-content-type-generate/SKILL.md +2 -2
  87. package/skills/experience-content-media-stock-image-search/SKILL.md +5 -4
  88. package/skills/experience-search-coordinate/SKILL.md +198 -0
  89. package/skills/experience-search-coordinate/assets/search-payload-template.json +25 -0
  90. package/skills/experience-search-coordinate/references/content-route.md +313 -0
  91. package/skills/experience-search-coordinate/references/content-type-discovery.md +57 -0
  92. package/skills/experience-search-coordinate/references/media-route.md +172 -0
  93. package/skills/experience-search-coordinate/references/scope-resolution.md +14 -0
  94. package/skills/experience-ui-bundle-localize/SKILL.md +1 -1
  95. package/skills/experience-ui-bundle-localize/references/i18n-setup.md +5 -3
  96. package/skills/experience-ui-bundle-project-generate/SKILL.md +18 -14
  97. package/skills/experience-ui-bundle-project-generate/references/angular-project-generate.md +22 -0
  98. package/skills/experience-ui-bundle-project-generate/references/react-project-generate.md +20 -0
  99. package/skills/experience-ui-bundle-salesforce-data-access/SKILL.md +58 -54
  100. package/skills/experience-ui-bundle-salesforce-data-access/references/caching.md +6 -0
  101. package/skills/experience-ui-bundle-salesforce-data-access/references/graphiti-cli.md +2 -2
  102. package/skills/experience-ui-bundle-salesforce-data-access/references/migration.md +6 -0
  103. package/skills/experience-ui-bundle-salesforce-data-access/references/rest-and-integration.md +2 -1
  104. package/skills/experience-ui-bundle-salesforce-data-access/references/sdk-api.md +6 -0
  105. package/skills/experience-ui-bundle-site-generate/SKILL.md +59 -8
  106. package/skills/experience-ui-bundle-site-generate/references/configure-metadata-digital-experience.md +8 -3
  107. package/skills/experience-ui-bundle-site-generate/references/configure-metadata-language-settings.md +120 -0
  108. package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +336 -0
  109. package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +143 -0
  110. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-application-flexipage-mapping.md +127 -0
  111. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-deploy-commands.md +116 -0
  112. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-lifesci-metadata-deploy.md +111 -0
  113. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-overview.md +312 -0
  114. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-profile-layout-assignments.md +171 -0
  115. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-state-tracking.md +64 -0
  116. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-trigger-handlers.md +122 -0
  117. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-4-user-provisioning-overview.md +335 -0
  118. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-4-user-provisioning-user-provisioning-details.md +140 -0
  119. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-execution-state-and-recovery.md +196 -0
  120. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-metadata-cache-generation.md +155 -0
  121. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md +307 -0
  122. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-visit-creation-data.md +211 -0
  123. package/skills/life-sciences-fieldsalesrep-coordinate/references/state-machine-and-changes.md +108 -0
  124. package/skills/life-sciences-kam-coordinate/SKILL.md +241 -0
  125. package/skills/life-sciences-kam-coordinate/references/orchestration-flow.md +152 -0
  126. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-application-flexipage-mapping.md +79 -0
  127. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-deploy-commands.md +131 -0
  128. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-kam-config-records.md +85 -0
  129. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-lifesci-metadata-deploy.md +112 -0
  130. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-overview.md +202 -0
  131. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-profile-layout-assignments.md +67 -0
  132. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-state-tracking.md +65 -0
  133. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-trigger-handlers.md +123 -0
  134. package/skills/life-sciences-kam-coordinate/references/stage-4-participant-role-and-sprint.md +89 -0
  135. package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +337 -0
  136. package/skills/life-sciences-kam-coordinate/references/stage-5-data-creation-data.md +248 -0
  137. package/skills/life-sciences-kam-coordinate/references/stage-6-ipad-validation-script.md +35 -0
  138. package/skills/life-sciences-kam-coordinate/references/stage-6-metadata-cache-generation.md +155 -0
  139. package/skills/life-sciences-kam-coordinate/references/stage-6-user-provisioning-details.md +146 -0
  140. package/skills/life-sciences-kam-coordinate/references/stage-6-user-provisioning-overview.md +89 -0
  141. package/skills/life-sciences-kam-coordinate/references/state-machine-and-changes.md +114 -0
  142. package/skills/life-sciences-prerequisites-validate/SKILL.md +138 -0
  143. package/skills/life-sciences-prerequisites-validate/references/checks-org-settings.md +190 -0
  144. package/skills/life-sciences-prerequisites-validate/references/checks-user-and-package.md +211 -0
  145. package/skills/life-sciences-territory-configure/SKILL.md +217 -0
  146. package/skills/life-sciences-territory-configure/references/territory-metadata.md +262 -0
  147. package/skills/platform-apex-logs-debug/SKILL.md +7 -7
  148. package/skills/platform-custom-application-generate/SKILL.md +4 -4
  149. package/skills/platform-custom-object-generate/SKILL.md +7 -7
  150. package/skills/platform-custom-tab-generate/SKILL.md +1 -1
  151. package/skills/platform-dsar-policy-manage/SKILL.md +272 -0
  152. package/skills/platform-dsar-policy-manage/references/configure.md +106 -0
  153. package/skills/platform-dsar-policy-manage/references/export-and-history.md +123 -0
  154. package/skills/platform-dsar-policy-manage/references/gap-analysis-guide.md +150 -0
  155. package/skills/platform-dsar-policy-manage/references/gap-scan.md +129 -0
  156. package/skills/platform-dsar-policy-manage/references/headless-sor.md +59 -0
  157. package/skills/platform-dsar-policy-manage/references/report-format.md +59 -0
  158. package/skills/platform-dsar-policy-manage/scripts/tests/__init__.py +0 -0
  159. package/skills/platform-dsar-policy-manage/scripts/tests/test_validate_policy_tree.py +76 -0
  160. package/skills/platform-dsar-policy-manage/scripts/validate-policy-tree.py +130 -0
  161. package/skills/platform-flexipage-generate/SKILL.md +4 -0
  162. package/skills/platform-list-view-generate/SKILL.md +1 -0
  163. package/skills/platform-salesforce-connect-adapter-generate/SKILL.md +359 -0
  164. package/skills/platform-salesforce-connect-adapter-generate/references/official-examples.md +69 -0
  165. package/skills/platform-salesforce-connect-adapter-generate/references/scenarios.md +187 -0
  166. package/skills/platform-soql-query/SKILL.md +8 -8
  167. package/skills/platform-value-set-generate/SKILL.md +2 -2
  168. package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +20 -27
  169. package/skills/service-native-voice-recording-transcription-configure/SKILL.md +47 -27
  170. package/skills/service-native-voice-recording-transcription-configure/references/thunderbird-voice-settings.md +13 -9
  171. package/skills/service-native-voice-recording-transcription-configure/scripts/enable-recording-transcription.sh +104 -45
@@ -0,0 +1,307 @@
1
+ # Stage 5 — Visit Creation
2
+
3
+ Creates a sample Visit and all supporting records as the Field Sales Rep user (not the admin) in a Life Sciences Cloud org. This is the final stage (Stage 5) of the `life-sciences-fieldsalesrep-coordinate` workflow; the coordinator invokes it after the rep user (Stage 4) is provisioned.
4
+
5
+ ## Stage Scope
6
+
7
+ - **In scope**: logging in as the sales rep; creating the full visit-chain records (Account → ProviderVisitProdDiscussion); generating the mobile metadata cache (LifeSciMobileMetadataRecord + Connect API); guiding a final manual iPad app validation; displaying a summary
8
+ - **Out of scope**: creating territories (Stage 3), provisioning users (Stage 4), package installation (Stage 1)
9
+
10
+ ---
11
+
12
+ ## Prerequisites
13
+
14
+ These must exist in the org before this stage runs (the coordinator sequences the earlier stages so they do):
15
+
16
+ | Prerequisite | Created by |
17
+ |---|---|
18
+ | Field Sales Rep user (with LSC Custom Profile) | Stage 4 (User Provisioning) |
19
+ | Active Territory Model with level-3 territory | Stage 3 (`life-sciences-territory-configure`) |
20
+ | Life Sciences Cloud packages installed | Stage 1 (`life-sciences-prerequisites-validate`) |
21
+
22
+ ---
23
+
24
+ ## Required Inputs
25
+
26
+ Gather before proceeding:
27
+
28
+ - **Target org** (admin alias): The org alias or username for the admin connection (from `sf config get target-org` or user-specified)
29
+ - **Sales Rep credentials**: Username and password for the Field Sales Rep user. **Ask the user** if not already known — do NOT assume or reuse admin credentials.
30
+
31
+ ---
32
+
33
+ ## Source Data (CSV-driven — read first, use only these)
34
+
35
+ **All record field values MUST come from the CSV files in `.lsc-starter-config/LSStarterConfig/Data/`** — read the corresponding CSV at execution time and use **only** the values it contains. Never hardcode values from this overview or carry them over from a prior run; the CSVs are the single source of truth and may change between runs.
36
+
37
+ > **The `.lsc-starter-config/LSStarterConfig/Data/` CSVs must already be present in the CWD** (from the public repo <https://github.com/SalesforceLabs/LSStarterConfig.git>). This embedded stage is a pure consumer of the folder and does NOT download or delete it — the coordinator (`life-sciences-fieldsalesrep-coordinate`) is the sole owner of the single download (at the start of the run) and the single delete (at the end). If `.lsc-starter-config/LSStarterConfig/` is absent when this stage runs, stop and report that it must be provisioned by the coordinator; do not download it here.
38
+
39
+ - Read each CSV (e.g. `cat .lsc-starter-config/LSStarterConfig/Data/<object>.csv`, named per the sobject — `account.csv`, `healthcareprovider.csv`, … `providervisitproddiscussion.csv`; the per-object mapping is in `references/stage-5-visit-creation-visit-creation-data.md`), parse header + rows, and create **one record per row** using exactly the columns present.
40
+ - CSV columns that hold **source-org IDs** (e.g. `ProductId`, `TerritoryId`, `ParentProductId`, `ProviderVisitId`, record-type IDs) will NOT exist in the target org — resolve the equivalent record in the target org and remap the ID. Never insert a raw source-org ID.
41
+ - The literal values shown in the workflow steps below and in `references/stage-5-visit-creation-visit-creation-data.md` are **illustrative of one CSV snapshot only** — the live CSV wins if they differ.
42
+
43
+ ---
44
+
45
+ ## State Tracking
46
+
47
+ Maintain a creation state throughout the workflow (target org, rep username/alias, and a per-step status list for steps 1–16) so a smoke-test failure can be diagnosed and resumed. See the full state model in `references/stage-5-visit-creation-execution-state-and-recovery.md`.
48
+
49
+ ---
50
+
51
+ ## Workflow
52
+
53
+ ### Phase 1 — Login as Sales Rep
54
+
55
+ 1. **Ask the user** for the Sales Rep credentials (username and password) if not already known.
56
+
57
+ 2. **Authenticate as the Sales Rep** using the web login flow — **run the command yourself** (do not hand it to the user); it opens a browser on the user's machine for them to complete the login interactively, then returns:
58
+ ```bash
59
+ sf org login web --alias lsc-rep --instance-url <instanceUrl>
60
+ ```
61
+ Or use JWT/password flow if available:
62
+ ```bash
63
+ sf org login sfdx-url --sfdx-url-stdin <<< "<sfdxAuthUrl>"
64
+ ```
65
+
66
+ > Rep-owned steps (2, 3, 4, 6, 10–13) use `--target-org lsc-rep`; admin-owned steps (5, 7, 8, 9, 14–15) use `--target-org <admin>`. See the Phase 2/3 notes for the ownership split rationale.
67
+
68
+ 3. **Verify the login** succeeded with `sf org display --target-org lsc-rep --json` and confirm the username matches the expected sales rep.
69
+
70
+ ### Phase 2 — Create Account and Provider Records (Steps 2–6)
71
+
72
+ > **Rep vs. Admin ownership (important):** The LSC Custom Profile can create the Account, HealthcareProvider, ContactPointAddress, ProviderAcctTerritoryInfo, and the whole Visit chain (Steps 10–13) — but NOT territory associations (Step 5) or product master data (Steps 7–9). Create those as the admin (`--target-org <admin>`), then switch back to the rep. This split is expected: territory associations and products are admin-managed data.
73
+
74
+ **Step 2: Create Account (RecordType = Health_Care_Provider)**
75
+
76
+ First, query the RecordType ID:
77
+ ```bash
78
+ sf data query --query "SELECT Id FROM RecordType WHERE SObjectType='Account' AND DeveloperName='Health_Care_Provider'" --target-org lsc-rep --json
79
+ ```
80
+
81
+ Then create the Account:
82
+ ```bash
83
+ sf data create record --sobject Account --values "FirstName='Aaron' LastName='Morita' Salutation='Dr.' RecordTypeId='<recordTypeId>' IsActive=true" --target-org lsc-rep --json
84
+ ```
85
+
86
+ > Reference: `account.csv` — Name=Aaron Morita, Salutation=Dr., RecordType=Health_Care_Provider.
87
+ > The active flag is the standard `IsActive` field (boolean) — NOT `IsActive__c`. If the rep lacks FLS to it, omit it and have an admin set it afterward.
88
+
89
+ **Step 3: Create HealthcareProvider**
90
+
91
+ First, query the HealthcareProvider RecordType ID:
92
+ ```bash
93
+ sf data query --query "SELECT Id FROM RecordType WHERE SObjectType='HealthcareProvider' AND DeveloperName != null LIMIT 1" --target-org lsc-rep --json
94
+ ```
95
+
96
+ Then create:
97
+ ```bash
98
+ sf data create record --sobject HealthcareProvider --values "AccountId='<accountId>' IsActive=true IsPrimaryProvider=true Name='Aaron Morita HP' ProviderType='Medical Doctor' Status='Active' RecordTypeId='<hcpRecordTypeId>'" --target-org lsc-rep --json
99
+ ```
100
+
101
+ > Reference: `healthcareprovider.csv` — ProviderType=Medical Doctor, Status=Active. Do NOT set `NationalProviderIdentifier` or `IsSpeaker` — they (and `IsActive`) are FLS-gated on the LSC Custom Profile, so as the rep the create fails with `INVALID_FIELD`. Omit NPI/IsSpeaker (an admin can set them later).
102
+
103
+ **Step 4: Create ContactPointAddress**
104
+
105
+ ```bash
106
+ sf data create record --sobject ContactPointAddress --values "ParentId='<accountId>' AddressType='Billing' Name='415 Mission St' Street='415 Mission St' City='San Francisco' State='California' StateCode='CA' PostalCode='94105' Country='United States' CountryCode='US' Latitude=37.789853 Longitude=-122.396806 IsActive=true IsPrimary=true UsageType='Work'" --target-org lsc-rep --json
107
+ ```
108
+
109
+ > Reference: `contactpointaddress.csv` — 415 Mission St, San Francisco, CA 94105
110
+
111
+ **Step 5: Create ObjectTerritory2Association — as ADMIN**
112
+
113
+ First, query the level-3 territory ID:
114
+ ```bash
115
+ sf data query --query "SELECT Id, Name FROM Territory2 WHERE Territory2Model.State='Active' AND ParentTerritory2.ParentTerritory2Id != null" --target-org <admin> --json
116
+ ```
117
+
118
+ Then create it **as the admin** — the rep profile lacks "Manage Territories", so as the rep this fails with `entity type cannot be inserted: Object Territory Association` (describe reports `createable=false` for the rep). As the admin it is `createable=true`:
119
+ ```bash
120
+ sf data create record --sobject ObjectTerritory2Association --values "ObjectId='<accountId>' Territory2Id='<territory2Id>' AssociationCause='Territory2Manual'" --target-org <admin> --json
121
+ ```
122
+
123
+ > Reference: `objectterritory2association.csv` — AssociationCause=Territory2Manual. This is an admin-managed record, not referenced by any later record (the Visit gets its territory from its own `TerritoryId`, Step 10; the account↔territory link is carried by ProviderAcctTerritoryInfo, Step 6). If admin access is unavailable, it may be skipped without breaking the visit.
124
+
125
+ **Step 6: Create ProviderAcctTerritoryInfo**
126
+
127
+ ```bash
128
+ sf data create record --sobject ProviderAcctTerritoryInfo --values "AccountId='<accountId>' Territory2Id='<territory2Id>' PreferredAddressId='<contactPointAddressId>' IsActive=true IsAvailableOffline=true IsTargetedAccount=true SourceType='Manual'" --target-org lsc-rep --json
129
+ ```
130
+
131
+ > Reference: `provideracctterritoryinfo.csv` — IsTargetedAccount=true, SourceType=Manual
132
+
133
+ ### Phase 3 — Create Product Records (Steps 7–9) — as ADMIN
134
+
135
+ Products are master data. The rep's LSC Custom Profile has NO create permission on `Product2` / `LifeSciMarketableProduct` (as the rep, even `Name` reports `createable=false` and `Product2.ProductCode` is not visible), and `ProductTerritoryAvailability` also fails as the rep. Create all three **as the admin** (`--target-org <admin>`). If your rep genuinely must own products, grant the profile Create + field access first — but the default and recommended path is admin.
136
+
137
+ **Step 7: Create Product2 (no RecordType) — as ADMIN**
138
+
139
+ ```bash
140
+ sf data create record --sobject Product2 --values "Name='Immunexis 5mg' ProductCode='IM001-5' IsActive=true" --target-org <admin> --json
141
+ ```
142
+
143
+ > Reference: `product2.csv` — Do NOT set a RecordType.
144
+
145
+ **Step 8: Create LifeSciMarketableProduct — as ADMIN**
146
+
147
+ ```bash
148
+ sf data create record --sobject LifeSciMarketableProduct --values "Name='Immunexis 5mg' ProductId='<product2Id>' IsActive=true IsAvlForSamplingAllocation=true Manufacturer='Makana Health' DistributionMethod='Drop' SignatureRequirementLevel='Mandatory' SortOrder=100 StartDate=2026-07-01 Type='Product'" --target-org <admin> --json
149
+ ```
150
+
151
+ > Reference: `lifescimarketableproduct.csv` — Manufacturer=Makana Health, DistributionMethod=Drop
152
+
153
+ **Step 9: Create ProductTerritoryAvailability — as ADMIN**
154
+
155
+ ```bash
156
+ sf data create record --sobject ProductTerritoryAvailability --values "ProductId='<lifeSciMarketableProductId>' TerritoryId='<territory2Id>' AlignmentType='Territory Inclusion' Purpose='Visit' Status='Draft' UsageType='LifeSciences'" --target-org <admin> --json
157
+ ```
158
+
159
+ > Reference: `productterritoryavailability.csv` — AlignmentType=Territory Inclusion, Purpose=Visit. After Step 9, switch back to the rep (`--target-org lsc-rep`) for the Visit chain (Steps 10–13) so the visit records are rep-owned.
160
+
161
+ ### Phase 4 — Create Visit Records (Steps 10–13)
162
+
163
+ > **STOP-GATE (chain integrity).** Steps 10–13 are a strict dependency chain — each `sf data create record` returns an `id` that is a required input to the next step. After **every** create in this stage (Steps 2–13), confirm the response has `"success": true` and capture the real returned `id`. If any create fails, **STOP immediately** — do NOT continue with a null, empty, or placeholder ID (that produces an orphaned or mis-parented record chain that looks created but is broken). Report which step failed and its error. After Step 13, verify the full chain resolves: the ProviderVisitProdDiscussion → ProviderVisitProdDetailing → ProviderVisit → Visit → Account links must all be non-null.
164
+
165
+ **Step 10: Create Visit (PlannedVisitStartTime = NOW)**
166
+
167
+ ```bash
168
+ sf data create record --sobject Visit --values "AccountId='<accountId>' PlaceId='<contactPointAddressId>' PlannedVisitStartTime='<NOW_ISO8601>' Status='Planned' TerritoryId='<territory2Id>'" --target-org lsc-rep --json
169
+ ```
170
+
171
+ > `<NOW_ISO8601>` = current datetime in ISO 8601 (e.g. `2026-08-01T10:30:00.000+0000`), generated at execution time with `date -u +"%Y-%m-%dT%H:%M:%S.000+0000"`.
172
+ >
173
+ > Reference: `visit.csv` — Status=Planned, linked to Account, Place, and Territory
174
+
175
+ **Step 11: Create ProviderVisit**
176
+
177
+ First, query the territory name:
178
+ ```bash
179
+ sf data query --query "SELECT Name FROM Territory2 WHERE Id='<territory2Id>'" --target-org lsc-rep --json
180
+ ```
181
+
182
+ Then create:
183
+ ```bash
184
+ sf data create record --sobject ProviderVisit --values "VisitId='<visitId>' TerritoryName='<territoryName>' IsConfirmed=false" --target-org lsc-rep --json
185
+ ```
186
+
187
+
188
+ **Step 12: Create ProviderVisitProdDetailing**
189
+
190
+ ```bash
191
+ sf data create record --sobject ProviderVisitProdDetailing --values "ProviderVisitId='<providerVisitId>' ProductId='<lifeSciMarketableProductId>' Priority=4 AdditionalInformation='Discussed Oncology products and treatments' IsGeneratedFromPresentation=false" --target-org lsc-rep --json
192
+ ```
193
+
194
+ > Reference: `providervisitproddetailing.csv` — Priority=4, AdditionalInformation about Oncology products
195
+
196
+ **Step 13: Create ProviderVisitProdDiscussion**
197
+
198
+ ```bash
199
+ sf data create record --sobject ProviderVisitProdDiscussion --values "ProviderVisitProductDtlId='<providerVisitProdDetailingId>' Note='Discussed Oncology treatments and patient care approaches'" --target-org lsc-rep --json
200
+ ```
201
+
202
+ > Reference: `providervisitproddiscussion.csv` — Note about Oncology treatments
203
+
204
+ ### Phase 5 — Generate Metadata Cache (Steps 14–15) — as ADMIN
205
+
206
+ This phase sets up a prerequisite metadata record and calls the Connect API to generate the metadata cache. No permission set is required — the generate Connect API bypasses the metadata validation itself, so validation-skip and generate permissions are not needed.
207
+
208
+ **Step 14: Create LifeSciMobileMetadataRecord Prerequisite**
209
+
210
+ Create a **parent** `LifeSciMobileMetadataRecord` record and a **child** record linked to the LSC Custom Profile (`ParentMobileMetadataRecId` + `ProfileId`). Set **both** to `Status = 'ValidationCompleted'` — the generate API rejects the call unless the **parent** is `ValidationCompleted`, not just the child. Extract the **parent** record ID — needed as `parentMetadataRecordId` in Step 15. Read `references/stage-5-visit-creation-metadata-cache-generation.md` for exact Apex and the schema-check command.
211
+
212
+ **Step 15: Call the Metadata Generate Connect API**
213
+
214
+ Use the CLI's own authenticated REST client — a hand-rolled `curl` fails with `INVALID_AUTH_HEADER`. The body accepts `parentMetadataRecordId`, `apiVersion`, and `prefix` (do NOT include `generateStandardTranslations` — it is rejected):
215
+
216
+ Write the request body to a **project-local** relative file (never `/tmp` or any path outside the project) and remove it right after:
217
+
218
+ ```bash
219
+ cat > .lsc-mdgen-body.json <<'EOF'
220
+ {
221
+ "parentMetadataRecordId": "<parentRecordId>",
222
+ "apiVersion": "65.0",
223
+ "prefix": "lsc4ce"
224
+ }
225
+ EOF
226
+ sf api request rest \
227
+ "/services/data/v65.0/connect/life-sciences/commercial/metadata/actions/generate" \
228
+ --method POST \
229
+ --body @.lsc-mdgen-body.json \
230
+ --target-org <admin>
231
+ rm -f .lsc-mdgen-body.json
232
+ ```
233
+
234
+ > Expected: HTTP 200 with `{ "message": "Task enqueued for metadata cache generation." }`. This only confirms the task was accepted — it is NOT the final success signal. Generation runs asynchronously; the metadata records' `Status` then transitions to `Active`. **`Active` is the success state** — wait for it before treating generation as complete. A transition to `Inactive` (or records stuck unchanged) means the job failed or never ran — check `IntegrationErrorMessage` and Setup → Apex Jobs. Verify with a query on `Status`. See `references/stage-5-visit-creation-metadata-cache-generation.md` for full details.
235
+
236
+ ---
237
+
238
+ ### Phase 6 — Manual iPad Mobile-App Validation (Step 16) — as REP (manual)
239
+
240
+ The **final validation step (Step 16)** is **manual** — it can't be done programmatically. A tester installs the Life Sciences Cloud iPad app, logs in as the **rep**, and confirms the Visit is visible. Do this in order:
241
+
242
+ 1. **Display the Sales Rep credentials** — `Username: <repUsername>`, `Password: use the password you created`, and (only if the app prompts for a custom domain) `Login URL: <instanceUrl>`. Use the actual username/URL from this run — never invent them. **Do NOT print the password value**; refer to the password created during user provisioning. If the user lacks it, an admin can reset it; never substitute admin credentials.
243
+
244
+ 2. **Give the install/login/navigation instructions:** on the iPad, install "Life Sciences Cloud Mobile" from the App Store (<https://apps.apple.com/us/app/life-sciences-cloud-mobile/id6499238627>); open it and log in with the rep credentials; wait for the initial sync to finish (org data + metadata cache, 3–5 min on first login); then open the **Visits** tab and tap the Visit to view details.
245
+
246
+ 3. **Ask the confirmation prompt** — substitute the actual Visit Name and Account Name (auto-generated here as Visit `00000001`, Account `Dr. Aaron Morita`): **"Do you see the Visit '00000001' for Account 'Dr. Aaron Morita' in the iPad app?"**
247
+
248
+ 4. **Handle the response:** **YES** → mark Step 16 `confirmed`; this is the **end of the LSC setup in the org** — report success (Phase 7) and stop. **Issue reported** → mark `issue`, walk the troubleshooting steps below, then re-ask.
249
+
250
+ **Troubleshooting (only if the Visit is not visible):** verify each of these (`--target-org <admin>`), fix any that fail, have the tester force a re-sync (pull-to-refresh on the Visits list, or log out/in), then re-ask the prompt: (1) rep assigned to the level-3 territory (`UserTerritory2Association`) — else assign via Stage 4 (User Provisioning); (2) `ProviderAcctTerritoryInfo` exists for the Account + territory and `IsActive=true` — else (re)create Step 6; (3) `LifeSciMobileMetadataRecord` records are `Status='Active'` — else re-run Steps 14–15. Common root cause: the app synced **before** the territory assignment, ProviderAcctTerritoryInfo, or metadata cache existed. Exact queries/fixes are in `references/stage-5-visit-creation-visit-creation-data.md`.
251
+
252
+ ---
253
+
254
+ ## Phase 7 — Summary
255
+
256
+ After all records are created, display the completion summary — Account details, Visit details, and a 16-step record-creation summary with each record ID, ending with "Created as user: `<repUsername>`" and the iPad confirmation line. The exact ASCII template is in `references/stage-5-visit-creation-execution-state-and-recovery.md`; substitute the actual IDs and values from the run.
257
+
258
+ > **Keep the summary to that block.** Do NOT append notes that describe the underlying data, its shape (row/record counts, hierarchy levels), specific product/record names or IDs, or commentary comparing the source data to the skill's examples. End at the summary; no "worth noting for future runs" addendum.
259
+
260
+ ---
261
+
262
+ ## Smoke-Test-Failure Recovery
263
+
264
+ If any step fails, immediately perform auto-diagnosis: show **What happened** (exact CLI error), **Why**, **Possible causes**, **What I can do** (retry / skip / auto-fix / stop), and a **partial-success status** (completed N-1/16, failed step, records created so far). **Wait for user choice before continuing — do NOT silently skip failed steps.**
265
+
266
+ The failure-report template and the full auto-diagnosis error table (error pattern → diagnosis → auto-fix, covering `INVALID_TYPE`, `INVALID_FIELD`, `INSUFFICIENT_ACCESS_OR_READONLY`, `DUPLICATE_VALUE`, the Step 15 Connect API errors, etc.) are in `references/stage-5-visit-creation-execution-state-and-recovery.md`.
267
+
268
+ ---
269
+
270
+ ## Rules / Constraints
271
+
272
+ Load-bearing rules (full table with rationales in `references/stage-5-visit-creation-execution-state-and-recovery.md`):
273
+
274
+ - **`.lsc-starter-config/LSStarterConfig/` must already be present in the CWD — do NOT download or delete it.** That folder's download/cleanup is owned by `life-sciences-fieldsalesrep-coordinate`.
275
+ - **Read the `.lsc-starter-config/LSStarterConfig/Data/` CSV for each object and use ONLY its values** — at execution time, one record per row; never hardcode field values or reuse a prior run's. The CSVs are the single source of truth.
276
+ - **Ownership split:** create the **visit records** (Account, HealthcareProvider, ContactPointAddress, ProviderAcctTerritoryInfo, Visit, ProviderVisit, detailing, discussion) as the rep (`--target-org lsc-rep`); create **territory associations (Step 5), product master data (Steps 7–9), and metadata cache (Steps 14–15) as the admin** (`--target-org <admin>`) — the LSC Custom Profile can't create those.
277
+ - **Ask for rep credentials — never assume or reuse admin credentials.**
278
+ - Create records in exact order 2→15, then run the manual iPad validation (Step 16) last; earlier IDs feed later records and the metadata cache must exist before the app can sync the Visit.
279
+ - **Step 16 is manual** — show rep credentials (ask for the password if unknown; never use admin creds), give instructions, and never claim it's done without the user's explicit "yes"; on a reported issue, run the troubleshooting checks before re-asking.
280
+ - `PlannedVisitStartTime` must be NOW; Product2 must NOT have a RecordType.
281
+ - Show diagnosis on every failure and wait for the user's decision — no silent skips.
282
+
283
+ ---
284
+
285
+ ## Gotchas
286
+
287
+ Common failures and fixes — missing RecordTypes/objects, rep-vs-admin FLS on HealthcareProvider (NPI/IsSpeaker) and product master data, ISO 8601 date formats, the Step 14 profile/metadata prerequisites, and the Step 15 Connect API errors — are tabulated in `references/stage-5-visit-creation-execution-state-and-recovery.md`.
288
+
289
+ ---
290
+
291
+ ## Output Expectations
292
+
293
+ Deliverables:
294
+ - Authenticated as the Sales Rep (not admin); all 13 visit-chain records created in dependency order (Account → ProviderVisitProdDiscussion).
295
+ - LifeSciMobileMetadataRecord parent + child (child linked to the LSC Custom Profile), both `Status='ValidationCompleted'`; cache generation enqueued via Connect API and confirmed complete when the records reach `Status='Active'`.
296
+ - Manual iPad validation guided (rep creds shown, instructions given, confirmation prompt asked); a "yes" closes out setup, an issue triggers troubleshooting.
297
+ - Completion summary displayed (Account + Visit details, all record IDs). On failure: auto-diagnosis (What/Why/Causes/Actions) + partial-success status.
298
+
299
+ ---
300
+
301
+ ## Reference File Index
302
+
303
+ | File | When to read |
304
+ |------|-------------|
305
+ | `references/stage-5-visit-creation-visit-creation-data.md` | Default field values for all records (sourced from CSV files); also the Step 16 manual iPad validation checklist and troubleshooting queries |
306
+ | `references/stage-5-visit-creation-metadata-cache-generation.md` | During Phase 5 (Steps 14–15) — exact Apex and `sf api request rest` commands for metadata cache generation |
307
+ | `references/stage-5-visit-creation-execution-state-and-recovery.md` | The full creation-state model, the smoke-test-failure recovery template + auto-diagnosis error table, and the gotchas table |
@@ -0,0 +1,211 @@
1
+ # Visit Creation Data Reference
2
+
3
+ > **Read the CSVs — do not treat these tables as authoritative.** The values below are a **snapshot** of one export of the `.lsc-starter-config/LSStarterConfig/Data/` CSV files, kept for orientation only. At execution time you MUST read the actual CSV file for each object and use **only** the values it currently contains (one record per row). If a CSV differs from a table here — added/removed columns, changed values, extra rows — the **live CSV wins**. Never hardcode these values or reuse values from a previous run.
4
+ >
5
+ > **Do NOT narrate the difference to the user.** The example values here (e.g. `Immunexis 5mg`) are illustrative placeholders, not data — silently use whatever the live CSV contains and never tell the user that the live data differs from these examples, name a specific CSV row, or comment that the real product is a hierarchy rather than the sample product. Announcing the mismatch leaks internal data structure into user-facing output (against the "never mention the CSVs or underlying data in user-facing notes" rule) and adds noise. Just read the CSV and create the records.
6
+
7
+ Field values for all records, sourced from `.lsc-starter-config/LSStarterConfig/Data/` CSV files.
8
+
9
+ ## Source folder & object→CSV mapping
10
+
11
+ The CSVs come from the public repo <https://github.com/SalesforceLabs/LSStarterConfig.git>. As an embedded Stage 5, this stage is a pure consumer of the `.lsc-starter-config/LSStarterConfig/` folder and MUST NOT download or delete it — the coordinator (`life-sciences-fieldsalesrep-coordinate`) is the sole owner of the single download (at the start of the run) and the single delete (at the end). If the folder is not present when this stage runs, stop and report that it must be provisioned by the coordinator; do not fetch it here.
12
+
13
+ Each object maps to a CSV named for the sobject (lowercased) under `.lsc-starter-config/LSStarterConfig/Data/`:
14
+
15
+ | Object | CSV file |
16
+ |---|---|
17
+ | Account | `account.csv` |
18
+ | HealthcareProvider | `healthcareprovider.csv` |
19
+ | ContactPointAddress | `contactpointaddress.csv` |
20
+ | ObjectTerritory2Association | `objectterritory2association.csv` |
21
+ | ProviderAcctTerritoryInfo | `provideracctterritoryinfo.csv` |
22
+ | Product2 | `product2.csv` |
23
+ | LifeSciMarketableProduct | `lifescimarketableproduct.csv` |
24
+ | ProductTerritoryAvailability | `productterritoryavailability.csv` |
25
+ | Visit | `visit.csv` |
26
+ | ProviderVisit | `providervisit.csv` |
27
+ | ProviderVisitProdDetailing | `providervisitproddetailing.csv` |
28
+ | ProviderVisitProdDiscussion | `providervisitproddiscussion.csv` |
29
+
30
+ ## Account (RecordType: Health_Care_Provider)
31
+
32
+ | Field | Value | Source |
33
+ |-------|-------|--------|
34
+ | FirstName | Aaron | account.csv |
35
+ | LastName | Morita | account.csv |
36
+ | Salutation | Dr. | account.csv |
37
+ | RecordType DeveloperName | Health_Care_Provider | account.csv |
38
+ | IsActive | True | account.csv (standard `IsActive` boolean — NOT `IsActive__c`) |
39
+
40
+ > Created as the **rep** (`--target-org lsc-rep`). `IsActive` is the standard field; if the rep lacks FLS to it, omit and set as admin.
41
+
42
+ ## HealthcareProvider
43
+
44
+ | Field | Value | Source |
45
+ |-------|-------|--------|
46
+ | Name | Aaron Morita HP | healthcareprovider.csv |
47
+ | IsActive | True | healthcareprovider.csv |
48
+ | IsPrimaryProvider | True | healthcareprovider.csv |
49
+ | ProviderType | Medical Doctor | healthcareprovider.csv |
50
+ | Status | Active | healthcareprovider.csv |
51
+ | AccountId | (from Step 2) | FK |
52
+
53
+ > Do NOT set `NationalProviderIdentifier` or `IsSpeaker` on creation. Both — along with `IsActive` — are gated by field-level security on the LSC Custom Profile; if the rep lacks FLS the create fails. `IsSpeaker` and `NationalProviderIdentifier` are not required for the visit, so omit them (an admin can set them later). The CSV lists them because it was exported from an org where the profile had FLS to those fields.
54
+
55
+ ## ContactPointAddress
56
+
57
+ | Field | Value | Source |
58
+ |-------|-------|--------|
59
+ | Name | 415 Mission St | contactpointaddress.csv |
60
+ | AddressType | Billing | contactpointaddress.csv |
61
+ | Street | 415 Mission St | contactpointaddress.csv |
62
+ | City | San Francisco | contactpointaddress.csv |
63
+ | State | California | contactpointaddress.csv |
64
+ | StateCode | CA | contactpointaddress.csv |
65
+ | PostalCode | 94105 | contactpointaddress.csv |
66
+ | Country | United States | contactpointaddress.csv |
67
+ | CountryCode | US | contactpointaddress.csv |
68
+ | Latitude | 37.789853 | contactpointaddress.csv |
69
+ | Longitude | -122.396806 | contactpointaddress.csv |
70
+ | IsActive | True | contactpointaddress.csv |
71
+ | IsPrimary | True | contactpointaddress.csv |
72
+ | UsageType | Work | contactpointaddress.csv |
73
+ | ParentId | (from Step 2 — Account) | FK |
74
+
75
+ ## ObjectTerritory2Association
76
+
77
+ | Field | Value | Source |
78
+ |-------|-------|--------|
79
+ | ObjectId | (from Step 2 — Account) | FK |
80
+ | Territory2Id | (queried — level-3 territory) | FK |
81
+ | AssociationCause | Territory2Manual | objectterritory2association.csv |
82
+
83
+ > Create as **admin** (`--target-org <admin>`) — the rep profile lacks "Manage Territories" so OT2A is `createable=false` for the rep. Not referenced by any later record; may be skipped if admin access is unavailable.
84
+
85
+ ## ProviderAcctTerritoryInfo
86
+
87
+ | Field | Value | Source |
88
+ |-------|-------|--------|
89
+ | AccountId | (from Step 2) | FK |
90
+ | Territory2Id | (queried — level-3 territory) | FK |
91
+ | PreferredAddressId | (from Step 4 — ContactPointAddress) | FK |
92
+ | IsActive | True | provideracctterritoryinfo.csv |
93
+ | IsAvailableOffline | True | provideracctterritoryinfo.csv |
94
+ | IsTargetedAccount | True | provideracctterritoryinfo.csv |
95
+ | SourceType | Manual | provideracctterritoryinfo.csv |
96
+
97
+ ## Product2 (NO RecordType)
98
+
99
+ | Field | Value | Source |
100
+ |-------|-------|--------|
101
+ | Name | Immunexis 5mg | product2.csv |
102
+ | ProductCode | IM001-5 | product2.csv |
103
+ | IsActive | True | product2.csv |
104
+
105
+ > Do NOT set RecordTypeId — this is an explicit requirement.
106
+ > Create as **admin** — the rep profile has no create permission on Product2 (`Name` is `createable=false`, `ProductCode` invisible for the rep). Steps 7–9 (Product2, LifeSciMarketableProduct, ProductTerritoryAvailability) are all admin-owned master data.
107
+
108
+ ## LifeSciMarketableProduct
109
+
110
+ | Field | Value | Source |
111
+ |-------|-------|--------|
112
+ | Name | Immunexis 5mg | lifescimarketableproduct.csv |
113
+ | ProductId | (from Step 7 — Product2) | FK |
114
+ | IsActive | True | lifescimarketableproduct.csv |
115
+ | IsAvlForSamplingAllocation | True | lifescimarketableproduct.csv |
116
+ | Manufacturer | Makana Health | lifescimarketableproduct.csv |
117
+ | DistributionMethod | Drop | lifescimarketableproduct.csv |
118
+ | SignatureRequirementLevel | Mandatory | lifescimarketableproduct.csv |
119
+ | SortOrder | 100 | lifescimarketableproduct.csv |
120
+ | StartDate | 2026-07-01 | lifescimarketableproduct.csv |
121
+ | Type | Product | lifescimarketableproduct.csv |
122
+
123
+ ## ProductTerritoryAvailability
124
+
125
+ | Field | Value | Source |
126
+ |-------|-------|--------|
127
+ | ProductId | (from Step 8 — LifeSciMarketableProduct) | FK |
128
+ | TerritoryId | (queried — level-3 territory) | FK |
129
+ | AlignmentType | Territory Inclusion | productterritoryavailability.csv |
130
+ | Purpose | Visit | productterritoryavailability.csv |
131
+ | Status | Draft | productterritoryavailability.csv |
132
+ | UsageType | LifeSciences | productterritoryavailability.csv |
133
+
134
+ ## Visit
135
+
136
+ | Field | Value | Source |
137
+ |-------|-------|--------|
138
+ | AccountId | (from Step 2) | FK |
139
+ | PlaceId | (from Step 4 — ContactPointAddress) | FK |
140
+ | PlannedVisitStartTime | NOW (generated at runtime) | requirement |
141
+ | Status | Planned | visit.csv |
142
+ | TerritoryId | (queried — level-3 territory) | FK |
143
+
144
+ ## ProviderVisit
145
+
146
+ | Field | Value | Source |
147
+ |-------|-------|--------|
148
+ | VisitId | (from Step 10) | FK |
149
+ | TerritoryName | (queried territory Name) | providervisit.csv |
150
+ | IsConfirmed | False | providervisit.csv |
151
+
152
+ ## ProviderVisitProdDetailing
153
+
154
+ | Field | Value | Source |
155
+ |-------|-------|--------|
156
+ | ProviderVisitId | (from Step 11) | FK |
157
+ | ProductId | (from Step 8 — LifeSciMarketableProduct) | FK |
158
+ | Priority | 4 | providervisitproddetailing.csv |
159
+ | AdditionalInformation | Discussed Oncology products and treatments | providervisitproddetailing.csv |
160
+ | IsGeneratedFromPresentation | False | providervisitproddetailing.csv |
161
+
162
+ ## ProviderVisitProdDiscussion
163
+
164
+ | Field | Value | Source |
165
+ |-------|-------|--------|
166
+ | ProviderVisitProductDtlId | (from Step 12) | FK |
167
+ | Note | Discussed Oncology treatments and patient care approaches | providervisitproddiscussion.csv |
168
+
169
+ ---
170
+
171
+ ## Manual iPad Mobile-App Validation (Step 16)
172
+
173
+ Final, **manual** step — a tester logs into the Life Sciences Cloud iPad app as the **rep** and confirms the Visit is visible.
174
+
175
+ - **App Store**: Life Sciences Cloud Mobile — <https://apps.apple.com/us/app/life-sciences-cloud-mobile/id6499238627>
176
+ - **Login**: open the app, log in with the rep credentials, wait for the initial sync (downloads org data + mobile metadata cache; 3-5 minutes on first login), then land on the Home page.
177
+ - **Navigate**: Home page → **Visits** tab (list of Visits) → tap the Visit name/row → Visit details.
178
+ - **Confirmation prompt**: "Do you see the Visit '00000001' for Account 'Dr. Aaron Morita' in the iPad app?" (substitute the actual Visit Name and Account Name from the run).
179
+
180
+ ### Troubleshooting (Visit not visible)
181
+
182
+ | Check | How to verify | Fix |
183
+ |---|---|---|
184
+ | Rep is assigned to the level-3 territory | `SELECT Id, Territory2.Name FROM UserTerritory2Association WHERE UserId = '<repUserId>'` | If missing, assign via Stage 4 (User Provisioning) |
185
+ | `ProviderAcctTerritoryInfo` exists for the Account + territory | `SELECT Id, AccountId, Territory2Id, IsActive FROM ProviderAcctTerritoryInfo WHERE AccountId = '<accountId>'` | If missing/inactive, (re)create Step 6 with `IsActive=true`, `IsAvailableOffline=true` |
186
+ | Mobile sync metadata cache available and current | `SELECT Id, Status, LastModifiedDate FROM LifeSciMobileMetadataRecord ORDER BY LastModifiedDate DESC` | Records must be `Status='Active'`; if not, re-run Steps 14–15, then re-sync on the iPad |
187
+
188
+ > Common root cause: the app synced **before** the territory assignment, `ProviderAcctTerritoryInfo`, or metadata cache existed. After fixing the data, have the tester **force a re-sync** (pull-to-refresh on the Visits list, or log out and back in), then re-ask the confirmation prompt.
189
+
190
+ ---
191
+
192
+ ## Dependency Chain
193
+
194
+ ```text
195
+ Account (Step 2)
196
+ ├── HealthcareProvider (Step 3) — AccountId
197
+ ├── ContactPointAddress (Step 4) — ParentId
198
+ ├── ObjectTerritory2Association (Step 5) — ObjectId
199
+ ├── ProviderAcctTerritoryInfo (Step 6) — AccountId, PreferredAddressId (Step 4)
200
+ └── Visit (Step 10) — AccountId, PlaceId (Step 4), TerritoryId
201
+
202
+ Product2 (Step 7)
203
+ └── LifeSciMarketableProduct (Step 8) — ProductId
204
+ └── ProductTerritoryAvailability (Step 9) — ProductId (Step 8)
205
+ └── ProviderVisitProdDetailing (Step 12) — ProductId (Step 8)
206
+
207
+ Visit (Step 10)
208
+ └── ProviderVisit (Step 11) — VisitId
209
+ └── ProviderVisitProdDetailing (Step 12) — ProviderVisitId
210
+ └── ProviderVisitProdDiscussion (Step 13) — ProviderVisitProductDtlId
211
+ ```
@@ -0,0 +1,108 @@
1
+ # Orchestration State Machine & Change Handling
2
+
3
+ Operational reference for `life-sciences-fieldsalesrep-coordinate`: the idempotent stage-transition rules, the mid-flow change-request impact assessment, and the resume/partial-re-run protocol. Read this alongside the workflow in `SKILL.md`.
4
+
5
+ ---
6
+
7
+ ## Idempotent Stage Transitions
8
+
9
+ Stages are **not re-entrant**. If the user says "Proceed" or names a stage that is already running or completed, do NOT re-execute it.
10
+
11
+ ### Behavior Matrix
12
+
13
+ | Current stage status | User says "Proceed" / "Run Stage N" | Response |
14
+ |---|---|---|
15
+ | `running` | Duplicate trigger | "Stage N is already in progress — I'll let you know when it completes." |
16
+ | `passed` | Re-run request | "Stage N already completed successfully. Would you like to re-run it anyway? This is safe (all stages are idempotent) but will take extra time." |
17
+ | `failed` | Retry request | Allow — re-run the stage (this is intentional recovery) |
18
+ | `pending` | Advance request | Allow — normal forward progression |
19
+
20
+ ### Implementation Rules
21
+
22
+ 1. **Before executing any stage**, check its current `status` in `OrchestrationState`.
23
+ 2. **If `running`**: reply with the in-progress message and take no action. Do not queue a second execution.
24
+ 3. **If `passed`**: ask for explicit confirmation before re-running. Only re-run if the user says "yes, re-run it".
25
+ 4. **If `failed`**: treat as a retry — re-run without extra confirmation (the user is explicitly recovering).
26
+ 5. **Accidental double-confirms** (user says "yes" or "proceed" twice in quick succession) must never cause a stage to execute twice. The `status` field is the single source of truth — transition to `running` at the START of execution, not on user input.
27
+
28
+ ---
29
+
30
+ ## Mid-Flow Change Requests (Impact Assessment)
31
+
32
+ If the user requests a change to inputs or decisions made in an earlier stage **while a later stage is in progress or pending**, perform an impact assessment before applying the change.
33
+
34
+ ### When This Applies
35
+
36
+ - User wants to change the target org mid-flow
37
+ - User wants to change territory names after territories were already deployed
38
+ - User wants to change the new user's details after the profile/permsets were chosen
39
+ - User wants to switch which layouts or flexipages were selected after deploy
40
+
41
+ ### Impact Assessment Protocol
42
+
43
+ 1. **Acknowledge the change request** without applying it immediately.
44
+
45
+ 2. **Identify affected stages** — determine which completed or in-progress stages would be impacted:
46
+
47
+ ```text
48
+ Change Request Impact Assessment
49
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
50
+
51
+ Requested change: <describe the change>
52
+
53
+ Stages affected:
54
+ Stage <N>: <StageName> — <what would need to change/redo>
55
+ Stage <M>: <StageName> — <downstream impact>
56
+
57
+ Stages NOT affected:
58
+ Stage <X>: <StageName> — no impact
59
+
60
+ Estimated rework: <time/effort to re-do affected stages>
61
+ ```
62
+
63
+ 3. **Present options** to the user:
64
+ - **Apply change and re-run affected stages** — will undo/redo the impacted work
65
+ - **Apply change for remaining stages only** — keep what's done, apply change going forward (if possible without inconsistency)
66
+ - **Cancel the change** — continue with original inputs
67
+
68
+ 4. **Wait for user decision** before taking any action.
69
+
70
+ ### Impact Mapping
71
+
72
+ | Change | Affects Stages | Re-run Required | Notes |
73
+ |--------|--------------|-----------------|-------|
74
+ | Target org | All stages | Yes — full restart | Nothing from prior org transfers |
75
+ | Territory names | Stage 3, Stage 4 | Stage 3 re-deploy + Stage 4 re-assign | Existing model may need new territories added |
76
+ | User details (name, email, username) | Stage 4, Stage 5 | Stage 4 + Stage 5 re-login | Stage 5 logs in as this rep; a new user means re-authenticating |
77
+ | Profile choice | Stage 4 only | Stage 4 only | Profile must exist (from Stage 2) |
78
+ | Layout/flexipage selection | Stage 2 only | Re-deploy updated profile + app | Does not affect Stages 3-4 |
79
+ | Permission set list | Stage 4 only | Stage 4 only | Can add/remove assignments |
80
+
81
+ ### Destructive Change Warnings
82
+
83
+ Some changes cannot be fully undone:
84
+
85
+ | Change | Warning |
86
+ |--------|---------|
87
+ | Territory model already activated | "The territory model cannot be deleted once activated. A new model with a different name can be created, but the old one will remain." |
88
+ | User already created | "The existing user will remain. A new user with different details will be created as a separate record." |
89
+ | Config records already deployed | "Config records are upsert-safe — re-deploying with changes will update existing records, not create duplicates." |
90
+
91
+ Always surface these warnings as part of the impact assessment so the user makes an informed decision.
92
+
93
+ ---
94
+
95
+ ## Resume / Partial Re-run
96
+
97
+ If the user has already completed some stages (e.g., from a prior session):
98
+
99
+ 1. Ask: "Have you already completed any of these stages?"
100
+ 2. For each claimed-complete stage, **verify** by querying the org:
101
+ - Stage 1: Ask user to confirm prerequisites are met
102
+ - Stage 2: Query for `LSC Custom Profile`
103
+ - Stage 3: Query for active territory model with level-3 territory
104
+ - Stage 4: Query for the user with correct profile and permsets
105
+ - Stage 5: Query for an existing `Visit` record (`SELECT Id FROM Visit LIMIT 1`)
106
+ 3. Skip verified stages and resume from the first incomplete one.
107
+
108
+ (The exact detection queries per stage are in `orchestration-flow.md` → Resume Logic.)