@salesforce/afv-skills 1.63.0 → 1.64.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-offline-experimentation-run/SKILL.md +253 -0
  3. package/skills/agentforce-offline-experimentation-run/scripts/build_report.py +796 -0
  4. package/skills/agentforce-offline-experimentation-run/scripts/resolve-token.sh +111 -0
  5. package/skills/agentforce-offline-experimentation-run/scripts/sfap_replay.py +1053 -0
  6. package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +21 -11
  7. package/skills/automation-sandbox-post-copy-config-generate/assets/config_template.json +10 -0
  8. package/skills/automation-sandbox-post-copy-config-generate/assets/json_schema.json +33 -1
  9. package/skills/automation-sandbox-post-copy-config-generate/references/configuration_catalog.md +44 -1
  10. package/skills/automation-sandbox-post-copy-configure/SKILL.md +132 -124
  11. package/skills/automation-sandbox-post-copy-configure/references/flow_activation_path.md +151 -0
  12. package/skills/automation-sandbox-post-copy-configure/references/scheduled_apex_path.md +55 -9
  13. package/skills/consumer-goods-promotion-bo-api-deploy/SKILL.md +54 -107
  14. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/copy.json +1 -1
  15. package/skills/consumer-goods-promotion-bo-api-deploy/references/conventions-and-payload-rules.md +82 -5
  16. package/skills/consumer-goods-promotion-bo-api-deploy/references/generate-and-wire.md +35 -2
  17. package/skills/consumer-goods-promotion-bo-api-deploy/references/preflight-and-seed-queries.md +149 -0
  18. package/skills/consumer-goods-promotion-bo-api-deploy/references/smoke-and-verify.md +17 -1
  19. package/skills/dx-devops-conflict-resolve/SKILL.md +1 -5
  20. package/skills/dx-devops-pipeline-manage/SKILL.md +1 -5
  21. package/skills/dx-devops-project-manage/SKILL.md +1 -5
  22. package/skills/dx-devops-promote/SKILL.md +1 -5
  23. package/skills/dx-devops-request-status/SKILL.md +1 -5
  24. package/skills/dx-lifecycle-center/SKILL.md +120 -0
  25. package/skills/dx-lifecycle-center/examples/workflows.md +175 -0
  26. package/skills/dx-lifecycle-center/references/connect-api.md +123 -0
  27. package/skills/dx-lifecycle-center/references/connect-org.md +184 -0
  28. package/skills/dx-lifecycle-center/references/deploy.md +153 -0
  29. package/skills/dx-lifecycle-center/references/error-handling.md +21 -0
  30. package/skills/dx-lifecycle-center/references/hub-org.md +37 -0
  31. package/skills/dx-lifecycle-center/references/list-orgs.md +99 -0
  32. package/skills/dx-lifecycle-center/references/request-body.md +75 -0
  33. package/skills/dx-lifecycle-center/references/troubleshooting.md +31 -0
  34. package/skills/dx-lifecycle-center/scripts/poll-deploy-status.sh +200 -0
  35. package/skills/dx-lifecycle-center/scripts/resolve-environment.sh +120 -0
  36. package/skills/dx-org-devhub-configure/SKILL.md +1 -3
  37. package/skills/dx-org-shape-manage/SKILL.md +1 -5
  38. package/skills/dx-org-snapshot-manage/SKILL.md +1 -3
  39. package/skills/education-cloud-academic-calendar-generate/SKILL.md +1 -3
  40. package/skills/education-cloud-course-catalog-migrate/SKILL.md +1 -3
  41. package/skills/education-cloud-domain-configure/SKILL.md +1 -3
  42. package/skills/education-cloud-multi-campus-configure/SKILL.md +1 -3
  43. package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +1 -5
  44. package/skills/experience-ui-bundle-2gp-deploy/SKILL.md +1 -3
  45. package/skills/experience-ui-bundle-features-generate/SKILL.md +1 -5
  46. package/skills/experience-ui-bundle-mfa-configure/SKILL.md +1 -3
  47. package/skills/field-service-data-capture-migrate/SKILL.md +1 -3
  48. package/skills/insurance-brokerage-agency-billing-configure/SKILL.md +1 -3
  49. package/skills/marketing-message-test/SKILL.md +1 -3
  50. package/skills/nonprofit-fundraising-configure/SKILL.md +240 -0
  51. package/skills/nonprofit-fundraising-configure/references/gotchas.md +26 -0
  52. package/skills/nonprofit-fundraising-configure/references/mcp-invocation.md +678 -0
  53. package/skills/nonprofit-fundraising-configure/references/permission-targeting.md +35 -0
  54. package/skills/nonprofit-volunteer-management-model-get/SKILL.md +166 -0
  55. package/skills/nonprofit-volunteer-management-model-get/references/entities.md +315 -0
  56. package/skills/nonprofit-volunteer-management-model-get/references/relationships.md +175 -0
  57. package/skills/nonprofit-volunteer-management-model-get/references/themes.md +143 -0
  58. package/skills/nonprofit-volunteer-management-records-create/SKILL.md +121 -0
  59. package/skills/nonprofit-volunteer-management-records-create/references/field-guide.md +284 -0
  60. package/skills/nonprofit-volunteer-management-records-create/references/mcp-invocation.md +248 -0
  61. package/skills/nonprofit-volunteer-management-records-create/references/review-format.md +140 -0
  62. package/skills/nonprofit-volunteer-management-records-create/scripts/expand-series.py +632 -0
  63. package/skills/nonprofit-volunteer-management-records-create/scripts/render-review-table.py +419 -0
  64. package/skills/nonprofit-volunteer-management-records-create/scripts/tests/test_expand_series.py +690 -0
  65. package/skills/nonprofit-volunteer-management-records-create/scripts/tests/test_render_review_table.py +421 -0
  66. package/skills/nonprofit-volunteer-management-structure-generate/SKILL.md +119 -0
  67. package/skills/nonprofit-volunteer-management-structure-generate/references/configuration-decisions.md +159 -0
  68. package/skills/nonprofit-volunteer-management-structure-generate/references/discovery-interview.md +137 -0
  69. package/skills/nonprofit-volunteer-management-structure-generate/references/edge-cases.md +48 -0
  70. package/skills/nonprofit-volunteer-management-structure-generate/references/mcp-invocation.md +75 -0
  71. package/skills/nonprofit-volunteer-management-structure-generate/references/plan-output.md +141 -0
  72. package/skills/platform-custom-field-generate/SKILL.md +1 -0
  73. package/skills/platform-custom-field-generate/references/advanced-picklists.md +5 -5
  74. package/skills/platform-custom-metadata-type-generate/SKILL.md +3 -0
  75. package/skills/platform-custom-object-generate/SKILL.md +4 -0
  76. package/skills/platform-custom-setting-generate/SKILL.md +3 -0
  77. package/skills/platform-datamask-run/SKILL.md +1 -5
  78. package/skills/platform-permission-set-generate/SKILL.md +3 -0
  79. package/skills/platform-salesforce-connect-adapter-generate/SKILL.md +1 -3
  80. package/skills/platform-sandbox-configure/SKILL.md +1 -3
  81. package/skills/platform-value-set-generate/SKILL.md +3 -0
  82. package/skills/sales-call-scoring-configure/SKILL.md +1 -5
  83. package/skills/service-agentforce-channel-configure/SKILL.md +1 -3
  84. package/skills/service-agentforce-human-escalation-configure/SKILL.md +1 -3
  85. package/skills/service-catalog-template-coordinate/SKILL.md +1 -3
  86. package/skills/service-concierge-portal-generate/SKILL.md +1 -3
  87. package/skills/service-email-to-case-configure/SKILL.md +1 -5
  88. package/skills/service-itsm-agentic-setup-agent-runtime-access-assign/SKILL.md +1 -3
  89. package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +1 -3
  90. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/SKILL.md +1 -3
  91. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/SKILL.md +1 -3
  92. package/skills/service-itsm-agentic-setup-cmdb-access-assign/SKILL.md +1 -3
  93. package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/SKILL.md +1 -5
  94. package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +1 -3
  95. package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +1 -3
  96. package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/SKILL.md +1 -3
  97. package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +1 -3
  98. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +1 -3
  99. package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +1 -0
  100. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/SKILL.md +1 -3
  101. package/skills/service-itsm-agentic-setup-uel-user-create/SKILL.md +1 -9
  102. package/skills/service-itsm-incident-mgmt-configure/SKILL.md +1 -5
  103. package/skills/service-itsm-incident-priority-configure/SKILL.md +1 -3
  104. package/skills/service-itsm-slack-itservice-configure/SKILL.md +1 -3
  105. package/skills/service-itsm-swarming-configure/SKILL.md +1 -3
  106. package/skills/service-itsm-teams-configure/SKILL.md +1 -3
  107. package/skills/service-itsm-teams-debug/SKILL.md +1 -3
  108. package/skills/service-itsm-teams-employee-agent-configure/SKILL.md +1 -3
  109. package/skills/service-itsm-teams-itdesk-configure/SKILL.md +1 -3
  110. package/skills/service-itsm-teams-itservice-configure/SKILL.md +1 -3
  111. package/skills/service-native-voice-recording-transcription-configure/SKILL.md +1 -3
  112. package/skills/service-omni-agent-users-create/SKILL.md +1 -3
  113. package/skills/service-omni-agent-work-sharing-configure/SKILL.md +1 -3
  114. package/skills/service-omni-attribute-routing-configure/SKILL.md +1 -3
  115. package/skills/service-omni-base-settings-configure/SKILL.md +1 -3
  116. package/skills/service-omni-channel-inventory-analyze/SKILL.md +1 -3
  117. package/skills/service-omni-channel-limits-analyze/SKILL.md +1 -3
  118. package/skills/service-omni-channel-setup-coordinate/SKILL.md +1 -3
  119. package/skills/service-omni-command-center-analyze/SKILL.md +1 -3
  120. package/skills/service-omni-command-center-configure/SKILL.md +1 -3
  121. package/skills/service-omni-permission-set-assign/SKILL.md +1 -3
  122. package/skills/service-omni-presence-status-deploy/SKILL.md +1 -3
  123. package/skills/service-omni-presence-user-config-deploy/SKILL.md +1 -3
  124. package/skills/service-omni-queue-deploy/SKILL.md +1 -3
  125. package/skills/service-omni-queue-members-assign/SKILL.md +1 -3
  126. package/skills/service-omni-queue-routing-config-deploy/SKILL.md +1 -3
  127. package/skills/service-omni-routing-flow-deploy/SKILL.md +1 -3
  128. package/skills/service-omni-service-channel-configure/SKILL.md +1 -3
  129. package/skills/service-omni-sidebar-configure/SKILL.md +1 -3
  130. package/skills/service-omni-skills-based-routing-configure/SKILL.md +1 -3
  131. package/skills/service-omni-supervisor-config-deploy/SKILL.md +1 -3
  132. package/skills/service-omni-supervisor-permset-assign/SKILL.md +1 -3
  133. package/skills/service-omni-supervisor-surface-deploy/SKILL.md +1 -3
  134. package/skills/service-omni-supervisor-users-create/SKILL.md +1 -3
  135. package/skills/service-omni-work-skill-routing-configure/SKILL.md +1 -3
  136. package/skills/field-service-setup-orchestrator-get/SKILL.md +0 -47
  137. package/skills/tableau-next-asset-create/README.md +0 -65
