education-cloud-multi-campus-configure
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEducation Cloud Multi-Campus Institutional Hierarchy Configuration
Education Cloud 多校区机构层级配置
Guides Salesforce Administrators through the full lifecycle of an institutional hierarchy: initial creation AND ongoing maintenance. Parses organizational structure from documents, URLs, CSV, or text, then either builds the hierarchy from scratch or reconciles it against what already exists in the org — creating only the delta. Supports any number of hierarchy levels (e.g., System → Campus → College → Department, or System → Region → Campus → Division → Department) based on the input. Creates/updates Account records with parent-child relationships and Business Profiles for each level, derives materialized paths on the fly for semantic navigation, and validates the result.
为Salesforce管理员提供机构层级的全生命周期指导:从初始创建到持续维护。可从文档、URL、CSV或文本中解析组织结构,然后从头构建层级,或与组织中已有的层级进行比对——仅创建差异部分。支持基于输入的任意数量层级(例如:System → Campus → College → Department,或System → Region → Campus → Division → Department)。创建/更新带有父子关系的Account记录,并为每个层级生成Business Profile,动态推导物化路径以实现语义导航,同时验证结果。
Mechanism
机制
Try first for every Account/BusinessProfile read or write — reads via , writes via (see for call shape, response envelope, and per-step invocations). Probe with before the first call: 2xx → route everything through it. Absent/4xx/5xx → probe other available transports (another Salesforce MCP server, or authenticated CLI) with the same read, use the first healthy one, and tell the user which transport is in use. None healthy → stop, ask the user to connect one; never fabricate a result.
headless-360dispatch_readonlydispatchreferences/mcp-invocation.mdGET /services/data/vXX.0/limitssf对于所有Account/BusinessProfile的读写操作,优先使用****——通过进行读取,通过进行写入(调用格式、响应包和分步调用请参见)。首次调用前,先通过进行探测:返回2xx状态码→所有操作都通过它路由;返回不存在/4xx/5xx→使用相同的读取操作探测其他可用传输方式(另一台Salesforce MCP服务器或已认证的 CLI),使用第一个可用的传输方式,并告知用户当前使用的传输方式。若没有可用的传输方式→停止操作,请求用户连接一个;绝不能编造结果。
headless-360dispatch_readonlydispatchreferences/mcp-invocation.mdGET /services/data/vXX.0/limitssfScope
范围
- In scope: Parsing institutional structure from PDF/URL/text/CSV with any number of hierarchy levels (2+); new setup (create full hierarchy); update/reconcile (compare desired structure to the org's current hierarchy and apply only the delta — add new nodes, rename a node, move a node under a different parent); creating Account hierarchy with parent-child relationships via ParentId; generating Business Profiles for all levels; deriving materialized paths on demand from the parent chain; validating parent-child relationships; handling API errors during bulk create/update
- Out of scope: Deleting Account or Business Profile records (destructive — report extras, do not delete unless the user explicitly confirms per Step 7); single-level flat structures (no parent-child relationships); non-Education-Cloud account management; migrating field data between hierarchy nodes
- 包含范围:从PDF/URL/文本/CSV解析任意数量层级(2层及以上)的机构结构;全新设置(创建完整层级);更新/比对(将目标结构与组织当前层级进行比较,仅应用差异部分——添加新节点、重命名节点、将节点移动至不同父节点下);通过ParentId创建带有父子关系的Account层级;为所有层级生成Business Profile;根据父链按需推导物化路径;验证父子关系;处理批量创建/更新过程中的API错误
- 排除范围:删除Account或Business Profile记录(具有破坏性——仅报告多余记录,除非用户在步骤7中明确确认,否则不得删除);单层扁平结构(无父子关系);非Education Cloud的账户管理;在层级节点之间迁移字段数据
Required Inputs
必要输入
Gather or infer before proceeding:
- Organizational structure source (the desired structure): PDF document path, website URL, CSV, or plain text description
- System name: Top-level institutional system name (e.g., "Riverside Community College System")
- Hierarchy levels: All organizational levels present (Campus, College, Department, Division, Region, etc.) — infer from parsing, do not assume a fixed 4-level structure
- Mode hint (optional): Whether this is a first-time build or an update to an existing hierarchy. If not stated, detect in Step 4.
- Existing root (update mode only): The System (root) Account Id, so the current hierarchy can be traversed. A prior run of this skill prints this Id in its summary (Step 10).
Defaults unless specified:
- Record type for all accounts: resolve from org (do not hardcode) — see Step 3.5
- Business Profile creation: Enabled for every hierarchy level that lacks one
- Materialized path: Not a stored field — derived on the fly by walking the Account's ParentId chain to the System root when displaying a path
- Naming convention: Title Case with spaces preserved
- Deletion: Never automatic — extra nodes in the org are reported, not removed
If the user provides a complete hierarchy description or document, parse and confirm the structure before creating or changing records.
在开始前收集或推断:
- 组织结构来源(目标结构):PDF文档路径、网站URL、CSV或纯文本描述
- 系统名称:顶级机构系统名称(例如:"Riverside Community College System")
- 层级级别:所有存在的组织级别(Campus、College、Department、Division、Region等)——从解析结果中推断,不要假设固定的4层结构
- 模式提示(可选):这是首次构建还是对现有层级的更新。若未说明,在步骤4中检测。
- 现有根节点(仅更新模式):System(根节点)的Account Id,以便遍历当前层级。此Skill的上一次运行会在摘要(步骤10)中打印此Id。
默认设置(除非指定):
- 所有账户的记录类型:从组织中解析(不要硬编码)——参见步骤3.5
- Business Profile创建:为每个缺少它的层级启用
- 物化路径:不是存储字段——当显示路径时,通过遍历Account的ParentId链至System根节点动态推导
- 命名规范:保留空格的标题大小写
- 删除操作:绝不会自动执行——仅报告组织中的多余节点,不删除
如果用户提供完整的层级描述或文档,在创建或修改记录前,先解析并确认结构。
Workflow
工作流程
All steps are sequential. Do not skip or reorder. If blocked, stop and ask for missing context.
-
Verify foundation prerequisites — Follow: org edition, Lightning Experience, Education Cloud license, running user's Full Access assignment, Education Cloud Foundation enabled (self-heal via confirm-then-enable if off). Do not proceed to Step 1 until all checks pass.
references/foundation_prerequisites.md -
Understand input format
- Ask user for organizational structure source: PDF path, URL, CSV, or text description
- If PDF: use Read tool to extract text content
- If CSV: read columns (see
Name,LevelType,Level,ParentNamefor the expected shape;examples/sample_hierarchy_input.csvshows duplicate names, abbreviations, and an orphaned parent reference)examples/sample_hierarchy_input_edgecases.csv - If URL: recommend to user that a trusted structured dataset (JSON/CSV) is the preferred input — web crawl results can be incomplete, inaccurate, or out of date, and some institutional sites block crawling. If the URL is not blocked it will still work. Then fetch and parse HTML to extract hierarchy information
- If the URL fetch is blocked or fails: do NOT silently substitute a different source (e.g. a search/research agent pulling from Wikipedia or another third-party site). Stop and ask the user for an alternative — a PDF, CSV, or pasted text from the institution's own site. The customer must never be left unaware of what their hierarchy was actually built from
- If text: parse directly from user's message
-
Parse desired hierarchy structure
- Extract System name (top level)
- Identify all hierarchy levels present (e.g., Campus, College, Department, Division, Region, etc.)
- Build parent-child relationships for each node based on nesting/indentation in source
- Store the desired structure as a tree: each node has Name, Level, and ParentNode reference
- For ambiguous structures, read for decision logic
references/hierarchy_parsing_rules.md - Do not assume fixed level names — use whatever level names appear in the source (Campus/Location/Site are equivalent, College/School/Faculty are equivalent, Department/Division/Program are equivalent)
-
Confirm desired structure with user
- Display extracted hierarchy in nested bullet format — see for the box-drawing template and formatting rules.
examples/hierarchy_visualization.md - Ask: "Is this structure correct?" (Yes/Make changes/No)
- If "Make changes": gather corrections and re-display
- If "No": stop workflow
- Display extracted hierarchy in nested bullet format — see
3.5. Resolve Account RecordType from org
- Do NOT hardcode a RecordType Id or DeveloperName. Resolve the org's actual Account RecordType at runtime via describe (RecordType metadata like /
developerNameisn't exposed through a plain Account SOQL query — describe is the correct source):available- via
GET /services/data/v68.0/sobjects/Account/describe(seedispatch_readonly)references/mcp-invocation.md - Read the array from
recordTypeInfos. Each entry hasbody,developerName,name,recordTypeId,available.defaultRecordTypeMapping
- Select the institutional/business RecordType by (varies by org, e.g.
developerName,Business). Ignore theBusiness_Accountsentry (Master) — not selectable for records.developerName = "Master" - Selection logic:
- If exactly one non-Master RecordType → use it.
available:true - If multiple candidates → ask user which to use.
developerName - If NO non-Master RecordType exists → missing prerequisite, not a dead end (common when this skill runs standalone, without a prior EDU setup skill). Follow : ask for/confirm a Label, confirm before creating, create via Tooling API, cold-verify
references/account_recordtype_prerequisite.md.available:true
- If exactly one non-Master
- Capture that entry's into a runtime variable
recordTypeId(a resolved value from THIS org's describe response — never a literal copied into the skill). UserecordTypeIdfor every Account create in Step 6.recordTypeId
-
Determine mode: new setup vs. update
- Decide whether the org already has this hierarchy:
- If the user states it is a first-time build, or no System (root) Account exists → Case 1 (New setup).
- If the user states it is an update/reorg, or supplies an existing System (root) Account Id → Case 2 (Update/reconcile).
- If unclear, ask: "Is this a brand-new hierarchy, or an update to one already in the org? If it exists, give me the System (root) Account Id (printed by the previous run's summary)."
- Case 1 → skip to Step 6 with an empty (every desired node is new).
existingTree - Case 2 → proceed to Step 5.
- Decide whether the org already has this hierarchy:
-
(Update mode) Load current hierarchy and compute the delta
- Traverse the current tree from the System Account Id (children level-by-level via , SOQL fallback), match desired vs. current by Name within sibling group, and classify each node as reuse / CREATE / EXTRA / RENAME / MOVE — full matching and cycle-rejection algorithm in
ChildAccounts.references/delta_computation.md - Result: a delta list of CREATE / RENAME / MOVE actions plus an EXTRA report (extras are reported, never deleted). If the delta is empty and no renames/moves were requested, tell the user the org already matches the desired structure and skip to Step 9 (verify).
- Traverse the current tree from the System Account Id (children level-by-level via
-
Preview before any write
- Show a summary BEFORE writing any records — new setup shows counts per level + RecordType; update/reconcile shows the delta explicitly (create/rename/move/unchanged/extra). See for both templates.
examples/output_examples.md - If any EXTRA nodes exist and the user wants them removed, that deletion is destructive — confirm each explicitly in Step 7; default is to leave them.
- Ask: "Proceed with these changes?" (Yes/No). If "No": stop workflow.
- Show a summary BEFORE writing any records — new setup shows counts per level + RecordType; update/reconcile shows the delta explicitly (create/rename/move/unchanged/extra). See
-
Apply changes (create / rename / move)
- Once the user confirmed in Step 6, apply the delta via the transport resolved in Mechanism — call shapes for create/rename/move/delete are in (Step 7). Capture each created Account's returned Id. Do not stop at a "pending"/"intended delta" plan — the confirmation is the go-ahead.
references/mcp-invocation.md - Order matters: process CREATE actions in depth-first order (create parent before children); apply MOVE and RENAME after creates so parent Ids resolve.
- Create: body uses (the field the Data API sObject POST accepts) — NOT a nested
RecordTypeId/RecordTypeobject, which the sObject create endpoint rejects. Value is theDeveloperNamevariable resolved from describe in Step 3.5 — never a hardcoded 18-char Id. For the System (top level, new setup only), OMITrecordTypeIdentirely (do not sendParentId). Store returned Account ID:nullaccountMap[NodeId] = response.body.id - Rename: patch only. Move: patch
Nameonly (cycle already rejected in Step 5).ParentId - Deletion (only if the user explicitly confirmed an EXTRA node for removal in Step 6): confirm the specific node once more, then delete. Skip by default.
- Print progress after each level/action:
[action] applied: [count] Accounts ([level name]) - Handle API errors per
references/error_handling.md - Repeat for all levels — do not hardcode level count or names
- Once the user confirmed in Step 6, apply the delta via the transport resolved in Mechanism — call shapes for create/rename/move/delete are in
-
Create Business Profiles (new/changed Accounts only)
- For each Account created in Step 7 that does not already have a Business Profile:
- with body
POST /services/data/v68.0/sobjects/BusinessProfile(see{AccountId})references/mcp-invocation.md - (Name field auto-populated from Account — do not set)
- Do NOT create duplicate Business Profiles for Accounts that already had one (reused nodes in update mode) — BusinessProfile is 1:1 with Account.
- warning: if the user asks to populate
InstitutionTypeon a Business Profile, note that it is a managed, restricted picklist (typicallyInstitutionType/Public/Privateonly — cannot be extended). For institutions outside that K-12/higher-ed taxonomy (e.g. vocational/trade, allied health, satellite/extension campuses), there is no valid value that fits. Tell the user this upfront rather than guessing or silently picking the closest match, and offerCharteras the only available workaround field for that nuance — it is not a substitute for a real categorization field.Description - Print:
[Total N] Business Profiles created and linked - Handle API rate limits per (retry with exponential backoff)
references/error_handling.md
- For each Account created in Step 7 that does not already have a Business Profile:
-
Verify hierarchy (cold verification)
- on a write is not proof. Cold
success:true(viaGET /services/data/v68.0/sobjects/Account/[Account Id]) on each affected Account (created, renamed, moved, and their parents); readdispatch_readonly,Name,ParentId. Confirm:RecordTypeIdresolves the expected parent (System hasParentId, no orphans);ParentId: nullmatches Step 3.5's resolved value; RENAME/MOVE persisted correctly.RecordTypeId - Spot-check at minimum: the deepest leaf (full chain to System) + one node per top-level branch + every renamed/moved node.
- Print:
Hierarchy verification complete — [N] Accounts, parent chains valid, 0 orphans
-
Return structure summary (completion report)
- This report describes what was actually created/changed (past tense), not a plan. Lead with a success headline — e.g. for an update run,
# Institutional Hierarchy Expanded Successfullyfor new setup. If an output location was provided, you MUST actually write the report there as# Institutional Hierarchy Created Successfullyby invoking the file-write tool — do not merely print the report body in chat and claim it was saved; a described-but-unwritten file does not exist. Otherwise display it.report.md - Display hierarchy visualization (nested bullet format from Step 3, see )
examples/hierarchy_visualization.md - Show total counts per level: System (1), Level 1 name (N), Level 2 name (N), etc.
- For update mode, break down what changed: created, renamed, moved, unchanged, and any untouched extras.
- Print the System (root) Account Id so a future update run can reference it.
- Offer spot-check: "Would you like me to show the complete path for a specific node or verify any account?"
- If user requests spot-check, GET the specific Account, then GET each ancestor up the ParentId chain to the System root and join their Names with to display the materialized path (derived on the fly — no stored path field)
/
- This report describes what was actually created/changed (past tense), not a plan. Lead with a success headline — e.g.
所有步骤按顺序执行,不得跳过或重新排序。若遇到阻塞,停止操作并请求缺失的信息。
-
验证基础前提条件——遵循:组织版本、Lightning Experience、Education Cloud许可证、运行用户的完全访问权限分配、Education Cloud Foundation已启用(若关闭,通过确认后启用的方式自动修复)。在所有检查通过前,不得进入步骤1。
references/foundation_prerequisites.md -
了解输入格式
- 请求用户提供组织结构来源:PDF路径、URL、CSV或文本描述
- 若为PDF:使用读取工具提取文本内容
- 若为CSV:读取列(预期格式请参见
Name,LevelType,Level,ParentName;examples/sample_hierarchy_input.csv展示了重复名称、缩写和孤立父引用的情况)examples/sample_hierarchy_input_edgecases.csv - 若为URL:建议用户使用可信的结构化数据集(JSON/CSV)作为首选输入——网页爬取结果可能不完整、不准确或过时,部分机构网站会阻止爬取。若URL未被阻止,仍可正常工作。然后获取并解析HTML以提取层级信息
- 若URL获取被阻止或失败:请勿静默替换为其他来源(例如从维基百科或其他第三方网站获取的搜索/研究代理结果)。停止操作并请求用户提供替代来源——PDF、CSV或从机构自身网站复制的文本。绝不能让用户不知道其层级实际基于什么数据构建
- 若为文本:直接从用户消息中解析
-
解析目标层级结构
- 提取系统名称(顶层)
- 识别所有存在的层级级别(例如:Campus、College、Department、Division、Region等)
- 根据来源中的嵌套/缩进为每个节点建立父子关系
- 将目标结构存储为树状结构:每个节点包含Name、Level和ParentNode引用
- 若结构存在歧义,请阅读获取决策逻辑
references/hierarchy_parsing_rules.md - 不要假设固定的级别名称——使用来源中出现的任何级别名称(Campus/Location/Site视为等效,College/School/Faculty视为等效,Department/Division/Program视为等效)
-
与用户确认目标结构
- 以嵌套项目符号格式显示提取的层级——格式规则和方框绘制模板请参见
examples/hierarchy_visualization.md - 询问:"此结构是否正确?"(是/修改/否)
- 若选择"修改":收集修正信息并重新显示
- 若选择"否":停止工作流程
- 以嵌套项目符号格式显示提取的层级——格式规则和方框绘制模板请参见
3.5. 从组织中解析Account RecordType
- 不得硬编码RecordType Id或DeveloperName。运行时通过describe操作解析组织实际的Account RecordType(RecordType元数据如/
developerName无法通过普通的Account SOQL查询获取——describe是正确的数据源):available- 通过调用
dispatch_readonly(请参见GET /services/data/v68.0/sobjects/Account/describe)references/mcp-invocation.md - 从中读取
body数组。每个条目包含recordTypeInfos、developerName、name、recordTypeId、availabledefaultRecordTypeMapping
- 通过
- 通过选择机构/业务RecordType(因组织而异,例如
developerName、Business)。忽略Business_Accounts条目(Master)——不可用于记录developerName = "Master" - 选择逻辑:
- 若恰好有一个非Master且的RecordType→使用它
available:true - 若有多个候选→询问用户使用哪个
developerName - 若不存在非Master的RecordType→缺少前提条件,但并非死胡同(当此Skill独立运行且未预先运行EDU设置Skill时常见)。遵循:请求/确认标签,确认后创建,通过Tooling API创建,冷验证
references/account_recordtype_prerequisite.mdavailable:true
- 若恰好有一个非Master且
- 将该条目的捕获到运行时变量
recordTypeId中(来自当前组织describe响应的解析值——绝不能是复制到Skill中的文字值)。步骤6中创建每个Account时都使用recordTypeIdrecordTypeId
-
确定模式:全新设置 vs 更新
- 判断组织是否已存在此层级:
- 若用户声明这是首次构建,或不存在System(根节点)Account→案例1(全新设置)
- 若用户声明这是更新/重组,或提供了现有System(根节点)Account Id→案例2(更新/比对)
- 若不确定,询问:"这是全新的层级,还是对组织中已存在层级的更新?若已存在,请提供System(根节点)Account Id(上一次运行的摘要中已打印)。"
- 案例1→跳过步骤5,直接进入步骤6,为空(所有目标节点均为新节点)
existingTree - 案例2→进入步骤5
- 判断组织是否已存在此层级:
-
(更新模式)加载当前层级并计算差异
- 从System Account Id开始遍历当前树(通过逐层遍历,SOQL作为备选),在同级组内通过Name匹配目标结构与当前结构,将每个节点分类为复用/ CREATE / EXTRA / RENAME / MOVE——完整的匹配和循环拒绝算法请参见
ChildAccountsreferences/delta_computation.md - 结果:包含CREATE/RENAME/MOVE操作的差异列表,以及EXTRA报告(仅报告多余记录,绝不删除)。若差异为空且未请求重命名/移动,告知用户组织已与目标结构匹配,跳过至步骤9(验证)
- 从System Account Id开始遍历当前树(通过
-
写入前预览
- 在写入任何记录前显示摘要——全新设置显示每个层级的数量+RecordType;更新/比对模式显式显示差异(创建/重命名/移动/未更改/多余)。两种模板请参见
examples/output_examples.md - 若存在多余节点且用户想要删除,此操作具有破坏性——在步骤7中明确确认每个节点;默认保留
- 询问:"是否继续执行这些更改?"(是/否)。若选择"否":停止工作流程
- 在写入任何记录前显示摘要——全新设置显示每个层级的数量+RecordType;更新/比对模式显式显示差异(创建/重命名/移动/未更改/多余)。两种模板请参见
-
应用更改(创建/重命名/移动)
- 用户在步骤6中确认后,通过机制中解析的传输方式应用差异——创建/重命名/移动/删除的调用格式请参见(步骤7)。捕获每个创建的Account返回的Id。不要停留在"待处理"/"预期差异"计划阶段——确认后即可执行
references/mcp-invocation.md - 顺序至关重要:按深度优先顺序处理CREATE操作(先创建父节点,再创建子节点);在创建完成后应用MOVE和RENAME,以便解析父Id
- 创建:请求体使用(Data API sObject POST接受的字段)——不得使用嵌套的
RecordTypeId/RecordType对象,sObject创建端点会拒绝此类请求。值为步骤3.5中通过describe解析的DeveloperName变量——绝不能是硬编码的18位Id。对于System(顶层,仅全新设置),完全省略recordTypeId(不要发送ParentId)。存储返回的Account ID:nullaccountMap[NodeId] = response.body.id - 重命名:仅更新字段。移动:仅更新
Name字段(步骤5中已拒绝循环)ParentId - 删除(仅当用户在步骤6中明确确认删除某个多余节点时):再次确认具体节点,然后删除。默认跳过
- 每个层级/操作完成后打印进度:
[操作] 已应用:[数量] 个Accounts([层级名称]) - 根据处理API错误
references/error_handling.md - 重复处理所有层级——不要硬编码层级数量或名称
- 用户在步骤6中确认后,通过机制中解析的传输方式应用差异——创建/重命名/移动/删除的调用格式请参见
-
创建Business Profile(仅新建/更改的Accounts)
- 对于步骤7中创建的每个尚未拥有Business Profile的Account:
- 调用,请求体为
POST /services/data/v68.0/sobjects/BusinessProfile(请参见{AccountId})references/mcp-invocation.md - (Name字段会从Account自动填充——无需设置)
- 调用
- 不得为已拥有Business Profile的Account创建重复的Business Profile(更新模式中复用的节点)——BusinessProfile与Account是一对一关系
- 警告:若用户要求在Business Profile上填充
InstitutionType,请注意这是一个受管理的受限选择列表(通常仅包含InstitutionType/Public/Private——无法扩展)。对于该K-12/高等教育分类之外的机构(例如职业/贸易、联合健康、卫星/延伸校区),没有合适的有效值。请提前告知用户,不要猜测或静默选择最接近的值,并提供Charter作为唯一可用的变通字段——它不能替代真正的分类字段Description - 打印:
已创建并关联 [总数量N] 个Business Profiles - 根据处理API速率限制(指数退避重试)
references/error_handling.md
- 对于步骤7中创建的每个尚未拥有Business Profile的Account:
-
验证层级(冷验证)
- 写入操作返回并不代表成功。对每个受影响的Account(创建、重命名、移动的Account及其父节点)执行冷
success:true(通过GET /services/data/v68.0/sobjects/Account/[Account Id]);读取dispatch_readonly、Name、ParentId。确认:RecordTypeId指向预期的父节点(System的ParentId,无孤立节点);ParentId: null与步骤3.5中解析的值匹配;重命名/移动操作已正确持久化RecordTypeId - 至少抽查:最深的叶子节点(到System的完整链)+每个顶层分支的一个节点+所有重命名/移动的节点
- 打印:
层级验证完成——[N]个Accounts,父链有效,0个孤立节点
- 写入操作返回
-
返回结构摘要(完成报告)
- 此报告描述实际创建/更改的内容(过去式),而非计划。以成功标题开头——例如,更新运行时为,全新设置时为
# 机构层级扩展成功。若提供了输出位置,必须通过调用文件写入工具将报告实际写入该位置的# 机构层级创建成功——不得仅在聊天中打印报告内容并声称已保存;描述但未写入的文件不存在。否则直接显示报告report.md - 显示层级可视化(步骤3中的嵌套项目符号格式,请参见)
examples/hierarchy_visualization.md - 显示每个层级的总数:System(1)、一级名称(N)、二级名称(N)等
- 对于更新模式,细分更改内容:创建、重命名、移动、未更改的数量,以及任何未触及的多余节点
- 打印System(根节点)Account Id,以便未来更新运行时引用
- 提供抽查选项:"是否需要我显示特定节点的完整路径或验证任何账户?"
- 若用户请求抽查,获取特定Account,然后遍历ParentId链至System根节点,获取每个祖先的Name,用连接以显示物化路径(动态推导——无存储的路径字段)
/
- 此报告描述实际创建/更改的内容(过去式),而非计划。以成功标题开头——例如,更新运行时为
Rules / Constraints
规则/约束
| Constraint | Rationale |
|---|---|
| Update mode changes only the delta — reuse existing Accounts, never recreate | Recreating produces duplicates and orphaned Business Profiles; reconcile is the correct maintenance model |
| Deletion is never automatic — report extras, delete only on explicit per-node user confirmation | Removing an Account cascades to its Business Profile and children; destructive and irreversible |
| System Account has no ParentId | Top-level account cannot reference a parent |
| Child ParentId must reference its immediate parent Account | Maintains tree structure integrity — children link to direct parent, not ancestors |
| Process CREATE in depth-first order; apply MOVE/RENAME after creates | ParentId references fail if parent doesn't exist yet |
| Reject a MOVE that places a node under its own descendant | Cycle would corrupt the tree; Salesforce also throws CIRCULAR_DEPENDENCY |
| BusinessProfile must link to exactly one Account via AccountId (1:1) | Required by Education Cloud; never create a second profile for an existing Account |
| All Account names must be unique within their sibling group | Delta matching keys on name-within-parent; duplicates make reconcile ambiguous |
Account RecordType resolved at runtime from Account describe, never hardcoded — capture | Hardcoded Id/DeveloperName silently mismatches other orgs; describe is the source of truth for RecordType metadata |
| Retry Business Profile creation on API rate limit | Bulk creation commonly hits rate limits; retry succeeds |
| Materialized path is derived on the fly (walk ParentId chain to root), not read from a stored field | No path column exists on Account; compute it by joining ancestor Names with |
| Support any number of levels (2+) | Do not hardcode level count — parse whatever structure appears in source |
| Keeps org auth on the session's bound OAuth JWT when available; falling back silently would hide which credential/transport actually made the change |
| Never silently substitute a different data source when the requested URL is blocked | Customer must know what their hierarchy was actually built from — ask for a PDF/CSV/pasted alternative instead |
| Guessing a value (or forcing the closest fit) misrepresents the institution's real category |
| 约束 | 理由 |
|---|---|
| 更新模式仅更改差异部分——复用现有Accounts,绝不重复创建 | 重复创建会产生重复记录和孤立的Business Profiles;比对是正确的维护模式 |
| 删除操作绝不会自动执行——仅报告多余记录,仅在用户明确确认每个节点时才删除 | 删除Account会级联删除其Business Profile和子节点;具有破坏性且不可逆 |
| System Account无ParentId | 顶级账户不能引用父节点 |
| 子节点的ParentId必须引用其直接父Account | 维护树结构完整性——子节点链接到直接父节点,而非祖先 |
| 按深度优先顺序处理CREATE操作;在创建完成后应用MOVE/RENAME | 若父节点不存在,ParentId引用会失败 |
| 拒绝将节点移动至其自身后代下的操作 | 循环会破坏树结构;Salesforce也会抛出CIRCULAR_DEPENDENCY错误 |
| BusinessProfile必须通过AccountId与恰好一个Account关联(一对一) | Education Cloud的要求;绝不为现有Account创建第二个Profile |
| 所有Account名称在同级组内必须唯一 | 差异匹配基于父节点下的名称;重复名称会导致比对歧义 |
Account RecordType在运行时通过Account describe解析,绝不硬编码——从 | 硬编码的Id/DeveloperName会在其他组织中静默不匹配;describe是RecordType元数据的可靠来源 |
| Business Profile创建遇到API速率限制时重试 | 批量创建通常会触发速率限制;重试可成功 |
| 物化路径通过遍历ParentId链至根节点动态推导,而非从存储字段读取 | Account上不存在路径列;当请求路径时,通过连接祖先的Name并使用 |
| 支持任意数量的层级(2层及以上) | 不要硬编码层级数量——解析来源中出现的任何结构 |
| 当可用时,保持组织认证在会话绑定的OAuth JWT上;静默回退会隐藏实际进行更改的凭证/传输方式 |
| 当请求的URL被阻止时,绝不静默替换为其他数据源 | 用户必须知道其层级实际基于什么数据构建——请求用户提供PDF/CSV/粘贴的替代文本 |
BusinessProfile上的 | 猜测值(或强制选择最接近的值)会错误代表机构的真实类别 |
Gotchas
注意事项
See for known failure modes and their resolutions (rename/delete ambiguity, duplicate update runs, paging, rate limits, ambiguous parsing, missing Education Cloud provisioning, and more).
references/gotchas.md已知故障模式及其解决方案请参见(重命名/删除歧义、重复更新运行、分页、速率限制、解析歧义、缺少Education Cloud配置等)。
references/gotchas.mdOutput Expectations
输出预期
Deliverables (new setup):
- Account records: 1 System + N Campuses + N Colleges + N Departments (all with the org's resolved Account RecordType)
- BusinessProfile records: 1 per Account, linked via field
AccountId - Hierarchy visualization: Nested bullet format showing complete structure
- Verification summary: Confirmation that all parent-child relationships are valid (materialized paths are derived on demand from the ParentId chain, not persisted)
- System (root) Account Id: Printed for reuse in future update runs
Deliverables (update/reconcile): the delta only — counts of created / renamed / moved / unchanged Accounts, any untouched extras, Business Profiles added for new Accounts, and the same verification summary.
See for sample output structures (new setup and update/reconcile).
examples/output_examples.md交付物(全新设置):
- Account记录:1个System + N个Campuses + N个Colleges + N个Departments(均使用组织解析的Account RecordType)
- BusinessProfile记录:每个Account对应1个,通过字段关联
AccountId - 层级可视化:显示完整结构的嵌套项目符号格式
- 验证摘要:确认所有父子关系有效(物化路径通过ParentId链按需动态推导,不持久化)
- System(根节点)Account Id:打印出来以便未来更新运行时复用
交付物(更新/比对):仅差异部分——创建/重命名/移动/未更改的Accounts数量,任何未触及的多余节点,为新Accounts添加的Business Profiles,以及相同的验证摘要。
全新设置和更新/比对的示例输出结构请参见。
examples/output_examples.mdReference File Index
参考文件索引
| File | When to read |
|---|---|
| Step 0 — org edition, Lightning Experience, EDU license, permission set assignment, Education Cloud Foundation enablement; run before Step 1 on every standalone invocation |
| Steps 3.5, 5, 7-9 — exact |
| Step 3.5 — no non-Master Account RecordType exists in org; ask/confirm/create it as a self-resolving prerequisite |
| Step 2 — when parsed structure is ambiguous (e.g., college names appear without explicit campus parent) |
| Step 5 — exact matching algorithm for reconciling desired vs. current hierarchy (reuse/CREATE/EXTRA/RENAME/MOVE), including cycle rejection |
| Steps 7-8 — when API errors occur during Account create/patch or Business Profile creation |
| Any step — known failure modes and their resolutions |
| Steps 3 & 10 — to format the hierarchy structure summary for the user |
| Steps 6 & 10 — pre-write preview templates, and sample completion-report output for new setup and update/reconcile |
| Step 1 — reference shape for CSV input ( |
| Step 1 — CSV edge cases: duplicate sibling names, abbreviations, orphaned parent reference |
| 文件 | 阅读时机 |
|---|---|
| 步骤0——组织版本、Lightning Experience、EDU许可证、权限集分配、Education Cloud Foundation启用;每次独立调用时,在步骤1之前运行 |
| 步骤3.5、5、7-9——所有Account/BusinessProfile读写操作的精确 |
| 步骤3.5——组织中不存在非Master的Account RecordType;请求/确认/创建它作为自解决前提条件 |
| 步骤2——解析结构存在歧义时(例如,学院名称未明确关联校区父节点) |
| 步骤5——比对目标结构与当前结构的精确匹配算法(复用/CREATE/EXTRA/RENAME/MOVE),包括循环拒绝 |
| 步骤7-8——Account创建/更新或Business Profile创建过程中出现API错误时 |
| 任何步骤——已知故障模式及其解决方案 |
| 步骤3和10——为用户格式化层级结构摘要 |
| 步骤6和10——写入前预览模板,以及全新设置和更新/比对的示例完成报告输出 |
| 步骤1——CSV输入的参考格式( |
| 步骤1——CSV边缘情况:同级重复名称、缩写、孤立父引用 |