@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.
- package/package.json +1 -1
- package/skills/agentforce-observe/SKILL.md +32 -4
- package/skills/agentforce-observe/references/ahm-alerts.md +719 -0
- package/skills/automation-flow-generate/SKILL.md +11 -5
- package/skills/consumer-goods-promotion-bo-api-deploy/SKILL.md +275 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/README.md +32 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/SetCommentValue.cls +75 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/SetCommentValue.cls-meta.xml +5 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/interview-answers.json +13 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/copy.json +10 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/create.json +20 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/update.json +16 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/references/conventions-and-payload-rules.md +273 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/references/generate-and-wire.md +236 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/references/reference-example-set-comment-value.md +132 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/references/smoke-and-verify.md +211 -0
- package/skills/dx-code-analyzer-configure/scripts/validate-config.sh +14 -10
- package/skills/dx-code-analyzer-run/scripts/apply-fixes.js +45 -4
- package/skills/dx-code-analyzer-run/scripts/describe-rule.js +52 -32
- package/skills/dx-devops-project-manage/SKILL.md +197 -0
- package/skills/dx-devops-project-manage/examples/common-workflows.md +197 -0
- package/skills/dx-devops-project-manage/references/cli-commands.md +295 -0
- package/skills/dx-devops-project-manage/scripts/create-project.sh +48 -0
- package/skills/dx-devops-project-manage/scripts/list-projects.sh +51 -0
- package/skills/dx-devops-project-manage/scripts/update-project.sh +96 -0
- package/skills/education-cloud-academic-calendar-generate/SKILL.md +225 -0
- package/skills/education-cloud-academic-calendar-generate/examples/quarter-calendar.json +47 -0
- package/skills/education-cloud-academic-calendar-generate/examples/sample-output.md +57 -0
- package/skills/education-cloud-academic-calendar-generate/examples/semester-calendar.json +54 -0
- package/skills/education-cloud-academic-calendar-generate/references/calendar-systems.md +127 -0
- package/skills/education-cloud-academic-calendar-generate/references/date-validation.md +222 -0
- package/skills/education-cloud-academic-calendar-generate/references/foundation_prerequisites.md +40 -0
- package/skills/education-cloud-academic-calendar-generate/scripts/validate_calendar_dates.py +143 -0
- package/skills/education-cloud-course-catalog-migrate/SKILL.md +321 -0
- package/skills/education-cloud-course-catalog-migrate/references/gotchas-detail.md +16 -0
- package/skills/education-cloud-course-catalog-migrate/references/gotchas.md +16 -0
- package/skills/education-cloud-course-catalog-migrate/references/large-catalog-handling.md +42 -0
- package/skills/education-cloud-course-catalog-migrate/scripts/batch_courses.py +36 -0
- package/skills/education-cloud-course-catalog-migrate/scripts/detect_linked_courses.py +51 -0
- package/skills/education-cloud-course-catalog-migrate/scripts/detect_modality_variants.py +48 -0
- package/skills/education-cloud-course-catalog-migrate/scripts/resolve_api_version.py +43 -0
- package/skills/education-cloud-course-catalog-migrate/scripts/split_course_code.py +39 -0
- package/skills/education-cloud-course-catalog-migrate/scripts/validate_completeness.py +54 -0
- package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md +3 -5
- package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +177 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/agent-and-subagents.md +151 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/customer-narration.md +34 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/execution-model.md +54 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/flows.md +82 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/grounding.md +199 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/permissions.md +183 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/platform-enablement.md +82 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/prerequisites.md +158 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/routing.md +141 -0
- package/skills/experience-cms-brand-apply/SKILL.md +5 -5
- package/skills/experience-cms-brand-create/SKILL.md +2 -2
- package/skills/experience-cms-content-generate/SKILL.md +1 -0
- package/skills/experience-cms-content-render/SKILL.md +173 -0
- package/skills/experience-cms-content-render/assets/angular/DetailPage.component.ts +25 -0
- package/skills/experience-cms-content-render/assets/angular/MediaRenderer.component.ts +133 -0
- package/skills/experience-cms-content-render/assets/angular/TypeList.component.ts +38 -0
- package/skills/experience-cms-content-render/assets/angular/TypeRenderer.component.ts +90 -0
- package/skills/experience-cms-content-render/assets/angular/cms-content.component.ts +248 -0
- package/skills/experience-cms-content-render/assets/angular/cms-item.service.ts +100 -0
- package/skills/experience-cms-content-render/assets/react/DetailPage.tsx +20 -0
- package/skills/experience-cms-content-render/assets/react/MediaRenderer.tsx +129 -0
- package/skills/experience-cms-content-render/assets/react/TypeList.tsx +40 -0
- package/skills/experience-cms-content-render/assets/react/TypeRenderer.tsx +64 -0
- package/skills/experience-cms-content-render/assets/react/heuristicRenderer.tsx +310 -0
- package/skills/experience-cms-content-render/assets/react/useCmsItem.ts +129 -0
- package/skills/experience-cms-content-render/assets/shared/cmsContentType.ts +49 -0
- package/skills/experience-cms-content-render/assets/shared/cmsCore.types.ts +96 -0
- package/skills/experience-cms-content-render/assets/shared/externalRefs.ts +55 -0
- package/skills/experience-cms-content-render/references/bulk-loading.md +60 -0
- package/skills/experience-cms-content-render/references/codegen-guardrails.md +111 -0
- package/skills/experience-cms-content-render/references/detail-pages.md +87 -0
- package/skills/experience-cms-content-render/references/embed-recipes.md +127 -0
- package/skills/experience-cms-content-render/references/failure-modes.md +96 -0
- package/skills/experience-cms-content-render/references/heuristic-render-rules.md +131 -0
- package/skills/experience-cms-content-render/references/init-scaffold.md +122 -0
- package/skills/experience-cms-content-render/references/interaction-model.md +173 -0
- package/skills/experience-cms-content-render/references/package-api.md +106 -0
- package/skills/experience-cms-content-render/references/schema-sync.md +114 -0
- package/skills/experience-cms-content-render/references/styling-scopes.md +65 -0
- package/skills/experience-cms-content-render/references/verify.md +49 -0
- package/skills/experience-cms-content-type-generate/SKILL.md +2 -2
- package/skills/experience-content-media-stock-image-search/SKILL.md +5 -4
- package/skills/experience-search-coordinate/SKILL.md +198 -0
- package/skills/experience-search-coordinate/assets/search-payload-template.json +25 -0
- package/skills/experience-search-coordinate/references/content-route.md +313 -0
- package/skills/experience-search-coordinate/references/content-type-discovery.md +57 -0
- package/skills/experience-search-coordinate/references/media-route.md +172 -0
- package/skills/experience-search-coordinate/references/scope-resolution.md +14 -0
- package/skills/experience-ui-bundle-localize/SKILL.md +1 -1
- package/skills/experience-ui-bundle-localize/references/i18n-setup.md +5 -3
- package/skills/experience-ui-bundle-project-generate/SKILL.md +18 -14
- package/skills/experience-ui-bundle-project-generate/references/angular-project-generate.md +22 -0
- package/skills/experience-ui-bundle-project-generate/references/react-project-generate.md +20 -0
- package/skills/experience-ui-bundle-salesforce-data-access/SKILL.md +58 -54
- package/skills/experience-ui-bundle-salesforce-data-access/references/caching.md +6 -0
- package/skills/experience-ui-bundle-salesforce-data-access/references/graphiti-cli.md +2 -2
- package/skills/experience-ui-bundle-salesforce-data-access/references/migration.md +6 -0
- package/skills/experience-ui-bundle-salesforce-data-access/references/rest-and-integration.md +2 -1
- package/skills/experience-ui-bundle-salesforce-data-access/references/sdk-api.md +6 -0
- package/skills/experience-ui-bundle-site-generate/SKILL.md +59 -8
- package/skills/experience-ui-bundle-site-generate/references/configure-metadata-digital-experience.md +8 -3
- package/skills/experience-ui-bundle-site-generate/references/configure-metadata-language-settings.md +120 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +336 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +143 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-application-flexipage-mapping.md +127 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-deploy-commands.md +116 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-lifesci-metadata-deploy.md +111 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-overview.md +312 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-profile-layout-assignments.md +171 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-state-tracking.md +64 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-trigger-handlers.md +122 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-4-user-provisioning-overview.md +335 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-4-user-provisioning-user-provisioning-details.md +140 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-execution-state-and-recovery.md +196 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-metadata-cache-generation.md +155 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md +307 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-visit-creation-data.md +211 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/state-machine-and-changes.md +108 -0
- package/skills/life-sciences-kam-coordinate/SKILL.md +241 -0
- package/skills/life-sciences-kam-coordinate/references/orchestration-flow.md +152 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-application-flexipage-mapping.md +79 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-deploy-commands.md +131 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-kam-config-records.md +85 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-lifesci-metadata-deploy.md +112 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-overview.md +202 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-profile-layout-assignments.md +67 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-state-tracking.md +65 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-trigger-handlers.md +123 -0
- package/skills/life-sciences-kam-coordinate/references/stage-4-participant-role-and-sprint.md +89 -0
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +337 -0
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-creation-data.md +248 -0
- package/skills/life-sciences-kam-coordinate/references/stage-6-ipad-validation-script.md +35 -0
- package/skills/life-sciences-kam-coordinate/references/stage-6-metadata-cache-generation.md +155 -0
- package/skills/life-sciences-kam-coordinate/references/stage-6-user-provisioning-details.md +146 -0
- package/skills/life-sciences-kam-coordinate/references/stage-6-user-provisioning-overview.md +89 -0
- package/skills/life-sciences-kam-coordinate/references/state-machine-and-changes.md +114 -0
- package/skills/life-sciences-prerequisites-validate/SKILL.md +138 -0
- package/skills/life-sciences-prerequisites-validate/references/checks-org-settings.md +190 -0
- package/skills/life-sciences-prerequisites-validate/references/checks-user-and-package.md +211 -0
- package/skills/life-sciences-territory-configure/SKILL.md +217 -0
- package/skills/life-sciences-territory-configure/references/territory-metadata.md +262 -0
- package/skills/platform-apex-logs-debug/SKILL.md +7 -7
- package/skills/platform-custom-application-generate/SKILL.md +4 -4
- package/skills/platform-custom-object-generate/SKILL.md +7 -7
- package/skills/platform-custom-tab-generate/SKILL.md +1 -1
- package/skills/platform-dsar-policy-manage/SKILL.md +272 -0
- package/skills/platform-dsar-policy-manage/references/configure.md +106 -0
- package/skills/platform-dsar-policy-manage/references/export-and-history.md +123 -0
- package/skills/platform-dsar-policy-manage/references/gap-analysis-guide.md +150 -0
- package/skills/platform-dsar-policy-manage/references/gap-scan.md +129 -0
- package/skills/platform-dsar-policy-manage/references/headless-sor.md +59 -0
- package/skills/platform-dsar-policy-manage/references/report-format.md +59 -0
- package/skills/platform-dsar-policy-manage/scripts/tests/__init__.py +0 -0
- package/skills/platform-dsar-policy-manage/scripts/tests/test_validate_policy_tree.py +76 -0
- package/skills/platform-dsar-policy-manage/scripts/validate-policy-tree.py +130 -0
- package/skills/platform-flexipage-generate/SKILL.md +4 -0
- package/skills/platform-list-view-generate/SKILL.md +1 -0
- package/skills/platform-salesforce-connect-adapter-generate/SKILL.md +359 -0
- package/skills/platform-salesforce-connect-adapter-generate/references/official-examples.md +69 -0
- package/skills/platform-salesforce-connect-adapter-generate/references/scenarios.md +187 -0
- package/skills/platform-soql-query/SKILL.md +8 -8
- package/skills/platform-value-set-generate/SKILL.md +2 -2
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +20 -27
- package/skills/service-native-voice-recording-transcription-configure/SKILL.md +47 -27
- package/skills/service-native-voice-recording-transcription-configure/references/thunderbird-voice-settings.md +13 -9
- package/skills/service-native-voice-recording-transcription-configure/scripts/enable-recording-transcription.sh +104 -45
package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md
ADDED
|
@@ -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.)
|