@@ -0,0 +1,35 @@
1
+ # Permission targeting reference — nonprofit-fundraising-configure
2
+
3
+ ## Org-wide role classification (steps 6, 8)
4
+
5
+ This skill provisions every active human user on the org, not just the invoking user. Query:
6
+
7
+ ```sql
8
+ SELECT Id, Username, Name, UserType, IsActive, ProfileId, Profile.Name
9
+ FROM User
10
+ WHERE IsActive = true AND UserType = 'Standard'
11
+ ```
12
+
13
+ `UserType = 'Standard'` alone is not sufficient — built-in integration/bot accounts (seen live:
14
+ "SalesforceIQ Integration", "Insights Integration", "Bot User", "DigitalAgent.*") also carry
15
+ `UserType = 'Standard'`. Exclude names matching those patterns before classifying.
16
+
17
+ Classify each remaining user by `Profile.Name`:
18
+
19
+ - `'System Administrator'` → **Admin** — gets `FundraisingAccess` (step 6) + `Fundraising_Admin`
20
+ (step 8).
21
+ - `'Standard User'` → **Standard** — gets `FundraisingAccess` (step 6) + `Fundraising_User`
22
+ (step 8).
23
+ - Anything else → gets `FundraisingAccess` only (step 6); step 8 skips them — never assign a
24
+ group to a user this classification didn't resolve.
25
+
26
+ **Known limitation**: literal `Profile.Name` matching misses custom or cloned admin/standard
27
+ profiles (e.g. an org-specific "Admin - Fundraising" clone). Users on such a profile fall through
28
+ to the plain-permission-set-only branch and will not get a permission set group. This is an
29
+ accepted gap, not a bug to work around — do not attempt profile-permission introspection to guess
30
+ at equivalence.
31
+
32
+ Idempotency for both steps: query for an existing `PermissionSetAssignment`
33
+ (`AssigneeId`+`PermissionSetId`, or the group-assignment equivalent) before creating. Treat a
34
+ match as already-satisfied rather than re-creating it (`DUPLICATE_VALUE` otherwise) — this skill
35
+ has no persisted resume state, so every invocation replays against live org state.
@@ -0,0 +1,166 @@
1
+ ---
2
+ name: nonprofit-volunteer-management-model-get
3
+ description: "Use this skill to explain how the Salesforce Nonprofit Cloud Volunteer Management (VM) data model works and why, answering from reference material without connecting to an org. Answers what a VM object, field, or relationship is for and how features such as volunteer matching, shift capacity, hours rollups, sign-up approval, and permission gating behave, and maps a goal (\"track volunteer hours\", \"cap a shift\") to the objects and fields behind it. TRIGGER when a user asks what a VM object, field, or relationship is for, or how a VM feature works. DO NOT TRIGGER to plan a program (use nonprofit-volunteer-management-structure-generate), to create records (use nonprofit-volunteer-management-records-create), to enable Volunteer Management in an org, or for NPSP / Volunteers for Salesforce (V4S), which is unsupported."
4
+ metadata:
5
+ version: "1.1"
6
+ domains: ["Nonprofit"]
7
+ relatedSkills:
8
+ - "nonprofit-volunteer-management-records-create"
9
+ - "nonprofit-volunteer-management-structure-generate"
10
+ accessCheck: "(OrgPermissions.VolunteerManagement) && (OrgPreferences.VolunteerManagementEnabled)"
11
+ ---
12
+
13
+ # Nonprofit Cloud Volunteer Management — Data Model Knowledge
14
+
15
+ This skill explains *why* the Volunteer Management object model is shaped the way it is: why so many
16
+ entities are borrowed from other clouds, how fields are gated by permissions, and how the pieces
17
+ combine into features. Object and field definitions give the fields; this skill gives the intent, so
18
+ an agent can map a user's goal ("track completed volunteer hours", "require approval before signup",
19
+ "cap a shift at 10 people") onto the right entities and fields.
20
+
21
+ ## Hard rules
22
+
23
+ - **Never delete records.** No delete, rollback or cleanup of any kind. If a write fails part-way, report what was created and what wasn't; never undo it.
24
+ - **Never act on NPSP or Volunteers for Salesforce (V4S).** That legacy package is unsupported here. Say so and stop.
25
+ - **No acronyms or internal labels in what the user sees.** Write out Volunteer Initiative, Job Position, Job Position Shift, Job Position Assignment, Position Qualification, Job Position Qualification, Data Processing Engine, and "out of the box". Never show internal step or section labels.
26
+ - **No org operations.** This skill answers from its references; it never reads or writes an org.
27
+
28
+ ## Scope
29
+
30
+ Only the entities in the **Volunteer** and **Volunteer Management** sections of the model, plus the
31
+ Address that a Location points at. Benefit is referenced by one in-scope bridge entity
32
+ (PositionBenefit) but belongs to Program Management: treat it as an external dependency and never
33
+ model it.
34
+
35
+ **Non-goals:**
36
+ - Planning or designing a program, or deciding which records a program needs → `nonprofit-volunteer-management-structure-generate`.
37
+ - Creating or reusing records, or how to fill in a field when creating one → `nonprofit-volunteer-management-records-create`.
38
+ - Turning Volunteer Management on in an org.
39
+
40
+ ## Required Inputs
41
+
42
+ The user's question. No org connection is needed.
43
+
44
+ ## Answering Workflow
45
+
46
+ 1. **Identify the concept.** Work out which feature or entity the question touches: matching,
47
+ capacity, rollups, approval, the benefit bridge, the hierarchy, or a single entity or field.
48
+ 2. **Read the matching reference.** Features and how entities connect → `references/relationships.md`;
49
+ one entity's purpose, fields and gotchas → `references/entities.md`; the design principle behind a
50
+ choice → `references/themes.md`.
51
+ 3. **Answer only what was asked, briefly.** Lead with the direct answer, then only the detail that
52
+ earns its place. Don't tour the model or add features the user didn't ask about. If the user
53
+ narrows the question ("just the permission model"), stay inside that boundary; mention a
54
+ neighbouring mechanism only if the answer depends on it, in one line. Keep an answer to a few
55
+ short paragraphs or bullets, about 300 words. Give each entity one line; list its fields, picklist
56
+ values or a summary table only when the user asks for them.
57
+ 4. **Mention caveats, don't list them.** If the topic has a "shipped but not configured" caveat (see
58
+ "Mechanism shipped, configuration is the customer's" below), say that one exists and offer to show
59
+ it. Give the detail only if the user asks.
60
+
61
+ ## Rules / Constraints
62
+
63
+ The hard rules above apply to every answer. In addition:
64
+
65
+ | Constraint | Rationale |
66
+ |---|---|
67
+ | Answer from the references, not from memory | The references hold the verified behaviour; general Salesforce knowledge often gets Volunteer Management wrong (for example, capacity and qualification matching). |
68
+ | No record Id literals in answers | Ids differ per org; a hard-coded Id is wrong in every other org. |
69
+ | Scope tightly to the question | A long answer that tours adjacent features buries the part the user needed. |
70
+ | Caveats only on request | Say a caveat exists and offer it; dumping every caveat makes each answer longer and less useful. |
71
+ | Don't state how to fill in fields when creating records | That belongs to records-create's field guide; two copies drift apart. |
72
+
73
+ ## The three things to understand first
74
+
75
+ ### 1. Reuse over new entities — and Account is a "hero" entity
76
+ Most Volunteer Management entities are **not native**. They are borrowed from other clouds, and
77
+ Volunteer Management adds a small number of fields gated behind its permissions. This is deliberate:
78
+ Account is a "hero" entity that Salesforce makes hard to extend, so product data hangs off
79
+ **related entities** rather than new Account or Contact fields. Volunteer Management adds **no**
80
+ fields to Account or Contact. For volunteer data, look for the related entity.
81
+
82
+ A borrowed entity's Volunteer Management fields are the only part of it that Volunteer Management
83
+ cares about. `references/entities.md` names every one.
84
+
85
+ ### 2. The permission model mirrors an authenticated boundary
86
+ Records are gated by four permission expressions that map to three kinds of user:
87
+
88
+ | Permission | Who |
89
+ |---|---|
90
+ | `orgHasVolunteerManagement` | the org has the feature (API access, related lists) |
91
+ | `userHasVolunteerManagement` | internal staff (volunteer managers) |
92
+ | `userHasVolunteerManagementCmtyAccess` | a signed-in community volunteer (Experience Cloud) |
93
+ | `userHasGuestVolunteerManagementCmtyAccess` | a guest who hasn't signed in |
94
+
95
+ A volunteer can sign up **before** they have an account. A guest exists only as a **Contact**; once
96
+ they create or convert to a **Person Account** they are an authenticated volunteer. This boundary is
97
+ the most important pattern in the model: entities that store a volunteer's own data (availability,
98
+ credentials, engagement history) require an **Account**; the public signup path accepts a bare
99
+ Contact.
100
+
101
+ The volunteer is a **Person Account**, so Person Accounts must be enabled. The "Business Account"
102
+ box in the diagram is just how Salesforce draws Person Accounts.
103
+
104
+ `&&` (AND) gating across two clouds marks a deliberate **cross-product bridge** (Volunteer
105
+ Management && Benefit Management), unlike the usual `||` (OR) gating of plain reuse. See
106
+ `references/themes.md` T20.
107
+
108
+ ### 3. Mechanism shipped, configuration is the customer's
109
+ Volunteer Management often ships the field or hook but not the behaviour. These are the caveats to
110
+ offer when a question touches them:
111
+
112
+ - **Engagement rollups** (4 fields on DonorGiftSummary, 6 on VolunteerInitiative) exist but are
113
+ **empty** until the customer builds and schedules a Data Processing Engine definition.
114
+ - **Status** on Volunteer Initiative, Position, Job Position and Job Position Shift ships with
115
+ out-of-the-box values that admins can change. Each lifecycle is independent: nothing moves
116
+ one entity's Status when another's changes. Stage Management automation is the customer's to set up.
117
+ - **`Position.IsInternalApprovalRequired`** does nothing on its own. The customer wires Salesforce
118
+ Approvals to it; approval moves the Job Position Assignment's Status.
119
+ - **Shift capacity is counted, never enforced.** Assignments are counted onto the shift and
120
+ RemainingCapacity is a formula, but nothing blocks a signup when a shift is full.
121
+ - **`ConstituentRole.RoleType`** ships with "Volunteer" (plus Donor, Philanthropic Prospect and
122
+ Participant), so the customer doesn't need to add it.
123
+
124
+ ## The model at a glance
125
+
126
+ - **Who:** Person Account (authenticated volunteer) or Contact (guest). Marked as a volunteer by
127
+ **ConstituentRole**. Engagement totals sit on **DonorGiftSummary** (a volunteer is assumed to be a
128
+ likely donor).
129
+ - **What they can do:** **PersonLocationAvailability** (when and where), **PersonCompetency**
130
+ (skills), **PersonExamination** (credentials). Matching uses availability and PersonCompetency;
131
+ PersonExamination is for a manager's own review, not matching.
132
+ - **The work:** **Position** (reusable template) → **JobPosition** (a concrete posting, optionally at
133
+ a Location) → **JobPositionShift** (a dated occurrence) → **JobPositionAssignment** (a person doing
134
+ it on a day; the source of truth for hours).
135
+ - **Requirements on the work:** **PositionQualification** and **JobPositionQualification** point at a
136
+ Competency or an Examination. Matching uses QualificationLevel on Competency qualifications. A Job
137
+ Position's own qualifications and its Position's qualifications are checked together, keeping the
138
+ higher level per Competency. Nothing is copied from the Position to the Job Position.
139
+ - **Organizing anchor:** **VolunteerInitiative** — an optional, self-referencing top-level parent.
140
+ - **Integrations:** **PositionBenefit** bridges to Benefit Management (volunteers provide a service
141
+ that beneficiaries receive as a Benefit); Approvals and Stage Management hook into the Status fields.
142
+
143
+ ## Output Expectations
144
+
145
+ - A direct answer in plain language, naming the entity and field API names the user needs.
146
+ - Only the entities and features the question needs, about 300 words, one line per entity. Say each point once: no restated summary, no closing recap, and no list of follow-up topics.
147
+ - When a caveat applies, one line saying it exists and offering to show it.
148
+ - When the request is out of scope, name the sibling skill that handles it, or say that NPSP / V4S is
149
+ unsupported and stop.
150
+
151
+ ## Cross-Skill Integration
152
+
153
+ | User wants to… | Use |
154
+ |---|---|
155
+ | Plan or design a program, or decide which records it needs | `nonprofit-volunteer-management-structure-generate` |
156
+ | Create or reuse records, or know how to fill in a field | `nonprofit-volunteer-management-records-create` |
157
+
158
+ Those skills come back here only for what an entity or field means.
159
+
160
+ ## Reference File Index
161
+
162
+ | File | Read it for |
163
+ |---|---|
164
+ | `references/entities.md` | One entity's purpose, origin, Volunteer Management fields, picklist values and gotchas (workflow step 2) |
165
+ | `references/relationships.md` | How entities connect, delete behaviour, and how they combine into features; intent → entity lookup (workflow step 2) |
166
+ | `references/themes.md` | The design principles (T1–T26) behind the model's shape (workflow step 2) |
@@ -0,0 +1,315 @@
1
+ # Entity Reference — Volunteer Management Data Model
2
+
3
+ Every in-scope entity: **purpose/intent**, **origin** (native VM / reused-from-cloud / standard),
4
+ **VM-gated fields** (the only fields VM cares about on a borrowed entity), **key relationships**,
5
+ and **gotchas**. How to fill in fields when creating records is not here — that is records-create's
6
+ field guide.
7
+
8
+ Origin legend:
9
+ - **NATIVE** — defined by Volunteer Management itself.
10
+ - **REUSED (+VM fields)** — borrowed from another cloud; VM added gated field(s).
11
+ - **REUSED (as-is)** — borrowed; VM added nothing (used unchanged).
12
+ - **STANDARD** — core Salesforce object.
13
+
14
+ Theme references (`Tn`) point at `themes.md`.
15
+
16
+ ---
17
+
18
+ ## Picklists
19
+
20
+ **Restricted** means only the listed values are accepted; a customer can't add their own.
21
+ **Unrestricted** means the values are the customer's: admins add and change them, so the org's
22
+ object description is the only source for them. Either way, a record can only use a value that's in the list,
23
+ so a new value is added to the list before it's used.
24
+
25
+ | Picklist | Values | Kind |
26
+ |---|---|---|
27
+ | `VolunteerInitiative.Status` | Upcoming, In Progress, Complete, Canceled, Postponed, Archived | unrestricted |
28
+ | `Position.Status`, `JobPosition.Status`, `JobPositionShift.Status` | Upcoming, In Progress, Complete, Canceled | unrestricted |
29
+ | `JobPositionAssignment.Status` | Awaiting Approval, Upcoming, In Progress, Pending Verification, Complete, Canceled, Absent | unrestricted |
30
+ | `ConstituentRole.RoleType` | Donor, Philanthropic Prospect, **Volunteer**, Participant | unrestricted |
31
+ | `ConstituentRole.Status` | Active, Former | unrestricted |
32
+ | Position/JobPosition Qualification `ProficiencyLevel` | Beginner, Intermediate, Advanced | unrestricted |
33
+ | `Location.LocationType` and `Address.LocationType` (one shared set), `Address.AddressType` | Business Site | unrestricted |
34
+ | `Position.Type`, `Position.Sensitivity`, `Position.ScheduleType`, `Competency.Category` | none (customers add their own) | unrestricted |
35
+ | `Examination.Status` | Active, Inactive | unrestricted |
36
+ | `TimeSlot.DayOfWeek`, `TimeSlot.Type`, the `TimeZone` fields | platform values | restricted |
37
+
38
+ **Record types:** VM ships no record types on its objects, but a customer may create some. Account
39
+ has Person Account record types.
40
+
41
+ **Note:** This is about picklist **values**. Rollup *field data* (DonorGiftSummary,
42
+ VolunteerInitiative) is still empty out of the box — a customer-built Data Processing Engine fills
43
+ it; see T12.
44
+
45
+ ---
46
+
47
+ ## Identity anchors
48
+
49
+ ### Account (Person Account) — STANDARD
50
+ **Purpose:** The volunteer. VM **requires Person Accounts enabled**; a volunteer is a Person
51
+ Account (authenticated identity). The "Business Account" in the diagram is just how Salesforce
52
+ renders Person Accounts — ignore that variant (T1).
53
+ **VM fields:** NONE. Account is a "hero" entity, deliberately hard to extend; volunteer data hangs
54
+ off related/extension entities instead (T4). The VM related lists on Account (Person Examinations,
55
+ Person Competency, Job Position Assignments, Person Location Availabilities) are UI only — they let
56
+ an internal user see at a glance what a volunteer is involved with.
57
+ **Gotcha:** Do not look for volunteer fields on Account. Look for a related entity.
58
+
59
+ ### Contact — STANDARD
60
+ **Purpose:** The **guest / pre-account** identity. Public Experience Cloud signup can create a
61
+ Contact with no Account yet. When the person creates/converts to a Person Account, later work links
62
+ to Account. Contact is the unauthenticated side of the boundary (T2, T10).
63
+ **VM fields:** NONE.
64
+ **Gotcha:** Guest contact forms can create the same person many times with no dedup — this "Contact
65
+ bloat" is *why* data-persisting entities require an authenticated Account (T10).
66
+
67
+ ---
68
+
69
+ ## Who-is-a-volunteer / engagement
70
+
71
+ ### ConstituentRole — REUSED (as-is; Education/Industries)
72
+ **Purpose:** Marks a **Person Account as a volunteer**. This is the flag that scopes who engagement
73
+ rollups apply to.
74
+ **Key fields:** `RoleType` (picklist — ships with **"Volunteer"** plus Donor, Philanthropic
75
+ Prospect, Participant, T6); `Status` (picklist — Active, Former) + `EffectiveStartDate`/
76
+ `EffectiveEndDate` (standing active/inactive status, T5).
77
+ **Relationship intent:** Informational/standing identity marker. Do **not** confuse with
78
+ JobPositionAssignment (the operational act). ConstituentRole = "is a volunteer"; JPA = "did a job."
79
+ **Gotcha:** VM adds no fields; it relies entirely on `RoleType`, which already has the
80
+ "Volunteer" value out of the box (see the picklist table above).
81
+
82
+ ### DonorGiftSummary — REUSED (+VM fields; Fundraising)
83
+ **Purpose:** Per-person engagement summary. VM added **volunteer** rollups here —
84
+ not on a new entity — because **a volunteer is assumed likely also a donor** (T14), so an org sees
85
+ giving + volunteering in one place. `Donor` is master-detail → Account.
86
+ **VM-gated fields (4; all rollups calculated by a scheduled Data Processing Engine job — NOT real-time):**
87
+ - `TotalVolunteerHours` (DOUBLE) — total hours volunteered.
88
+ - `TotalVolunJobPstnAsgnCnt` (INTEGER) — number of job position assignments.
89
+ - `FirstVolunJobPstnAsgntDt` (DATEONLY) — first volunteer shift date.
90
+ - `LastVolunJobPstnAsgntDate` (DATEONLY) — most recent volunteer shift date.
91
+ **CRITICAL — not shipped populated:** there is **no Data Processing Engine definition out of the
92
+ box**. The customer must create and schedule one to fill these (T12). They exist empty until then.
93
+ **CRITICAL — description correction:** the field's description text says these aggregate JPAs "related
94
+ to a volunteer initiative." That is **misleading** (T13). Real intent: **any JobPositionAssignment on the Person
95
+ Account** (VolunteerInitiative linkage is NOT a filter). These rollups only count JPAs that have an
96
+ `AssignedAccount` — see JobPositionAssignment.
97
+
98
+ ---
99
+
100
+ ## Matching profile (what the volunteer can do) — the Volunteer Matching feature (T9)
101
+
102
+ ### PersonLocationAvailability (PLA) — NATIVE (generic-but-VM-only-customer, T11)
103
+ **Purpose:** The **when + where** a volunteer can serve. Volunteer-supplied via Experience Cloud or
104
+ other means ("I'm available at these times in these locations"). One leg of Volunteer Matching (T9).
105
+ **Key fields/rels:** `Account` (**required** — authenticated only, prevents guest bloat, T10/T16),
106
+ `Contact` (optional), `Location` (**required** — where), `OperatingHours` (optional — when, via its
107
+ TimeSlots), `UsageType` (**required** picklist — discriminator; PLA was built generic so any product
108
+ could adopt it, and VM is the only current customer; VM's records carry the VM usage value, T11).
109
+ **Chain:** TimeSlot → OperatingHours → PLA (+ Location).
110
+ **Gotcha:** Availability is **authenticated-only** by design (Account required).
111
+
112
+ ### PersonCompetency — REUSED (as-is; Position Recruitment)
113
+ **Purpose:** A skill the volunteer **holds** (supply side of matching). Declared by the volunteer
114
+ via Experience Cloud OR set by an internal user.
115
+ **Key fields:** `Person` is polymorphic → **Account, Contact** — already supports Account,
116
+ so **VM added nothing** (contrast PersonExamination). `Competency` → Competency. `QualificationLevel`
117
+ (a number — **the field matching reads**); `ProficiencyLevel` (picklist — not read by matching);
118
+ `VerificationStatus`/`VerificationDate`/`VerificationSummary`.
119
+ **Verification fields are NOT used in matching.** `VerificationStatus`/`VerificationDate`/
120
+ `VerificationSummary` record whether a manager has vetted a claimed skill, but matching does **not**
121
+ read them — it does not weigh verified vs merely claimed. They are informational only.
122
+ **Gotcha — matching reads `QualificationLevel` only.** A volunteer matches when their
123
+ `PersonCompetency.QualificationLevel` is at or above the required level. `ProficiencyLevel` is never
124
+ read, so a skill recorded only with a ProficiencyLevel doesn't help a volunteer match.
125
+ **Don't use PersonCompetency for interests or preferences** (e.g. a cause the volunteer cares about):
126
+ it feeds matching, so a non-skill entry distorts who matches.
127
+
128
+ ### PersonExamination — REUSED (+VM field; Public Sector)
129
+ **Purpose:** A credential/exam the volunteer **holds**.
130
+ **Not used by automated Matching today.** The Volunteer Matching feature does **not** read
131
+ PersonExamination — it is not a factor in automated matching as currently shipped. It is still
132
+ useful **internally**: a volunteer manager (user) can review a volunteer's held credentials to
133
+ find the right volunteer for a role and confirm they are qualified before assigning them.
134
+ **VM-gated field:** `Account` (FK → Account, org-gated). Native person link is **Contact** only; VM
135
+ added `Account` because credentials assigned via the Experience Cloud portal require an
136
+ **authenticated Person Account** (T16). Asymmetry vs PersonCompetency is purely mechanical
137
+ (PersonCompetency's polymorphic Person already had Account; this one didn't).
138
+ **Other rels:** `Contact` (required), `Examination` (FK).
139
+
140
+ ### Competency — REUSED (as-is; Position Recruitment)
141
+ **Purpose:** The definition of a skill or expertise, shared by every record that refers to it. Used unchanged; no VM fields. The demand side
142
+ (PositionQualification and JobPositionQualification) and supply side (PersonCompetency) both point
143
+ at it.
144
+
145
+ ### Examination — REUSED (as-is; Public Sector)
146
+ **Purpose:** The definition of an authorized exam or credential. Used unchanged; no VM fields. Both
147
+ the requirements (PositionQualification and JobPositionQualification) and the held credential
148
+ (PersonExamination) point at it — but none of these participate in automated matching (T9). An
149
+ Examination qualification is optional and informational: a manager reviews it, matching doesn't.
150
+
151
+ ### TimeSlot — REUSED (as-is; Field Service)
152
+ **Purpose:** One **weekly-recurring availability window** (`DayOfWeek` + `StartTime` + `EndTime`) inside
153
+ an OperatingHours — the atomic unit of "I'm free then." Master-detail child of OperatingHours; times
154
+ are interpreted in the parent's `TimeZone`. `Type` is unused by VM. No VM fields.
155
+
156
+ ### OperatingHours — REUSED (as-is; Field Service)
157
+ **Purpose:** A named set of weekly TimeSlots plus the `TimeZone` they're read in (it also has a
158
+ `Description`). A PLA points at one (FK `OperatingHours`, optional). An OperatingHours isn't tied to
159
+ a person or a Location: several PLAs with the same weekly windows can share one. No VM fields.
160
+
161
+ **Modeling availability:** **1 PLA = 1 Location + 1 OperatingHours**, and **one TimeSlot per weekly
162
+ window**. "Free Mon mornings and Sat afternoons at the SF site" → 1 PLA → 1 OperatingHours (TimeZone =
163
+ SF) → 2 TimeSlots. A **different Location is a separate PLA**.
164
+ **Matching (T9):** with a shift time filter, a TimeSlot must **contain** the shift window (day-of-week +
165
+ time-of-day); with none, matching falls back to Location-only. A PLA with no OperatingHours/TimeSlot is
166
+ dropped from time-based matches.
167
+
168
+ ### Location — STANDARD
169
+ **Purpose:** The "where" — a physical/logical place. Referenced by PLA (availability) and by
170
+ JobPosition (where the job is, optional). No VM fields. The Location link on JobPosition is what ties
171
+ availability to opportunities in matching.
172
+
173
+ ### Address — STANDARD
174
+ **Purpose:** The street address of a Location. Master-detail child of Location (deleting a Location
175
+ deletes its Addresses); a Location's `VisitorAddressId` points at the one shown to visitors. A
176
+ virtual Location may have none. `LocationType` and `AddressType` are unrestricted picklists; each ships
177
+ with Business Site. No VM fields.
178
+
179
+ ---
180
+
181
+ ## The work backbone (Position → JobPosition → Shift → Assignment)
182
+
183
+ ### Position — REUSED (+VM field; Position Recruitment)
184
+ **Purpose:** The reusable **template** for a job to be done (T15). Carries PositionQualifications.
185
+ Does not itself carry a Location and does not link down to JobPosition (JobPosition links up).
186
+ `Status` is an unrestricted picklist (Upcoming, In Progress, Complete, Canceled, T24).
187
+ **VM-gated field:** `IsInternalApprovalRequired` (BOOLEAN). When true, signup for a JobPosition
188
+ under this Position needs internal approval. **The field is inert on its own** — it is a hook for
189
+ Salesforce **Approvals**; approval ultimately advances JobPositionAssignment.Status (T18, T26).
190
+ Placed at the **template** level on purpose: approval is a property of the role.
191
+
192
+ ### PositionQualification — NATIVE
193
+ **Purpose:** A requirement the **template** demands (demand side of matching).
194
+ **Fields:** `Position` (master-detail, required), `Description`, `QualificationReferenceRecordId`
195
+ (polymorphic — **Competency or Examination only**, T17), `QualificationLevel` (number),
196
+ `ProficiencyLevel` (picklist — Beginner, Intermediate, Advanced). There is **no `Type` field**; what
197
+ a qualification refers to is the type of its QualificationReferenceRecord.
198
+ **Matching (T9):** uses QualificationLevel on Competency qualifications — "at or above the required
199
+ level," not just "has." Examination qualifications are ignored, a qualification with no
200
+ QualificationLevel is skipped, and ProficiencyLevel is never read.
201
+
202
+ ### JobPosition — REUSED (+VM field; Position Recruitment)
203
+ **Purpose:** The concrete **posting** — optionally at a **Location** — that references its
204
+ **Position** via a **lookup** (restrict — a Position that still has postings can't be deleted; nothing
205
+ is copied from it). This is the operational anchor: **Shift and Assignment attach ONLY to
206
+ JobPosition, never Position** (T15). A JobPosition is required for any scheduling/matching.
207
+ **Qualifications are checked together, never copied.** Template-wide requirements live on the
208
+ Position; per-posting extras live on the JobPosition (`JobPositionQualification`). Matching checks a
209
+ Job Position's own qualifications and its Position's qualifications together, keeping the higher
210
+ level per Competency. Nothing is copied from the Position to the Job Position. The Position's
211
+ qualifications are *shown* on the JobPosition through a computed related list, which is why it can
212
+ look like inheritance.
213
+ **VM-gated field:** `VolunteerInitiative` (FK, org-gated) — optional link to the organizing
214
+ initiative (T21). `Location` (FK, optional) is what matching compares against PLA; a JobPosition
215
+ with no Location can't match on availability. `Status` is an unrestricted picklist (Upcoming, In
216
+ Progress, Complete, Canceled, T24).
217
+ **Required text fields:** `Name` and `Title` are both required and are separate fields. How to fill
218
+ them is records-create's job.
219
+
220
+ ### JobPositionQualification — NATIVE
221
+ **Purpose:** A requirement **added to a specific posting** beyond the template's (e.g. an extra
222
+ certification required only at the SF location). Same shape as PositionQualification but
223
+ `JobPosition` (master-detail, required) + `QualificationReferenceRecordId` {Competency, Examination}.
224
+ **Canonical example:** one Position "Delivery Driver" (requires license) → two JobPositions NY & SF;
225
+ add a JobPositionQualification (certification) to SF only. NY needs license; SF needs license + cert.
226
+
227
+ ### JobPositionShift — NATIVE
228
+ **Purpose:** The **concrete dated/timed occurrence** volunteers actually sign up for (e.g. "Tue
229
+ 9–12 at SF"). Bottom of the backbone above the assignment.
230
+ **Key rels:** `JobPosition` (FK, **required**; deleting the JobPosition deletes its shifts);
231
+ `RecurrenceSchedule` (FK, optional).
232
+ **Scheduling fields — exact API names (a common guess-trap):** `StartDate`/`EndDate` (DATE) and
233
+ `StartTime`/`EndTime` (TIME) are **four separate date-and-time fields** plus `TimeZone` (picklist,
234
+ IANA names e.g. `America/Los_Angeles`). There is **NO `StartDateTime`/`EndDateTime`** on this object —
235
+ do not invent them. (The combined-datetime shape you may be reaching for is `ScheduledStartTime`/
236
+ `ScheduledEndTime` on the **different** object JobPositionAssignment.) `Name` is **auto-numbered**.
237
+ **Capacity model (T22, optional) — counted, never enforced:** `MaximumAttendeesCount` (the
238
+ intended limit); `PositionAssignmentCount` (recounted by a hook whenever a JPA is saved or deleted:
239
+ it counts the shift's JPAs with `DoesCountTowardShiftCapacity = true`, which defaults to true, in any
240
+ status — NOT a rollup); `RemainingCapacity` (formula = MAX(0, Max − Count) when both are set and Max
241
+ is above 0; otherwise blank). `Status` is an unrestricted picklist (Upcoming, In Progress, Complete,
242
+ Canceled, T24).
243
+ **Gotcha:** Nothing blocks a signup when a shift is full. A customer who wants a hard limit adds
244
+ their own validation rule.
245
+
246
+ ### RecurrenceSchedule — STANDARD (platform scheduling)
247
+ **Purpose:** Out-of-the-box recurrence *pattern definition* (not a shift) that generates `JobPositionShift`
248
+ occurrences via `JobPositionShift.RecurrenceSchedule` (FK, optional). The UI owns it; records-create writes discrete `JobPositionShift` rows instead.
249
+ **Real fields (guess-trap — do NOT invent cadence fields):** cadence lives in `ScheduleFrequency` (req) + `ScheduleDayValue`; also `ProcessName` (req), `StartDate` (**DATETIME**, req), `NextScheduleDateTime` (req), plus `EndDate`/`TotalRecurrencesCount`/`CompletedScheduleCount`/`ReferenceRecordId` bookkeeping. **NO** `RecurrenceType`/`RecurrenceInterval`/`DayOfWeek`/`DayOfMonth`/`MaxOccurrences`.
250
+
251
+ ### JobPositionAssignment (JPA) — NATIVE
252
+ **Purpose:** A person assigned to a job on a specific day — the **act of volunteering** and the
253
+ **single source of truth for hours served**. Everything engagement-related is measured from here.
254
+ **Person link — both optional:** `AssignedAccount` (Account) + `AssignedContact` (Contact). A guest
255
+ can create a Contact-only JPA; the org can later attach the Account (manual — **no automation out of the box**).
256
+ **`AssignedAccount` gates per-person (DGS) rollups only** (T2/T16): a JPA feeds a person's volunteer
257
+ totals only if it has an `AssignedAccount` — a Contact-only JPA doesn't roll up until an Account is
258
+ attached. **VolunteerInitiative rollups are unaffected** — they aggregate JPAs by
259
+ `RelatedVolunteerInitiative`, so the person link (`AssignedAccount` *or* `AssignedContact`) doesn't
260
+ matter for them.
261
+ **Parent links — all optional, any mix (T7):** `AssignedPositionShift` (JobPositionShift), `JobPosition`,
262
+ `RelatedVolunteerInitiative` (VolunteerInitiative; this FK is itself VM-gated). Standalone ad-hoc is
263
+ allowed — no parent is mandatory.
264
+ **Key fields:** `ScheduledStartTime`/`ScheduledEndTime` (what they signed up for) vs
265
+ `ActualStartTime`/`ActualEndTime` (what really happened) — commitment vs reality, kept separate on
266
+ purpose. `ActualDuration` (DOUBLE, hours) — the hours source for rollups; **NOT auto-computed out of the box**
267
+ because it must stay editable (auto-calc would overwrite manual edits) — customer can build their
268
+ own. `Status` (required picklist — Awaiting Approval, Upcoming, In Progress, Pending
269
+ Verification, Complete, Canceled, Absent; T24/T26). `DoesCountTowardShiftCapacity` (BOOLEAN,
270
+ default true, per-assignment) — so a waitlisted JPA needn't be counted (T22).
271
+
272
+ ---
273
+
274
+ ## Organizing anchor
275
+
276
+ ### VolunteerInitiative (VI) — NATIVE
277
+ **Purpose:** "All volunteer activities within a single volunteering initiative" — the **logical
278
+ top-level** object. Optional parent of JobPosition/Shift/Assignment; ad-hoc work with no VI is
279
+ allowed (T21).
280
+ **Self-referential tree:** `ParentVolunteerInitiative` (FK → self, optional) — a real hierarchy
281
+ (e.g. "2026" → "Fall Food Drive" → "Thanksgiving Week"); rollups aggregate **up** to parents.
282
+ **Rollup fields (6; shipped but NOT populated — the customer builds a Data Processing Engine job, T12):**
283
+ `TotalVolunteerHours`, `TotalActiveVolunteerCount` (unique active volunteers meeting the customer's
284
+ configured eligibility), `AttendanceRate` (PERCENT — % who fulfilled commitments to date),
285
+ `OpenAssignmentCount`, `FilledAssignmentCount`, `TotalAssignmentCount` (open + filled).
286
+ `TotalActiveVolunteerCount`/`AttendanceRate` depend on **customer configuration** of which JPA
287
+ `Status` values count — VM ships no fixed eligibility store.
288
+ **Other fields:** `Status` (unrestricted picklist — Upcoming, In Progress, Complete, Canceled,
289
+ Postponed, Archived; T24), `StartDate`/`EndDate`,
290
+ `IsPublished` (BOOLEAN — intended to signal visibility in Experience Cloud, but **not automated
291
+ out of the box**: nothing flips it or gates visibility on it automatically — the customer wires it into their
292
+ site). VI being "top" is a data-model statement;
293
+ customers can build their Experience Cloud site to let volunteers browse JobPositions/Shifts however.
294
+
295
+ ---
296
+
297
+ ## Cross-product bridge (requires two clouds)
298
+
299
+ ### PositionBenefit — NATIVE (requires VM AND Benefit Management)
300
+ **Purpose:** Bridges Volunteering ↔ Benefit Management: **volunteers provide a service that
301
+ beneficiaries receive as a Benefit** (T19). NOT perks for volunteers. Ties a Position to the
302
+ Benefits that position provides.
303
+ **Compound gating (T20):** `userHasVolunteerManagement && userHasBenefitManagement` — unusable
304
+ unless BOTH clouds are enabled — the org needs Benefit Management as well as VM. The `&&` signals a
305
+ deliberate cross-product bridge.
306
+ **Key rels:** `Position` (master-detail, required — attaches to the **template**, since all its
307
+ JobPositions provide the same service); `Benefit` (lookup, required) → **Benefit is OUT OF SCOPE**
308
+ (Program Management). Treat Benefit as an external dependency; do not model it.
309
+
310
+ ---
311
+
312
+ ## Entities to IGNORE
313
+
314
+ ### ContactProfile — REUSED (Education), but IGNORE
315
+ Appears in the diagram, but VM adds nothing to it (no VM-gated fields). Treat as noise; do not model.