@salesforce/afv-skills 1.47.0 → 1.48.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/education-cloud-domain-configure/SKILL.md +234 -0
- package/skills/education-cloud-domain-configure/references/dependent-features.md +198 -0
- package/skills/education-cloud-domain-configure/references/domain-features/academic-operations.md +386 -0
- package/skills/education-cloud-domain-configure/references/domain-features/alumni-relations.md +155 -0
- package/skills/education-cloud-domain-configure/references/domain-features/cross-domain-dependencies.md +18 -0
- package/skills/education-cloud-domain-configure/references/domain-features/industriessettings-toggle-reference.md +43 -0
- package/skills/education-cloud-domain-configure/references/domain-features/mentoring.md +198 -0
- package/skills/education-cloud-domain-configure/references/domain-features/recruitment-admissions.md +315 -0
- package/skills/education-cloud-domain-configure/references/domain-features/student-management.md +155 -0
- package/skills/education-cloud-domain-configure/references/domain-features/student-success.md +249 -0
- package/skills/education-cloud-domain-configure/references/domain-features.md +27 -0
- package/skills/education-cloud-domain-configure/references/gotchas-extended.md +23 -0
- package/skills/education-cloud-domain-configure/references/toggle-write-path.md +67 -0
- package/skills/education-cloud-domain-configure/scripts/check_license_provisioned.py +62 -0
- package/skills/education-cloud-domain-configure/scripts/check_org_edition.py +44 -0
- package/skills/education-cloud-domain-configure/scripts/check_permission_assigned.py +39 -0
- package/skills/education-cloud-multi-campus-configure/SKILL.md +7 -0
- package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md +4 -3
- package/skills/service-agentforce-channel-configure/SKILL.md +33 -28
- package/skills/service-agentforce-human-escalation-configure/SKILL.md +205 -0
- package/skills/service-agentforce-human-escalation-configure/assets/escalation-thresholds.instructions.md +37 -0
- package/skills/service-agentforce-human-escalation-configure/assets/force-app/main/default/flows/Human_Escalation_Outbound_Flow.flow-meta.xml +173 -0
- package/skills/service-agentforce-human-escalation-configure/assets/package.xml +8 -0
- package/skills/service-agentforce-human-escalation-configure/assets/sfdx-project.json +5 -0
- package/skills/service-agentforce-human-escalation-configure/references/classifier-contracts.md +103 -0
- package/skills/service-agentforce-human-escalation-configure/references/escalation-mechanism.md +63 -0
- package/skills/service-agentforce-human-escalation-configure/references/failure-policy.md +44 -0
- package/skills/service-agentforce-human-escalation-configure/references/nga-escalation.md +57 -0
- package/skills/service-agentforce-human-escalation-configure/references/runtime-verification.md +72 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/classify-agent-active.mjs +49 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/classify-nga-escalation.mjs +166 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/extract-outbound-route.mjs +67 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/patch-escalation-surfaces.mjs +131 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/tests/__init__.py +0 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/tests/_bootstrap.py +249 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/tests/test_escalation_contracts.py +899 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/verify-and-configure.sh +705 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/verify-escalation-config.mjs +89 -0
- package/skills/service-de-channel-routing-configure/SKILL.md +13 -5
- package/skills/service-de-channel-routing-configure/scripts/tests/test_skill_contract.py +25 -0
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +23 -10
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +63 -48
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +6 -2
- package/skills/service-omni-agent-users-create/SKILL.md +96 -0
- package/skills/service-omni-agent-users-create/assets/create-users.apex.template +80 -0
- package/skills/service-omni-agent-users-create/references/apex-patterns.md +135 -0
- package/skills/service-omni-agent-users-create/references/apex-template-notes.md +40 -0
- package/skills/service-omni-agent-users-create/scripts/detect-and-create.sh +206 -0
- package/skills/service-omni-agent-users-create/scripts/detect-existing.sh +122 -0
- package/skills/service-omni-agent-users-create/scripts/run-create.sh +298 -0
- package/skills/service-omni-agent-users-create/scripts/tests/test_user_create_security.py +171 -0
- package/skills/service-omni-agent-work-sharing-configure/SKILL.md +78 -0
- package/skills/service-omni-agent-work-sharing-configure/references/api-notes.md +31 -0
- package/skills/service-omni-agent-work-sharing-configure/scripts/configure-and-report.sh +186 -0
- package/skills/service-omni-agent-work-sharing-configure/scripts/tests/_bootstrap.py +120 -0
- package/skills/service-omni-agent-work-sharing-configure/scripts/tests/test_agent_work_sharing_contracts.py +93 -0
- package/skills/service-omni-base-settings-configure/SKILL.md +77 -0
- package/skills/service-omni-base-settings-configure/assets/force-app/main/default/settings/OmniChannel.settings-meta.xml +8 -0
- package/skills/service-omni-base-settings-configure/assets/package.xml +8 -0
- package/skills/service-omni-base-settings-configure/assets/sfdx-project.json +12 -0
- package/skills/service-omni-base-settings-configure/references/api-notes.md +121 -0
- package/skills/service-omni-base-settings-configure/scripts/configure-and-report.sh +164 -0
- package/skills/service-omni-base-settings-configure/scripts/detect-existing.sh +69 -0
- package/skills/service-omni-channel-setup-coordinate/SKILL.md +168 -0
- package/skills/service-omni-channel-setup-coordinate/examples/output-templates.md +161 -0
- package/skills/service-omni-channel-setup-coordinate/references/gap-catalog.md +99 -0
- package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +1542 -0
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/__init__.py +0 -0
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/_bootstrap.py +223 -0
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +804 -0
- package/skills/service-omni-command-center-analyze/SKILL.md +84 -0
- package/skills/service-omni-command-center-analyze/references/api-notes.md +54 -0
- package/skills/service-omni-command-center-analyze/scripts/analyze.sh +198 -0
- package/skills/service-omni-command-center-analyze/scripts/tests/_bootstrap.py +115 -0
- package/skills/service-omni-command-center-analyze/scripts/tests/test_command_center_analyze_contracts.py +165 -0
- package/skills/service-omni-permission-set-assign/SKILL.md +88 -0
- package/skills/service-omni-permission-set-assign/assets/package.xml +8 -0
- package/skills/service-omni-permission-set-assign/references/api-notes.md +143 -0
- package/skills/service-omni-permission-set-assign/scripts/verify-and-assign.sh +397 -0
- package/skills/service-omni-presence-status-deploy/SKILL.md +87 -0
- package/skills/service-omni-presence-status-deploy/assets/package.xml +12 -0
- package/skills/service-omni-presence-status-deploy/references/api-notes.md +115 -0
- package/skills/service-omni-presence-status-deploy/scripts/deploy-and-report.sh +422 -0
- package/skills/service-omni-presence-user-config-deploy/SKILL.md +80 -0
- package/skills/service-omni-presence-user-config-deploy/references/api-notes.md +60 -0
- package/skills/service-omni-presence-user-config-deploy/scripts/deploy-and-report.sh +261 -0
- package/skills/service-omni-presence-user-config-deploy/scripts/tests/_bootstrap.py +106 -0
- package/skills/service-omni-presence-user-config-deploy/scripts/tests/test_presence_user_config_contracts.py +142 -0
- package/skills/service-omni-queue-deploy/SKILL.md +91 -0
- package/skills/service-omni-queue-deploy/references/api-notes.md +140 -0
- package/skills/service-omni-queue-deploy/scripts/verify-and-align.sh +470 -0
- package/skills/service-omni-queue-members-assign/SKILL.md +93 -0
- package/skills/service-omni-queue-members-assign/references/api-notes.md +144 -0
- package/skills/service-omni-queue-members-assign/scripts/tests/_bootstrap.py +67 -0
- package/skills/service-omni-queue-members-assign/scripts/tests/test_queue_members_contracts.py +73 -0
- package/skills/service-omni-queue-members-assign/scripts/verify-and-bind.sh +362 -0
- package/skills/service-omni-queue-routing-config-deploy/SKILL.md +101 -0
- package/skills/service-omni-queue-routing-config-deploy/references/api-notes.md +127 -0
- package/skills/service-omni-queue-routing-config-deploy/scripts/tests/_bootstrap.py +90 -0
- package/skills/service-omni-queue-routing-config-deploy/scripts/tests/test_queue_routing_config_contracts.py +70 -0
- package/skills/service-omni-queue-routing-config-deploy/scripts/upsert-and-report.sh +538 -0
- package/skills/service-omni-routing-flow-deploy/SKILL.md +111 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Case_Trigger.SkillsBased.flow-meta.xml +94 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Case_Trigger.flow-meta.xml +88 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Cases.flow-meta.xml +144 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCall_Trigger.SkillsBased.flow-meta.xml +94 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCall_Trigger.flow-meta.xml +88 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCalls.flow-meta.xml +144 -0
- package/skills/service-omni-routing-flow-deploy/assets/package.xml +11 -0
- package/skills/service-omni-routing-flow-deploy/assets/sfdx-project.json +11 -0
- package/skills/service-omni-routing-flow-deploy/references/api-notes.md +265 -0
- package/skills/service-omni-routing-flow-deploy/scripts/deploy-and-report.sh +684 -0
- package/skills/service-omni-service-channel-configure/SKILL.md +83 -0
- package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/Cases.serviceChannel-meta.xml +9 -0
- package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/Incidents.serviceChannel-meta.xml +9 -0
- package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/MessagingSessions.serviceChannel-meta.xml +9 -0
- package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/VoiceCalls.serviceChannel-meta.xml +9 -0
- package/skills/service-omni-service-channel-configure/assets/package.xml +11 -0
- package/skills/service-omni-service-channel-configure/assets/sfdx-project.json +12 -0
- package/skills/service-omni-service-channel-configure/references/api-notes.md +84 -0
- package/skills/service-omni-service-channel-configure/scripts/deploy-and-report.sh +383 -0
- package/skills/service-omni-sidebar-configure/SKILL.md +77 -0
- package/skills/service-omni-sidebar-configure/references/api-notes.md +51 -0
- package/skills/service-omni-sidebar-configure/scripts/enable-and-report.sh +315 -0
- package/skills/service-omni-sidebar-configure/scripts/tests/_bootstrap.py +142 -0
- package/skills/service-omni-sidebar-configure/scripts/tests/test_sidebar_contracts.py +139 -0
- package/skills/service-omni-skills-based-routing-configure/SKILL.md +81 -0
- package/skills/service-omni-skills-based-routing-configure/references/api-notes.md +50 -0
- package/skills/service-omni-skills-based-routing-configure/scripts/configure-and-report.sh +270 -0
- package/skills/service-omni-skills-based-routing-configure/scripts/tests/_bootstrap.py +120 -0
- package/skills/service-omni-skills-based-routing-configure/scripts/tests/test_sbr_contracts.py +129 -0
- package/skills/service-omni-supervisor-config-deploy/SKILL.md +97 -0
- package/skills/service-omni-supervisor-config-deploy/assets/force-app/main/default/omniSupervisorConfigs/Omni_Supervisor.omniSupervisorConfig-meta.xml +9 -0
- package/skills/service-omni-supervisor-config-deploy/assets/package.xml +8 -0
- package/skills/service-omni-supervisor-config-deploy/assets/sfdx-project.json +12 -0
- package/skills/service-omni-supervisor-config-deploy/references/api-notes.md +205 -0
- package/skills/service-omni-supervisor-config-deploy/scripts/deploy-and-report.sh +586 -0
- package/skills/service-omni-supervisor-config-deploy/scripts/tests/_bootstrap.py +153 -0
- package/skills/service-omni-supervisor-config-deploy/scripts/tests/test_supervisor_config_contracts.py +116 -0
- package/skills/service-omni-supervisor-permset-assign/SKILL.md +88 -0
- package/skills/service-omni-supervisor-permset-assign/references/api-notes.md +48 -0
- package/skills/service-omni-supervisor-permset-assign/scripts/verify-and-assign.sh +316 -0
- package/skills/service-omni-supervisor-surface-deploy/SKILL.md +85 -0
- package/skills/service-omni-supervisor-surface-deploy/references/api-notes.md +47 -0
- package/skills/service-omni-supervisor-surface-deploy/scripts/deploy-and-report.sh +216 -0
- package/skills/service-omni-supervisor-surface-deploy/scripts/tests/_bootstrap.py +95 -0
- package/skills/service-omni-supervisor-surface-deploy/scripts/tests/test_supervisor_surface_contracts.py +154 -0
- package/skills/service-omni-supervisor-users-create/SKILL.md +92 -0
- package/skills/service-omni-supervisor-users-create/assets/create-supervisors.apex.template +72 -0
- package/skills/service-omni-supervisor-users-create/references/apex-patterns.md +73 -0
- package/skills/service-omni-supervisor-users-create/references/apex-template-notes.md +41 -0
- package/skills/service-omni-supervisor-users-create/scripts/detect-and-create.sh +197 -0
- package/skills/service-omni-supervisor-users-create/scripts/detect-existing.sh +112 -0
- package/skills/service-omni-supervisor-users-create/scripts/run-create.sh +296 -0
- package/skills/service-omni-work-skill-routing-configure/SKILL.md +80 -0
- package/skills/service-omni-work-skill-routing-configure/references/api-notes.md +67 -0
- package/skills/service-omni-work-skill-routing-configure/scripts/configure-and-report.sh +262 -0
- package/skills/service-omni-work-skill-routing-configure/scripts/tests/_bootstrap.py +121 -0
- package/skills/service-omni-work-skill-routing-configure/scripts/tests/test_work_skill_routing_contracts.py +161 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# 1. Student Success
|
|
2
|
+
|
|
3
|
+
**Purpose**: Track student advising, success interventions, care plans, and wellness support.
|
|
4
|
+
|
|
5
|
+
**Prerequisites**:
|
|
6
|
+
- All Foundation prerequisites (Section 0)
|
|
7
|
+
- Cases enabled — advising uses case-based workflows
|
|
8
|
+
- Salesforce Scheduler — for advising appointment booking
|
|
9
|
+
- Experience Cloud license — for Learner Portal (student-facing)
|
|
10
|
+
- OmniStudio — for portal components and guided experiences
|
|
11
|
+
- CRM Analytics / Education Analytics — for Advisor Insights and KPI dashboards (optional)
|
|
12
|
+
- Einstein Generative AI — for Einstein Advising Summary (optional)
|
|
13
|
+
|
|
14
|
+
**Core features**:
|
|
15
|
+
- Student records (Person Accounts)
|
|
16
|
+
- Advising case management
|
|
17
|
+
- Success teams for collaborative support
|
|
18
|
+
- Care plans to track interventions
|
|
19
|
+
- Alerts and notifications
|
|
20
|
+
- Salesforce Scheduler for appointment booking
|
|
21
|
+
|
|
22
|
+
### Sub-Feature Configuration
|
|
23
|
+
|
|
24
|
+
> **Executed order (from Student Success testing):** Support Process → Case Record Types → Success Teams (create `CaseTeamTemplate` first) → Care Plans → Support Programs → Salesforce Scheduler. Do Care Plans AFTER Success Teams and Support Programs BEFORE Scheduler.
|
|
25
|
+
|
|
26
|
+
> **License-gating on Care Plans / Support Programs / Scheduler writes.** These three toggle writes can return `400 INSUFFICIENT_ACCESS_OR_READONLY` (nothing written) on an under-licensed org — confirmed on a test org where the identical write failed on day 1 and succeeded (`success:true`) on day 2 after the org was given more licenses, with no skill/API change in between. Treat this error as **"check licensing on this org first,"** not as a fixed product limitation — retry after the admin confirms licensing rather than concluding the feature is unreachable via API.
|
|
27
|
+
|
|
28
|
+
> **`IndustriesSettings` tooling GET cold-verify can 500 org-wide.** `GET /services/data/v68.0/tooling/sobjects/IndustriesSettings/<DurableId>` has been observed returning HTTP 500 `UNKNOWN_EXCEPTION` on every value read (any field, any API version) in at least one org, root-caused to a null UDD `LogicalFieldDefinition` on one preference column in that org's data — an org-data defect, not a skill or transport bug (`describe` and `SELECT Id, DurableId` still return 200; only value reads fail). If this GET 500s on 3 consecutive attempts, stop retrying the API path and ask the admin to confirm the toggle's ON state in Setup UI instead — record that the write's `success:true` was confirmed via Setup UI, not cold-verified via API, and say so explicitly in any summary.
|
|
29
|
+
|
|
30
|
+
#### Step 1 — Create Support Process
|
|
31
|
+
|
|
32
|
+
**What it does**: Creates a Support Process named "Student Advising" to organize case statuses. Used as the `businessProcess` on the case record types in Step 2.
|
|
33
|
+
|
|
34
|
+
**API approach** (works — try first):
|
|
35
|
+
```bash
|
|
36
|
+
POST /services/data/v68.0/sobjects/BusinessProcess
|
|
37
|
+
{"Name":"Student Advising","TableEnumOrId":"Case","Description":"Advising case support process"}
|
|
38
|
+
```
|
|
39
|
+
Do **NOT** send `IsActive` on insert — it is `INVALID_FIELD_FOR_INSERT_UPDATE`. The BusinessProcess is active by default. Capture the returned `Id` and the `Name` ("Student Advising") — Step 2 references the process by **Name**, not Id.
|
|
40
|
+
|
|
41
|
+
**Setup path** (UI fallback):
|
|
42
|
+
1. Navigate to Setup → Quick Find → "Support Processes" → Click New
|
|
43
|
+
2. For "Existing Support Process", select Master
|
|
44
|
+
3. Enter support process name: "Student Advising"
|
|
45
|
+
4. Click Save; leave Case Status as default, click Save again
|
|
46
|
+
|
|
47
|
+
**Verification** (read back by the Id captured at creation — a SOQL `SELECT Id FROM <Object> WHERE ...` via `queryParams` also works if you need to re-find the record later):
|
|
48
|
+
```http
|
|
49
|
+
GET /services/data/v68.0/sobjects/BusinessProcess/<id-captured-from-create-response>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
#### Step 2 — Create Advising Case Record Types
|
|
55
|
+
|
|
56
|
+
**What it does**: Creates specialized case record types for different advising scenarios.
|
|
57
|
+
|
|
58
|
+
**API approach** (works — try first). Use the Tooling `RecordType` with the `FullName` + `Metadata` shape (NOT flat columns). `businessProcess` = the BusinessProcess **Name** from Step 1, not its Id:
|
|
59
|
+
```http
|
|
60
|
+
POST /services/data/v68.0/tooling/sobjects/RecordType
|
|
61
|
+
{"FullName":"Case.Academic","Metadata":{"label":"Academic","active":true,"businessProcess":"Student Advising","description":"Academic advising cases"}}
|
|
62
|
+
```
|
|
63
|
+
Repeat with `FullName` `Case.Health`, `Case.Wellbeing` (and `Case.FinancialAid` if used), changing `label`.
|
|
64
|
+
|
|
65
|
+
**Profile permissions (record type visibility) are NOT applied via this API** — the record type is created but not assigned to any profile. Assigning it to profiles is a separate step (Setup → Profiles → Record Type Settings, or a `Profile` metadata deploy).
|
|
66
|
+
|
|
67
|
+
**Setup path** (UI fallback):
|
|
68
|
+
1. Setup → Quick Find → "Set Up Education Cloud" → Set Up Education Cloud → under "Create Advising Case Record Types" click "Create Case Record Types"
|
|
69
|
+
2. On Case Record Types → New; for "Existing Record Type" select Master
|
|
70
|
+
3. Enter label (e.g., "Academic"), Tab to auto-populate name
|
|
71
|
+
4. For "Support Process" select "Student Advising"; select Active
|
|
72
|
+
5. Select profile permissions → Next → Save
|
|
73
|
+
6. Repeat for Health, Wellbeing (and optional Financial Aid)
|
|
74
|
+
|
|
75
|
+
**Verification** (RecordType is a tooling object — use `/tooling/sobjects` for GET-by-Id, or `/tooling/query` via `queryParams` for a SOQL lookup):
|
|
76
|
+
```http
|
|
77
|
+
GET /services/data/v68.0/tooling/sobjects/RecordType/<id-captured-from-create-response>
|
|
78
|
+
```
|
|
79
|
+
Repeat per record type created (Academic, Health, Wellbeing, and FinancialAid if used), using each one's Id from its own create response.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
#### Step 3 — Set Up Success Teams
|
|
84
|
+
|
|
85
|
+
**What it does**: Creates success teams for collaborative case management, keyed to a case record type.
|
|
86
|
+
|
|
87
|
+
**PREREQUISITE** — a `CaseTeamTemplate` must exist first; `SuccessTeam` references it by **Name** via `DefaultUnassignedCaseTeam`. Check existence first with `GET /services/data/v68.0/query` and `queryParams: {"q": "SELECT Id FROM CaseTeamTemplate WHERE Name='<name>'"}`; if none found, create directly and read back by the Id captured at creation:
|
|
88
|
+
```http
|
|
89
|
+
POST /services/data/v68.0/sobjects/CaseTeamTemplate
|
|
90
|
+
{"Name":"Advising Team","Description":"Default advising success team"}
|
|
91
|
+
```
|
|
92
|
+
```http
|
|
93
|
+
GET /services/data/v68.0/sobjects/CaseTeamTemplate/<id-captured-from-create-response>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Create the Success Team** (`IsActive` IS writable here, unlike BusinessProcess). `CaseRecordTypeId` = the RecordType Id from Step 2; `DefaultUnassignedCaseTeam` = the CaseTeamTemplate **Name**:
|
|
97
|
+
```http
|
|
98
|
+
POST /services/data/v68.0/sobjects/SuccessTeam
|
|
99
|
+
{"Name":"Academic Success Team","CaseRecordTypeId":"<Academic RecordType Id>","DefaultUnassignedCaseTeam":"Advising Team","IsActive":true}
|
|
100
|
+
```
|
|
101
|
+
Repeat per case record type (Wellbeing, Health).
|
|
102
|
+
|
|
103
|
+
**Setup path** (UI fallback): Student Success app → Success Teams tab → New → name, select case record type, select/create case team → Save.
|
|
104
|
+
|
|
105
|
+
**Verification** (read back each by the Id captured at creation — a SOQL `SELECT Id FROM <Object> WHERE ...` via `queryParams` also works if you need to re-find records later):
|
|
106
|
+
```http
|
|
107
|
+
GET /services/data/v68.0/sobjects/SuccessTeam/<id-captured-from-create-response>
|
|
108
|
+
```
|
|
109
|
+
Repeat per case record type's Success Team created above.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
#### Step 4 — Enable Care Plans (after Success Teams)
|
|
114
|
+
|
|
115
|
+
**What it does**: Enables care plans to track intervention plans, goals, and progress for at-risk students.
|
|
116
|
+
|
|
117
|
+
**Write approach** (works — `IndustriesSettings` toggle). **IRREVERSIBLE.** Element is **`enableCarePlansPreference`** — do NOT use `enableCarePlans` (→ `FIELD_INTEGRITY_EXCEPTION`). Use the SKILL.md **Domain & Feature Toggle Write Path**:
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"type": "IndustriesSettings",
|
|
121
|
+
"fullName": "Industries",
|
|
122
|
+
"xmlRep": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><IndustriesSettings xmlns=\"http://soap.sforce.com/2006/04/metadata\"><enableCarePlansPreference>true</enableCarePlansPreference></IndustriesSettings>"
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
Do NOT use `setup/org/preferences/{name}` (404).
|
|
126
|
+
|
|
127
|
+
**Verification** (cold read — `success:true` alone unreliable): tooling GET `IndustriesSettings` by DurableId `bWRjLzBIRS9JbmR1c3RyaWVzU2V0dGluZ3M=` and confirm `.Metadata.enableCarePlansPreference` / flat `IsCarePlansPreferenceEnabled` is `true`. If the GET 500s, fall back to a Setup UI confirmation (see license-gating/cold-verify note above) rather than reporting unverified.
|
|
128
|
+
|
|
129
|
+
If the write itself 400s `INSUFFICIENT_ACCESS_OR_READONLY`, this is likely license-gated on this org — see note above.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
#### Step 5 — Enable Support Programs (before Scheduler)
|
|
134
|
+
|
|
135
|
+
**What it does**: Enables benefit/program management used by Student Success programs. Four toggles flip in a **single** metadata PUT.
|
|
136
|
+
|
|
137
|
+
**Write approach** (works — `IndustriesSettings` toggles). **IRREVERSIBLE.** One PUT with all four elements:
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"type": "IndustriesSettings",
|
|
141
|
+
"fullName": "Industries",
|
|
142
|
+
"xmlRep": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><IndustriesSettings xmlns=\"http://soap.sforce.com/2006/04/metadata\"><enableBenefitManagementPreference>true</enableBenefitManagementPreference><enableBenefitAndGoalSharingPref>true</enableBenefitAndGoalSharingPref><allowBenefitAssignmentWithInactiveProgramEnrollment>true</allowBenefitAssignmentWithInactiveProgramEnrollment><enableProgramCohorts>true</enableProgramCohorts></IndustriesSettings>"
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Verification** (cold read): tooling GET by DurableId; confirm `.Metadata.enableBenefitManagementPreference`, `enableBenefitAndGoalSharingPref`, `allowBenefitAssignmentWithInactiveProgramEnrollment`, and `enableProgramCohorts` are all `true`. If the GET 500s, fall back to Setup UI confirmation (see license-gating/cold-verify note above).
|
|
147
|
+
|
|
148
|
+
If the write itself 400s `INSUFFICIENT_ACCESS_OR_READONLY`, this is likely license-gated on this org — see note above.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
#### Step 6 — Enable Salesforce Scheduler (partial — for advising appointments)
|
|
153
|
+
|
|
154
|
+
**What it does**: Enables Salesforce Scheduler for students to book advising appointments. **Partially API-writable** — two org prefs flip via metadata PUT; the master enable + a couple settings are manual/UI only.
|
|
155
|
+
|
|
156
|
+
**API-writable** (`IndustriesSettings` toggles — one PUT):
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"type": "IndustriesSettings",
|
|
160
|
+
"fullName": "Industries",
|
|
161
|
+
"xmlRep": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><IndustriesSettings xmlns=\"http://soap.sforce.com/2006/04/metadata\"><enableEventManagementOrgPref>true</enableEventManagementOrgPref><enableShareSaWithArOrgPref>true</enableShareSaWithArOrgPref></IndustriesSettings>"
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
Cold-verify `enableEventManagementOrgPref` and `enableShareSaWithArOrgPref` are `true`. If the cold-verify GET 500s, fall back to Setup UI confirmation (see license-gating/cold-verify note above); if the write 400s `INSUFFICIENT_ACCESS_OR_READONLY`, check licensing on this org before concluding the toggle is unreachable via API.
|
|
165
|
+
|
|
166
|
+
**Manual / UI only** (NOT API-writable):
|
|
167
|
+
- **Scheduler master enable** — license-gated (Field Service). Setup → Quick Find → "Salesforce Scheduler Settings" → turn on Salesforce Scheduler. If no license, enablement fails.
|
|
168
|
+
- **Multiple Topics for Shifts** — skip (has its own prerequisites; not needed for advising).
|
|
169
|
+
- **Schedule Appointments Using Engagement Channels** — enable manually in Salesforce Scheduler Settings.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
#### Step 7 — Set Up the Advisor Console
|
|
174
|
+
|
|
175
|
+
**What it does**: Configures the Advisor Console app with care plans, alerts, success teams, and appointment scheduler components.
|
|
176
|
+
|
|
177
|
+
**Setup path**:
|
|
178
|
+
1. Navigate to Setup → App Manager → Find "Advisor Console"
|
|
179
|
+
2. Click Edit
|
|
180
|
+
3. Assign page layouts and record types to advisor profiles
|
|
181
|
+
4. Add relevant components to app:
|
|
182
|
+
- Care Plans
|
|
183
|
+
- Alerts
|
|
184
|
+
- Success Teams
|
|
185
|
+
- Appointment Scheduler
|
|
186
|
+
- Student 360 view
|
|
187
|
+
5. Save and assign to advisor user profiles
|
|
188
|
+
|
|
189
|
+
**Verification**: Check App Launcher shows Advisor Console for advisor users.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
#### Step 8 — Set Up the Director Console (Student Success)
|
|
194
|
+
|
|
195
|
+
**What it does**: Configures the Director Console with KPI components for directors.
|
|
196
|
+
|
|
197
|
+
**Setup path**:
|
|
198
|
+
1. Navigate to Setup → App Manager → Find "Director Console"
|
|
199
|
+
2. Click Edit
|
|
200
|
+
3. Configure visibility and KPI components for directors:
|
|
201
|
+
- Student Success KPIs
|
|
202
|
+
- Advisor performance metrics
|
|
203
|
+
- Care plan pipeline
|
|
204
|
+
4. Save and assign to director user profiles
|
|
205
|
+
|
|
206
|
+
**Verification**: Check App Launcher shows Director Console for director users.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
#### Step 9 — Configure Performance Alerts
|
|
211
|
+
|
|
212
|
+
**What it does**: Configures alert types (attendance, grades, concerns) and maps them to Success Teams.
|
|
213
|
+
|
|
214
|
+
**Setup path**:
|
|
215
|
+
1. Navigate to Student Success app → Alert Settings tab
|
|
216
|
+
2. Configure alert types:
|
|
217
|
+
- Attendance alerts (threshold: < 80%)
|
|
218
|
+
- Grade alerts (threshold: < C average)
|
|
219
|
+
- Concern alerts (flagged by faculty)
|
|
220
|
+
3. Map alerts to Success Teams and case record types
|
|
221
|
+
4. Optionally connect to Care Plans via "Apply Care Plans to Alerts" feature
|
|
222
|
+
5. Save
|
|
223
|
+
|
|
224
|
+
**Verification**: Check Alert Settings show configured alert types.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
#### Step 10 — Set Up the Learner Portal (Experience Cloud)
|
|
229
|
+
|
|
230
|
+
**What it does**: Deploys student-facing portal with Action Center, Pulse Checks, Career Planning, Degree Planning.
|
|
231
|
+
|
|
232
|
+
**Prerequisites**: Experience Cloud license required.
|
|
233
|
+
|
|
234
|
+
**Setup path**:
|
|
235
|
+
1. Navigate to Setup → Digital Experiences → All Sites
|
|
236
|
+
2. Create new Experience Cloud site or configure existing site
|
|
237
|
+
3. Add Student Success components:
|
|
238
|
+
- Action Center (tasks, alerts)
|
|
239
|
+
- Pulse Checks (wellness check-ins)
|
|
240
|
+
- Career Planning
|
|
241
|
+
- Degree Planning
|
|
242
|
+
- Appointment booking
|
|
243
|
+
4. Configure access for authenticated students
|
|
244
|
+
5. Publish and activate the portal
|
|
245
|
+
|
|
246
|
+
**Verification**: Navigate to portal URL and verify components load for student users.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Education Cloud Domain Features — Complete Setup Guide
|
|
2
|
+
|
|
3
|
+
Configuration guide for each Education Cloud domain and its sub-features. Based on Salesforce Help Articles. Each domain's full setup steps live in its own reference file under `domain-features/` — open the one matching the domain being configured.
|
|
4
|
+
|
|
5
|
+
## Domain Reference Files
|
|
6
|
+
|
|
7
|
+
| Domain | File |
|
|
8
|
+
|--------|------|
|
|
9
|
+
| 1. Student Success | [domain-features/student-success.md](domain-features/student-success.md) |
|
|
10
|
+
| 2. Recruitment & Admissions | [domain-features/recruitment-admissions.md](domain-features/recruitment-admissions.md) |
|
|
11
|
+
| 3. Academic Operations | [domain-features/academic-operations.md](domain-features/academic-operations.md) |
|
|
12
|
+
| 4. Alumni Relations | [domain-features/alumni-relations.md](domain-features/alumni-relations.md) |
|
|
13
|
+
| 5. Student Management | [domain-features/student-management.md](domain-features/student-management.md) |
|
|
14
|
+
| 6. Mentoring | [domain-features/mentoring.md](domain-features/mentoring.md) |
|
|
15
|
+
| Cross-Domain Dependencies | [domain-features/cross-domain-dependencies.md](domain-features/cross-domain-dependencies.md) |
|
|
16
|
+
| IndustriesSettings Toggle Fields — Quick Reference | [domain-features/industriessettings-toggle-reference.md](domain-features/industriessettings-toggle-reference.md) |
|
|
17
|
+
|
|
18
|
+
## General Notes
|
|
19
|
+
|
|
20
|
+
- All domains require Education Cloud Foundation and Person Accounts enabled first
|
|
21
|
+
- Some sub-features require additional licenses (Field Service for Scheduler, Fundraising for gift management, Experience Cloud for portals)
|
|
22
|
+
- Object names may vary by Education Cloud version — check API version compatibility
|
|
23
|
+
- Verification queries may fail if objects are not yet provisioned (async provisioning) — wait 2-3 minutes and retry
|
|
24
|
+
- Setup menu paths may change with Salesforce UI updates — if path not found, search Setup for the feature name
|
|
25
|
+
- Write domain/feature toggles via the headless metadata PUT path (IndustriesSettings `xmlRep`, write `dispatch` tool); never `setup/org/preferences/{name}` (404). Fall back to UI instructions only on error
|
|
26
|
+
- EDU toggles are IRREVERSIBLE (`false → true` only) — warn the user, never promise a revert
|
|
27
|
+
- Student Management has no separate domain toggle — it is enabled when Academic Operations is configured with student enrollment records
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Additional Gotchas
|
|
2
|
+
|
|
3
|
+
Lower-frequency gotchas and toggle-write failure classes, split out of `SKILL.md`'s Gotchas table (kept to the 10 highest-impact entries). Read this when the top-10 table doesn't cover the error you're seeing.
|
|
4
|
+
|
|
5
|
+
| Issue | Resolution |
|
|
6
|
+
|-------|------------|
|
|
7
|
+
| Org edition not Enterprise+ | Education Cloud requires Enterprise, Performance, Unlimited, or Developer Edition — cannot install on lower editions |
|
|
8
|
+
| Some sub-features require additional licenses | If enablement fails with license error, inform user of required license (e.g., Salesforce Scheduler requires Field Service, Fundraising requires Advancement license, Experience Cloud license for portals) |
|
|
9
|
+
| Student Management has no separate domain toggle | Student Management is enabled when Academic Operations is configured with student enrollment records |
|
|
10
|
+
| Record creation (Business Process, Learning Programs) must be done manually or via API | Education Cloud does not auto-create these records — user must create via Setup, Data API, or Tooling API after domain is enabled |
|
|
11
|
+
| OmniStudio components must be activated separately | After OmniStudio is enabled, individual OmniScripts and FlexCards (Application Stages, Course Search, Matching Assessments) must be activated in Setup → OmniStudio |
|
|
12
|
+
| Experience Cloud portals require separate configuration | After domain is enabled, portals (Learner Portal, Applicant Portal, Alumni Portal, Mentoring Portal) must be created/configured in Experience Builder with domain-specific components |
|
|
13
|
+
| Sub-feature configuration steps vary significantly by domain | Always read the domain's file under `references/domain-features/` for domain-specific setup paths — Student Success, Recruitment & Admissions, and Academic Operations have 10+ sub-feature steps each |
|
|
14
|
+
| Verification queries may fail if objects not yet provisioned | Some domains provision objects asynchronously — retry after 2-3 minutes if query fails with "invalid object" error |
|
|
15
|
+
| `SELECT IsPersonAccountEnabled FROM Organization` returns `INVALID_FIELD` | No such column on `Organization` — verify Person Accounts via `Account/describe` (API, headless first) and check for `IsPersonAccount`/`Person*` fields, or `sf sobject describe -s Account` as fallback |
|
|
16
|
+
| Profile permissions on newly created RecordTypes (including LearningAchievement types) are NOT settable via API | Record type creates successfully but has no profile visibility — flag as a manual follow-up step (Setup → Profiles → Record Type Settings, or a `Profile` metadata deploy) |
|
|
17
|
+
| SOAP `updateMetadata` / `metadata/deployRequest` return `ROUTE_NOT_FOUND` | Blocked through the gateway — do NOT use; the headless metadata PUT is the supported write path (see "Endpoints that DO NOT work" in `SKILL.md`) |
|
|
18
|
+
| **Failure class — Aura-only, no MDAPI/Tooling/REST route at all** (e.g. Industries Cloud Common Decision Tables Access, `BREDecisionTableAccess`) | Backing call is an internal Aura action with no external route — manual UI only, do not keep probing endpoints |
|
|
19
|
+
| **Failure class — API write blocked at field level** (e.g. Intelligent Question Generation, `enableSmartAsmtQstnGeneration`) | Field exists and name is correct, but write returns `INSUFFICIENT_ACCESS_OR_READONLY: "cannot be accessed using the API"` — manual UI only |
|
|
20
|
+
| **Failure class — hard reject on disable-only** (e.g. Discovery Framework, `enableIndustriesAssessment`) | `true→false` returns HTTP 500 `UNKNOWN_EXCEPTION`; this is separate from the general one-way irreversibility — the enable (`false→true`) direction is untested where the field was already `true` |
|
|
21
|
+
| **Failure class — settings type invisible to Tooling/EntityDefinition but still MDAPI-writable** (e.g. Omnistudio Metadata, `OmniStudioSettings`, `fullName: OmniStudio`) | Metadata PUT write succeeds, but no GET/verify path exists via Tooling API — UI-confirmed only; if you encounter one of these, note it as write-succeeds-zero-verify-path rather than assuming failure |
|
|
22
|
+
| **Failure class — type-level UPDATE block** (e.g. Timeline `TimelineSettings`, Video Calls `VideoCallsSettings`) | PUT returns HTTP 400 `UNSUPPORTED_OPERATION: "MetadataCrud does not support UPDATE on type: X"` — block is on the whole type, no `fullName` variant fixes it; manual UI only |
|
|
23
|
+
| **Pattern — org preference API, not `IndustriesSettings`** (confirmed on Einstein Generative AI, `EinsteinGPTCopilotEnabled`) | Some toggles are Setup-Connect org preferences, not `IndustriesSettings` metadata fields — no `type`/`fullName`/`xmlRep`. Shape: `GET /services/data/v68.0/setup/org/preferences/<PrefName>` → `{"isPreferenceEnabled": bool}`; `PATCH` same path with `{"desiredState": true}` → response echoes post-write state. If a metadata PUT returns `FIELD_INTEGRITY_EXCEPTION: invalid at this location` for a plausible-looking element name, the field may not be on `IndustriesSettings` at all — try this org-preference path next before assuming manual-UI-only |
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Domain & Feature Toggle Write Path (authoritative)
|
|
2
|
+
|
|
3
|
+
Education Cloud domain toggles — `enableEducationCloud`, `enableStudentSuccess`, `enableAcademicOperations`, `enableMentoring`, `enableCorporateRelations`, `enableStudentManagement`, `enableFinancialAid`, `enableFundraising`, `enableOutcomes`, `enableProgramCohorts`, `enableStudentGoals`, `enableAlumniRelations`, `enableRNADynamicApplications`, and ~28 similar — are **fields inside the `IndustriesSettings` settings file**. They are NOT in Core's `ORG_PREFERENCES` allowlist.
|
|
4
|
+
|
|
5
|
+
> **IRREVERSIBLE — one-way by design.** These toggles are `false → true` only. `true → false` is rejected/unsupported. **WARN the user before flipping any toggle. Do NOT promise a revert or rollback.**
|
|
6
|
+
|
|
7
|
+
## Endpoints that DO NOT work — never use these
|
|
8
|
+
|
|
9
|
+
| Attempt | Result |
|
|
10
|
+
|---------|--------|
|
|
11
|
+
| `PATCH setup/org/preferences/{name}` | 404 — name not in ORG_PREFERENCES allowlist |
|
|
12
|
+
| Tooling sObject `PATCH` on `IndustriesSettings` | 400 `JSON_PARSER_ERROR` (complexvalue fields) |
|
|
13
|
+
| SOAP `/services/Soap/m/XX.0` `updateMetadata` | `ROUTE_NOT_FOUND` through the gateway |
|
|
14
|
+
| `POST /services/data/vXX/metadata/deployRequest` (multipart zip) | `ROUTE_NOT_FOUND` through the gateway |
|
|
15
|
+
|
|
16
|
+
## What writes via this path, what does not
|
|
17
|
+
|
|
18
|
+
| Category | API-writable via metadata PUT? |
|
|
19
|
+
|----------|-------------------------------|
|
|
20
|
+
| Domain toggles (`enableStudentSuccess`, …) — **once foundation is ON** | Yes |
|
|
21
|
+
| Sub-feature toggles (`enableCarePlansPreference`, Support Programs, Scheduler org prefs) — **once foundation is ON** | Yes |
|
|
22
|
+
| **Education Cloud foundation** (`enableEducationCloud`) | No — via metadata PUT. **Confirmed silent no-op** for this specific field (`success:true`, stays `false`); the metadata PUT path itself is proven to route AND flip real sub-feature toggles (verified: `enableStudentGoals` `false→true`), so this is feature-specific, not a transport failure. Yes — via the dedicated invoke endpoint instead (see "Enabling the foundation" below). |
|
|
23
|
+
|
|
24
|
+
## Enabling the foundation (`enableEducationCloud`) — dedicated invoke endpoint
|
|
25
|
+
|
|
26
|
+
Root cause of the silent no-op: this toggle is AURA-IS-CANONICAL — the real enable action runs extra `ReleasableAction` provisioning wiring beyond a raw field flip, and only the dedicated controller endpoint below runs it. Do not attempt the metadata PUT for foundation.
|
|
27
|
+
|
|
28
|
+
Same `dispatch`/`dispatch_readonly` tools and headless-360 transport as the metadata path, different URL:
|
|
29
|
+
- READ: `GET /headless/invoke/platform/education-cloud-settings` (`dispatch_readonly` is fine) — inspect `educationCloudEnabled`.
|
|
30
|
+
- WRITE: `PATCH /headless/invoke/platform/education-cloud-settings/enable-education-cloud` (empty body, via the write-enabled `dispatch` tool).
|
|
31
|
+
- cold-VERIFY: repeat the GET above — confirm `educationCloudEnabled: true` on a fresh read. Also cold-check the `IndustriesSettings` tooling GET (`.Metadata.enableEducationCloud` / `IsEducationCloudEnabled`) as a secondary check — the invoke GET is authoritative if they disagree.
|
|
32
|
+
- If the invoke endpoint errors or cold-verify still shows `false`: fall back to manual UI — Setup → Quick Find → "Set Up Education Cloud" → Toggle "Enable Education Cloud" → Save. Warn this cannot be disabled after enabling. Wait for user confirmation, then cold-verify again.
|
|
33
|
+
| Person Accounts | No — manual UI only |
|
|
34
|
+
| License-gated features (Salesforce Scheduler master enable, Field Service) | No — manual UI only |
|
|
35
|
+
|
|
36
|
+
## The correct sequence: READ → WRITE → VERIFY (cold-verify is mandatory)
|
|
37
|
+
|
|
38
|
+
**Constants:** API version `v68.0` · `IndustriesSettings` `DurableId` = `bWRjLzBIRS9JbmR1c3RyaWVzU2V0dGluZ3M=` (raw `=`, NOT url-encoded `%3D`).
|
|
39
|
+
|
|
40
|
+
**1. READ (pre-read current state)** — `dispatch_readonly` GET is fine here:
|
|
41
|
+
```http
|
|
42
|
+
GET /services/data/v68.0/tooling/sobjects/IndustriesSettings/bWRjLzBIRS9JbmR1c3RyaWVzU2V0dGluZ3M=
|
|
43
|
+
```
|
|
44
|
+
Inspect `.Metadata.enable*` (and the flat `Is<X>Enabled` fields) for current state.
|
|
45
|
+
|
|
46
|
+
> `SELECT ... FROM IndustriesSettings` returns **only `Id` and `DurableId` — NO `Metadata`.** You MUST GET the record by `DurableId` to read toggle state. Do NOT use the placeholder Id `000000000000000AAA`.
|
|
47
|
+
|
|
48
|
+
**2. WRITE (flip the toggle)** — use the **write-enabled `dispatch` tool** (NOT `dispatch_readonly` — read-only *fakes* write success, returning `success:true` without writing). Synchronous, no polling:
|
|
49
|
+
```http
|
|
50
|
+
PUT /services/data/v68.0/headless/metadata
|
|
51
|
+
```
|
|
52
|
+
Structured JSON body — `type` is literally `IndustriesSettings`, `fullName` is `Industries`, `xmlRep` includes the XML declaration. One PUT can flip **multiple** elements at once:
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"type": "IndustriesSettings",
|
|
56
|
+
"fullName": "Industries",
|
|
57
|
+
"xmlRep": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><IndustriesSettings xmlns=\"http://soap.sforce.com/2006/04/metadata\"><enableStudentSuccess>true</enableStudentSuccess></IndustriesSettings>"
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**3. VERIFY (cold read — REQUIRED)** — repeat step 1 and confirm `.Metadata.<element>` and/or the flat `Is<X>Enabled` field is now `true`.
|
|
62
|
+
|
|
63
|
+
> **`success:true` alone is unreliable — always cold-verify.** The foundation write returned `success:true` yet no-op'd. Only a fresh GET of the record confirms the toggle actually flipped.
|
|
64
|
+
|
|
65
|
+
> **Cold-verify fallback — the tooling GET can 500 org-wide.** Confirmed on a test org: `GET .../tooling/sobjects/IndustriesSettings/<DurableId>` returned HTTP 500 `UNKNOWN_EXCEPTION` on every value read (any field, any API version), root-caused to a null UDD `LogicalFieldDefinition` on one preference column in that org's data — an org-data defect, not a skill or transport bug (`describe` and `SELECT Id, DurableId` still returned 200). If this GET 500s on 3 consecutive attempts, stop retrying and ask the admin to confirm the toggle's state in Setup UI instead. Report it explicitly as "confirmed via Setup UI, not cold-verified via API" — never claim API cold-verify succeeded when it didn't.
|
|
66
|
+
|
|
67
|
+
> **License-gating on the write itself.** A toggle write can return `400 INSUFFICIENT_ACCESS_OR_READONLY` (nothing written) purely because the org lacks a license, not because the feature is unreachable via API — confirmed on a test org where the identical write failed, then succeeded after the admin added licenses with no other change. On this error, ask whether the org is fully licensed for the feature before concluding the API path doesn't work.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Decide whether Education Cloud is licensed/provisioned on the org.
|
|
3
|
+
|
|
4
|
+
Permission set names for Education Cloud vary by org/release, so a single
|
|
5
|
+
exact-name match is unreliable. Reads a JSON object from stdin:
|
|
6
|
+
|
|
7
|
+
{
|
|
8
|
+
"permissionSets": [ { "Id": "...", "Name": "..." }, ... ],
|
|
9
|
+
"businessProfileDescribe": { "createable": true, ... } | null
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
`permissionSets` is the `records` array from
|
|
13
|
+
`SELECT Id, Name FROM PermissionSet WHERE Name LIKE '%EducationCloud%'`.
|
|
14
|
+
`businessProfileDescribe` is the describe result for the `BusinessProfile`
|
|
15
|
+
sobject, or null/omitted if that describe call 404'd.
|
|
16
|
+
|
|
17
|
+
Rows found in `permissionSets` -> provisioned. Zero rows -> cross-check
|
|
18
|
+
`businessProfileDescribe.createable` before concluding not-provisioned.
|
|
19
|
+
|
|
20
|
+
Usage:
|
|
21
|
+
python3 scripts/check_license_provisioned.py <<'JSON'
|
|
22
|
+
{"permissionSets": [], "businessProfileDescribe": {"createable": true}}
|
|
23
|
+
JSON
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
import json
|
|
29
|
+
import sys
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def main() -> int:
|
|
33
|
+
payload = json.load(sys.stdin)
|
|
34
|
+
permission_sets = payload.get("permissionSets") or []
|
|
35
|
+
describe = payload.get("businessProfileDescribe")
|
|
36
|
+
|
|
37
|
+
if permission_sets:
|
|
38
|
+
result = {
|
|
39
|
+
"provisioned": True,
|
|
40
|
+
"reason": "matching permission set(s) found",
|
|
41
|
+
"matchingPermissionSets": [ps.get("Name") for ps in permission_sets],
|
|
42
|
+
}
|
|
43
|
+
elif isinstance(describe, dict) and describe.get("createable") is True:
|
|
44
|
+
result = {
|
|
45
|
+
"provisioned": True,
|
|
46
|
+
"reason": "zero permission-set matches, but BusinessProfile is createable — treat as provisioned, note the mismatch",
|
|
47
|
+
"matchingPermissionSets": [],
|
|
48
|
+
}
|
|
49
|
+
else:
|
|
50
|
+
result = {
|
|
51
|
+
"provisioned": False,
|
|
52
|
+
"reason": "zero permission-set matches and BusinessProfile is not createable (404 or createable:false) — license not provisioned",
|
|
53
|
+
"matchingPermissionSets": [],
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
json.dump(result, sys.stdout, indent=2)
|
|
57
|
+
print()
|
|
58
|
+
return 0
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
if __name__ == "__main__":
|
|
62
|
+
sys.exit(main())
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Check whether an org's edition meets Education Cloud's minimum requirement.
|
|
3
|
+
|
|
4
|
+
Reads a JSON object from stdin shaped like a SOQL query result for
|
|
5
|
+
`SELECT OrganizationType FROM Organization` (the `records` array, or a bare
|
|
6
|
+
list containing that one record). Prints a JSON verdict.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python3 scripts/check_org_edition.py \
|
|
10
|
+
--allowed "Enterprise Edition,Performance Edition,Unlimited Edition,Developer Edition" <<'JSON'
|
|
11
|
+
{"records": [{"OrganizationType": "Enterprise Edition"}]}
|
|
12
|
+
JSON
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import argparse
|
|
18
|
+
import json
|
|
19
|
+
import sys
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def main() -> int:
|
|
23
|
+
parser = argparse.ArgumentParser()
|
|
24
|
+
parser.add_argument("--allowed", required=True, help="Comma-separated list of qualifying OrganizationType values")
|
|
25
|
+
args = parser.parse_args()
|
|
26
|
+
allowed = [a.strip() for a in args.allowed.split(",") if a.strip()]
|
|
27
|
+
|
|
28
|
+
payload = json.load(sys.stdin)
|
|
29
|
+
records = payload.get("records", payload) if isinstance(payload, dict) else payload
|
|
30
|
+
|
|
31
|
+
if not records:
|
|
32
|
+
json.dump({"eligible": False, "organizationType": None, "reason": "no Organization record returned"}, sys.stdout, indent=2)
|
|
33
|
+
print()
|
|
34
|
+
return 0
|
|
35
|
+
|
|
36
|
+
org_type = records[0].get("OrganizationType")
|
|
37
|
+
result = {"eligible": org_type in allowed, "organizationType": org_type, "allowed": allowed}
|
|
38
|
+
json.dump(result, sys.stdout, indent=2)
|
|
39
|
+
print()
|
|
40
|
+
return 0
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
if __name__ == "__main__":
|
|
44
|
+
sys.exit(main())
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Check whether the running user has one of the org's Education Cloud permission sets assigned.
|
|
3
|
+
|
|
4
|
+
Reads a JSON object from stdin shaped like a SOQL query result for
|
|
5
|
+
`SELECT Id, PermissionSet.Name FROM PermissionSetAssignment WHERE
|
|
6
|
+
AssigneeId='<id>' AND PermissionSet.Name LIKE '%EducationCloud%'` (the
|
|
7
|
+
`records` array, or a bare list). Prints a JSON verdict.
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
python3 scripts/check_permission_assigned.py <<'JSON'
|
|
11
|
+
{"records": [{"PermissionSet": {"Name": "EducationCloudAccess"}}]}
|
|
12
|
+
JSON
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import json
|
|
18
|
+
import sys
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def main() -> int:
|
|
22
|
+
payload = json.load(sys.stdin)
|
|
23
|
+
records = payload.get("records", payload) if isinstance(payload, dict) else payload
|
|
24
|
+
|
|
25
|
+
names = []
|
|
26
|
+
for rec in records or []:
|
|
27
|
+
permission_set = rec.get("PermissionSet") or {}
|
|
28
|
+
name = permission_set.get("Name")
|
|
29
|
+
if name:
|
|
30
|
+
names.append(name)
|
|
31
|
+
|
|
32
|
+
result = {"assigned": bool(names), "matchingPermissionSets": names}
|
|
33
|
+
json.dump(result, sys.stdout, indent=2)
|
|
34
|
+
print()
|
|
35
|
+
return 0
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if __name__ == "__main__":
|
|
39
|
+
sys.exit(main())
|
|
@@ -6,6 +6,8 @@ metadata:
|
|
|
6
6
|
minApiVersion: "65.0"
|
|
7
7
|
domains:
|
|
8
8
|
- "Education"
|
|
9
|
+
relatedSkills:
|
|
10
|
+
- "education-cloud-domain-configure"
|
|
9
11
|
accessCheck:
|
|
10
12
|
- type: "license"
|
|
11
13
|
value: "Education Cloud"
|
|
@@ -22,6 +24,11 @@ allowed-tools: |
|
|
|
22
24
|
mcp__headless-360__describe
|
|
23
25
|
mcp__headless-360__dispatch
|
|
24
26
|
mcp__headless-360__dispatch_readonly
|
|
27
|
+
distribution:
|
|
28
|
+
sf-skills:
|
|
29
|
+
visibility: "public"
|
|
30
|
+
headless360Mcp:
|
|
31
|
+
visibility: "public"
|
|
25
32
|
---
|
|
26
33
|
|
|
27
34
|
# Education Cloud Multi-Campus Institutional Hierarchy Configuration
|
package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Step 0 — Foundation Prerequisites
|
|
2
2
|
|
|
3
3
|
This skill can run standalone, without any other Education Cloud setup skill running first. Verify
|
|
4
|
-
these before Step 1 — they are shared across the EDU skill family
|
|
5
|
-
|
|
6
|
-
write, otherwise instruct manual
|
|
4
|
+
these before Step 1 — they are shared across the EDU skill family (also required by
|
|
5
|
+
`education-cloud-domain-configure`). A gap here is a missing prerequisite to resolve, not a
|
|
6
|
+
dead end — self-heal what's API-writable, ask/confirm before any write, otherwise instruct manual
|
|
7
|
+
Setup and wait for confirmation.
|
|
7
8
|
|
|
8
9
|
## Checks (in order — each can stop the workflow if unresolved)
|
|
9
10
|
|