education-cloud-academic-calendar-generate
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEducation Cloud Academic Calendar Generation
Education Cloud 学术日历生成
Create the foundational academic calendar infrastructure for Education Cloud orgs, parsing calendar data from documents or natural language and generating validated Academic Year, Term, and Session records with proper date ranges and institutional linkage.
为Education Cloud组织创建基础学术日历架构,从文档或自然语言中解析日历数据,生成经过验证的Academic Year、Term和Session记录,并确保日期范围准确且机构关联正确。
Scope
适用范围
- In scope: Academic Year records, Academic Term records (semester/quarter/trimester systems), Academic Session records (term subdivisions), registration windows, add/drop deadlines, date validation
- Out of scope: Course scheduling (delegate to course offering skills), individual course section dates, financial aid deadlines, exam schedules, institutional hierarchy setup (no dedicated skill exists yet for this — set up Accounts/campuses manually)
- 包含内容:Academic Year记录、Academic Term记录(学期/学季/三学期制)、Academic Session记录(学期细分学段)、注册窗口期、退课截止日期、日期验证
- 排除内容:课程排期(委托给课程产品Skill)、单个课程章节日期、助学金截止日期、考试日程、机构层级设置(目前暂无专用Skill,需手动设置Accounts/校区)
Execution Model
执行模型
All Salesforce operations use relative-path REST calls. Do not use CLI or shell commands to reach Salesforce (, , ); the execution environment may not provide them. This does not apply to the skill's own local validation script (, see step 4) — that runs locally and never touches the org.
sfsfdxcurlscripts/validate_calendar_dates.py- Record CRUD: sObject REST — ,
POST /services/data/<ver>/sobjects/<Object>,GET /services/data/<ver>/sobjects/<Object>/<Id>PATCH /services/data/<ver>/sobjects/<Object>/<Id> - Schema checks: sObject describe — (confirm object + field API names exist before writing).
GET /services/data/<ver>/sobjects/<Object>/describe - SOQL is routable:
/querywith the SOQL passed as a structuredGET /services/data/<ver>/query, NOT inlined into the URL asqueryParams: {"q": "..."}— confirmed by live test: inlining?q=...404s (?q=/ROUTE_NOT_FOUND) via headless-360 dispatch, whileNOT_FOUNDreliably 200s. Use it to list-scan for existing terms/sessions, or resolve records by the runtime Id captured at create time and read them back with a directqueryParams— either is valid.GET .../sobjects/<Object>/<Id> - All IDs are runtime variables captured from create-response — never hardcode a literal Salesforce Id.
body.id - Resolve API version dynamically — see Execution Transport below. Do not hardcode a version.
所有Salesforce操作均使用相对路径REST调用。请勿使用CLI或Shell命令访问Salesforce(、、);执行环境可能未提供这些工具。此规则不适用于Skill自带的本地验证脚本(,见步骤4)——该脚本仅在本地运行,不会访问组织。
sfsfdxcurlscripts/validate_calendar_dates.py- 记录增删改查(CRUD):sObject REST — 、
POST /services/data/<ver>/sobjects/<Object>、GET /services/data/<ver>/sobjects/<Object>/<Id>PATCH /services/data/<ver>/sobjects/<Object>/<Id> - Schema检查:sObject描述 — (写入前确认对象及字段API名称存在)。
GET /services/data/<ver>/sobjects/<Object>/describe - SOQL 路由规则:通过
/query传递结构化GET /services/data/<ver>/query,而非将SOQL内联到URL中(如queryParams: {"q": "..."})——经实测:内联?q=...会触发404错误(?q=/ROUTE_NOT_FOUND),而使用NOT_FOUND可稳定返回200状态码。可用于扫描现有学期/学段,或通过创建时捕获的运行时Id直接读取记录(queryParams)——两种方式均有效。GET .../sobjects/<Object>/<Id> - 所有ID均为运行时变量:从创建响应的中捕获,切勿硬编码Salesforce字面ID。
body.id - 动态解析API版本:见下文执行传输部分。请勿硬编码版本号。
Required Inputs
必要输入
Gather or infer before proceeding:
- Calendar system: Semester (Fall/Spring/Summer) or Quarter (Fall/Winter/Spring/Summer) or Trimester
- Academic year span: Start and end dates for the overall academic year
- Term dates: For each term - class start/end, registration open date, add/drop deadline
- Session subdivisions: Any sub-sessions within terms (e.g., Summer Session 1 and 2)
If the user provides a calendar document (PDF, CSV, spreadsheet), parse it to extract all dates. If the user provides natural language, ask for specific dates before proceeding.
Note: AcademicYear, AcademicTerm, and AcademicSession have no Account reference field — calendar records are not linked to a Business Account. Linkage is Year → Term () and Term → Session () only.
AcademicYearIdAcademicTermIdDefaults unless specified:
- Calendar system: Semester (Fall, Spring, Summer)
- Academic year naming: "Academic Year YYYY-YYYY" format
- Registration windows: Open 3-4 months before term start
- Add/drop deadlines: 2 weeks after term start
执行前需收集或推断以下信息:
- 日历体系:学期制(秋季/春季/夏季)、学季制(秋季/冬季/春季/夏季)或三学期制
- 学年跨度:整个学年的开始和结束日期
- 学期日期:每个学期的课程起止日期、注册开放日期、退课截止日期
- 学段细分:学期内的子学段(如夏季学段1和学段2)
若用户提供日历文档(PDF、CSV、电子表格),需解析提取所有日期;若用户提供自然语言描述,需先询问具体日期再执行。
注意:AcademicYear、AcademicTerm和AcademicSession无Account关联字段——日历记录不关联至企业Account。仅支持学年→学期()、学期→学段()的层级关联。
AcademicYearIdAcademicTermId默认设置(未指定时):
- 日历体系:学期制(秋季、春季、夏季)
- 学年命名格式:"Academic Year YYYY-YYYY"
- 注册窗口期:学期开始前3-4个月开放
- 退课截止日期:学期开始后2周
Execution Transport
执行传输
- Resolve API version: (unversioned) via headless-360 dispatch. Response is a map of endpoint paths already resolved to the org's current max version (e.g.
GET /services/data/) — not an array with a"limits": "/services/data/v69.0/limits"field. Extract the version from any returned path (regexversion) and use it asv\d+\.\d+for every call below.<ver> - Probe transport health: via headless-360 dispatch. 2xx → route all calls through it. On absent/4xx/5xx → probe other available transports (other Salesforce MCP, authenticated
GET /services/data/<ver>/limitsCLI, custom MCP) with the same read, use first healthy, announce it. None healthy → stop, ask user to connect one; never fabricate.sf
- 解析API版本:通过headless-360调度发送(无版本号)。响应为已解析至组织当前最高版本的端点路径映射(如
GET /services/data/)——并非包含"limits": "/services/data/v69.0/limits"字段的数组。从任意返回路径中提取版本号(正则表达式version),并将其作为后续所有调用的v\d+\.\d+。<ver> - 探测传输健康状态:通过headless-360调度发送。返回2xx状态码→所有调用均通过该路由;若返回缺失/4xx/5xx状态码→使用相同读取请求探测其他可用传输方式(其他Salesforce MCP、已认证的
GET /services/data/<ver>/limitsCLI、自定义MCP),使用第一个可用的传输方式并告知用户;若无可用传输方式→停止执行,请求用户连接可用传输方式,切勿伪造连接。sf
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 EDU access, 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 -
Confirm calendar system
- Ask user: semester, quarter, or trimester system?
- Identify expected term names based on system type
-
Gather calendar data
- If user provides document (PDF, CSV, spreadsheet): parse to extract year, term, and session dates
- If user provides natural language: extract dates from description
- If insufficient detail: ask for specific dates (term start/end, registration windows, deadlines)
-
Verify object and field schema
- Before writing, confirm each object and every field you will set exists on the org:
,
GET /services/data/<ver>/sobjects/AcademicYear/describe,.../AcademicTerm/describe.../AcademicSession/describe - Read the array; match your intended field API names (
fields,Name,AcademicYearId,StartDate,EndDate,RegistrationOpenDate,RegistrationCloseDate,Season,AcademicTermId,ClassStartDate,ClassEndDate) against it.AddDropDeadline - Note picklist field (
Season, valuesAcademicTerm.Season/Fall/Spring/Summer): only send values present in that field'sWinter.picklistValuesis a different picklist (AcademicSession.Type/Semester/Trimester/etc.) not used by this workflow — do not confuse it withQuarter.Season - If a field is absent: STOP — do not POST with an unverified field name; report the mismatch to the user.
- Before writing, confirm each object and every field you will set exists on the org:
-
Validate date ranges
- Assemble the gathered year/term/session data into the JSON shape documented at the top of , then run it once:
scripts/validate_calendar_dates.pybashpython3 scripts/validate_calendar_dates.py <<'EOF' {"academicYear": {...}, "terms": [...], "sessions": [...]} EOF - The script checks term end > start, year spans all terms, registration open < term start, add/drop deadline within term bounds, and session containment within parent term — and computes each term's .
RegistrationCloseDate - If is
valid: stop, report each entry infalseto the user, and ask for corrected dates. Do not proceed to step 5.errors - (e.g., intentional session overlaps) do not block — surface each one to the user for confirmation in step 6.
warnings - Carry forward — step 8 uses it instead of recalculating.
computedRegistrationCloseDates
- Assemble the gathered year/term/session data into the JSON shape documented at the top of
-
Detect duplicate terms
- AcademicTerm is not unique-constrained, so a duplicate name will NOT error on insert. List-scan for existing terms with matching names before creating:
NamewithGET /services/data/<ver>/query— pass the SOQL viaqueryParams: {"q": "SELECT Id, Name, StartDate, EndDate FROM AcademicTerm WHERE Name = 'Fall 2025'"}, not inlined asqueryParamsin the URL (inlining 404s) — or, if the user has previously created a calendar for this year in the same session, reuse the Ids captured then instead of re-creating.?q= - If a duplicate name is found, compare dates and ask the user whether to update the existing record or skip.
- If the duplicate-check read itself fails (non-2xx, transport error): STOP — do not proceed to create the term. Report the failure to the user and ask how to proceed; do not silently create a possibly-duplicate record.
- AcademicTerm
-
Display proposed calendar structure and confirm
- Present a summary of what will be created: Academic Year name and dates, then each term's name/dates/registration window/computed , then each session's name and dates grouped under its parent term. See
RegistrationCloseDatefor a filled-in rendering.examples/sample-output.md - For every session-overlap warning from step 4: state the overlap period and ask the user to confirm it's intentional.
- Ask user: "Should I create all of these records?"
- Wait for user confirmation before proceeding to step 7
- Present a summary of what will be created: Academic Year name and dates, then each term's name/dates/registration window/computed
-
Create Academic Year record
- After user confirms in step 6, insert Academic Year:
http
POST /services/data/<ver>/sobjects/AcademicYear {"Name": "Academic Year 2025-2026"} - Capture from the response
academicYearIdfor term linkagebody.id - Report: "Academic Year created: Academic Year 2025-2026"
- After user confirms in step 6, insert Academic Year:
-
Create Academic Term records
- For each term (Fall, Spring, Summer or Quarter equivalents), insert with set to
AcademicYearIdfrom step 7:academicYearIdhttpPOST /services/data/<ver>/sobjects/AcademicTerm {"Name": "Fall 2025", "Season": "Fall", "StartDate": "2025-08-18", "EndDate": "2025-12-12", "AcademicYearId": "<academicYearId>", "RegistrationOpenDate": "2025-04-01", "RegistrationCloseDate": "2025-08-17"}- comes from step 4's
RegistrationCloseDate— do not recompute it by hand.computedRegistrationCloseDates[<term name>] - is a restricted picklist:
Season,Fall,Spring,Summer. AcademicTerm has NO add/drop field — add/drop deadlines live on AcademicSession only.Winter
- Capture each from the response
termIdfor session linkagebody.id - Report progress: "Created 3 terms: Fall 2025, Spring 2026, Summer 2026"
- For each term (Fall, Spring, Summer or Quarter equivalents), insert with
-
Create Academic Session records
- For each session subdivision (e.g., Summer Session 1, Summer Session 2), insert with set to the parent
AcademicTermIdfrom step 8:termIdhttpPOST /services/data/<ver>/sobjects/AcademicSession {"Name": "Summer Session 1", "ClassStartDate": "2026-05-26", "ClassEndDate": "2026-07-03", "AddDropDeadline": "2026-06-11", "AcademicTermId": "<termId>"} - Report progress: "Created 2 sessions: Summer Session 1, Summer Session 2"
- For each session subdivision (e.g., Summer Session 1, Summer Session 2), insert with
-
Generate completion summary
- Display a final summary: the created Academic Year with its dates, each created Term with its date range, and each created Session grouped under its parent Term, plus a one-line note on the Year → Term → Session linkage. See for a filled-in rendering.
examples/sample-output.md - If any sessions overlap (per step 4's warnings), note the overlap period and that it was confirmed intentional.
- If any terms were skipped due to duplicates, list them with reason
- Display a final summary: the created Academic Year with its dates, each created Term with its date range, and each created Session grouped under its parent Term, plus a one-line note on the Year → Term → Session linkage. See
所有步骤按顺序执行,请勿跳过或重新排序。若遇阻塞,停止执行并询问缺失信息。
-
验证基础前提条件:遵循:组织版本、Lightning Experience、Education Cloud许可证、运行用户的EDU权限、Education Cloud Foundation已启用(若未启用,可先确认再自动修复)。所有检查通过后方可进入步骤1。
references/foundation_prerequisites.md -
确认日历体系
- 询问用户:采用学期制、学季制还是三学期制?
- 根据体系类型确定预期学期名称
-
收集日历数据
- 若用户提供文档(PDF、CSV、电子表格):解析提取学年、学期、学段日期
- 若用户提供自然语言描述:从描述中提取日期
- 若信息不足:询问具体日期(学期起止、注册窗口期、截止日期)
-
验证对象和字段Schema
- 写入前,确认每个对象及所有待设置字段在组织中存在:
、
GET /services/data/<ver>/sobjects/AcademicYear/describe、.../AcademicTerm/describe.../AcademicSession/describe - 读取数组;将待设置字段的API名称(
fields、Name、AcademicYearId、StartDate、EndDate、RegistrationOpenDate、RegistrationCloseDate、Season、AcademicTermId、ClassStartDate、ClassEndDate)与数组内容匹配。AddDropDeadline - 注意选择列表字段(
Season,可选值AcademicTerm.Season/Fall/Spring/Summer):仅发送该字段Winter中存在的值。picklistValues是另一个选择列表(AcademicSession.Type/Semester/Trimester等),本工作流程不使用该字段——请勿与Quarter混淆。Season - 若字段缺失:停止执行——请勿使用未验证的字段名称进行POST请求;向用户报告字段不匹配问题。
- 写入前,确认每个对象及所有待设置字段在组织中存在:
-
验证日期范围
- 将收集到的学年/学期/学段数据组装成顶部文档化的JSON格式,然后运行一次:
scripts/validate_calendar_dates.pybashpython3 scripts/validate_calendar_dates.py <<'EOF' {"academicYear": {...}, "terms": [...], "sessions": [...]} EOF - 该脚本检查学期结束日期>开始日期、学年覆盖所有学期、注册开放日期<学期开始日期、退课截止日期在学期范围内、学段包含在父学期内——并计算每个学期的。
RegistrationCloseDate - 若为
valid:停止执行,向用户报告false中的每条错误信息,并请求修正日期。请勿进入步骤5。errors - (如故意设置的学段重叠)不会阻塞执行——需在步骤6中向用户展示每条警告并确认。
warnings - 保留——步骤8将使用该值,无需重新计算。
computedRegistrationCloseDates
- 将收集到的学年/学期/学段数据组装成
-
检测重复学期
- AcademicTerm的无唯一性约束,因此重复名称不会导致插入错误。创建前需扫描现有同名学期:发送
Name并携带GET /services/data/<ver>/query——通过queryParams: {"q": "SELECT Id, Name, StartDate, EndDate FROM AcademicTerm WHERE Name = 'Fall 2025'"}传递SOQL,而非内联到URL中(内联会触发404错误);若用户在同一会话中已为该学年创建过日历,可复用之前捕获的Id,无需重新创建。queryParams - 若发现同名学期,比较日期并询问用户是更新现有记录还是跳过创建。
- 若重复检查读取请求失败(非2xx状态码、传输错误):停止执行——请勿继续创建学期。向用户报告失败情况并询问后续操作;切勿静默创建可能重复的记录。
- AcademicTerm的
-
展示拟创建的日历结构并确认
- 展示将创建的内容摘要:学年名称及日期,然后是每个学期的名称/日期/注册窗口期/计算得到的,最后是每个学段的名称及日期(按父学期分组)。可参考
RegistrationCloseDate中的示例输出。examples/sample-output.md - 对于步骤4中出现的每条学段重叠警告:说明重叠时间段并询问用户是否确认该设置为故意操作。
- 询问用户:“是否创建所有这些记录?”
- 等待用户确认后方可进入步骤7
- 展示将创建的内容摘要:学年名称及日期,然后是每个学期的名称/日期/注册窗口期/计算得到的
-
创建Academic Year记录
- 用户在步骤6中确认后,插入学年记录:
http
POST /services/data/<ver>/sobjects/AcademicYear {"Name": "Academic Year 2025-2026"} - 从响应的中捕获
body.id,用于学期关联academicYearId - 反馈:“已创建学年:Academic Year 2025-2026”
- 用户在步骤6中确认后,插入学年记录:
-
创建Academic Term记录
- 为每个学期(秋季、春季、夏季或学季制对应学期)插入记录,并将设置为步骤7中获取的
AcademicYearId:academicYearIdhttpPOST /services/data/<ver>/sobjects/AcademicTerm {"Name": "Fall 2025", "Season": "Fall", "StartDate": "2025-08-18", "EndDate": "2025-12-12", "AcademicYearId": "<academicYearId>", "RegistrationOpenDate": "2025-04-01", "RegistrationCloseDate": "2025-08-17"}- 来自步骤4的
RegistrationCloseDate——请勿手动重新计算。computedRegistrationCloseDates[<term name>] - 为受限选择列表:可选值
Season、Fall、Spring、Summer。AcademicTerm无退课字段——退课截止日期仅存储在AcademicSession中。Winter
- 从每个响应的中捕获
body.id,用于学段关联termId - 反馈进度:“已创建3个学期:Fall 2025、Spring 2026、Summer 2026”
- 为每个学期(秋季、春季、夏季或学季制对应学期)插入记录,并将
-
创建Academic Session记录
- 为每个学段细分(如夏季学段1、夏季学段2)插入记录,并将设置为步骤8中获取的父学期
AcademicTermId:termIdhttpPOST /services/data/<ver>/sobjects/AcademicSession {"Name": "Summer Session 1", "ClassStartDate": "2026-05-26", "ClassEndDate": "2026-07-03", "AddDropDeadline": "2026-06-11", "AcademicTermId": "<termId>"} - 反馈进度:“已创建2个学段:Summer Session 1、Summer Session 2”
- 为每个学段细分(如夏季学段1、夏季学段2)插入记录,并将
-
生成完成摘要
- 展示最终摘要:已创建的学年及其日期、每个已创建学期的日期范围、每个已创建学段(按父学期分组),并添加一行关于学年→学期→学段层级关联的说明。可参考中的示例输出。
examples/sample-output.md - 若存在学段重叠(步骤4中的警告),需说明重叠时间段并确认该设置为用户故意操作。
- 若因重复而跳过某些学期,需列出这些学期及原因
- 展示最终摘要:已创建的学年及其日期、每个已创建学期的日期范围、每个已创建学段(按父学期分组),并添加一行关于学年→学期→学段层级关联的说明。可参考
按需验证
步骤10完成后可随时进行,非工作流程必要步骤——仅在用户请求抽查记录或查看日历范围时使用。
- 特定记录(如“查看Fall 2025”):通过捕获的Id直接读取——(返回所有字段;请勿使用
GET /services/data/<ver>/sobjects/AcademicTerm/<termId>选择器);若未捕获Id,可通过名称查询:发送?fields=并携带GET /services/data/<ver>/query(通过queryParams: {"q": "SELECT Id FROM AcademicTerm WHERE Name = 'Fall 2025'"}传递SOQL,而非内联到URL中——内联会触发404错误)。以表格形式展示所有字段值及父层级关系。queryParams - 日历视图(如“查看Summer 2026的所有日期”):通过捕获的Id直接读取学期及所有子学段——和
GET /services/data/<ver>/sobjects/AcademicTerm/<termId>——并以表格形式展示(记录类型、名称、开始日期、结束日期、时长、注册开放日期、注册截止日期、退课截止日期)。若存在重叠,计算并展示重叠时间段。可参考GET /services/data/<ver>/sobjects/AcademicSession/<sessionId>中的示例输出。examples/sample-output.md
On-Demand Verification
规则/约束
Available at any time after step 10, not a required workflow step — use only when the user asks to spot-check a record or view a calendar range.
- Specific record (e.g., "show me Fall 2025"): cold-read by its captured Id — (returns all fields; do not use a
GET /services/data/<ver>/sobjects/AcademicTerm/<termId>selector) — or, if the Id was not captured, look it up by name with?fields=andGET /services/data/<ver>/query(pass the SOQL viaqueryParams: {"q": "SELECT Id FROM AcademicTerm WHERE Name = 'Fall 2025'"}, not inlined asqueryParamsin the URL — inlining 404s). Display all field values in table format with parent hierarchy.?q= - Calendar view (e.g., "show all dates for Summer 2026"): cold-read the term and each child session by their captured Ids — and
GET /services/data/<ver>/sobjects/AcademicTerm/<termId>— and display as a table (Record Type, Name, Start Date, End Date, Duration, Registration Open, Registration Close, Add/Drop). Calculate and display overlap periods if applicable. SeeGET /services/data/<ver>/sobjects/AcademicSession/<sessionId>for a filled-in rendering.examples/sample-output.md
| 约束条件 | 理由 |
|---|---|
| 写入前通过describe验证对象及字段API名称 | 避免因使用未验证字段导致POST请求失败; |
| 学期结束日期必须晚于开始日期 | 平台会验证并拒绝无效日期范围 |
| 注册窗口期必须在学期开始前开放 | 学生无法在课程开始后注册 |
| 退课截止日期(AcademicSession字段)必须晚于或等于学期开始日期 | 截止日期早于课程开始日期不符合逻辑;AcademicTerm无退课字段 |
| 学年必须覆盖所有子学期 | 学期日期超出学年范围会导致报告问题 |
| 同一学期内允许学段重叠 | 夏季学段常采用此模式(如学段1:5月-7月,学段2:6月-8月) |
| 学期名称需符合日历体系惯例 | 学期制为秋季/春季/夏季,学季制为秋季/冬季/春季/夏季 |
| 动态解析API版本,切勿硬编码 | 组织的最高API版本会随时间变化;硬编码的旧版本会与组织当前版本脱节 |
创建前通过SOQL | |
Rules / Constraints
常见问题
| Constraint | Rationale |
|---|---|
| Verify object + field API names via describe before writing | Prevents a failed POST on an unverified field; |
| Term end date must be after start date | Platform validation will reject invalid date ranges |
| Registration window must open before term starts | Students cannot register after classes begin |
| Add/drop deadline (on AcademicSession) after or equal to term start | Deadline before classes start is logically invalid; AcademicTerm has no add/drop field |
| Academic Year must span all its child terms | Term dates outside year range cause reporting issues |
| Overlapping sessions within same term are allowed | Common pattern for Summer sessions (e.g., Session 1: May-Jul, Session 2: Jun-Aug) |
| Term names should match calendar system convention | Fall/Spring/Summer for semester, Fall/Winter/Spring/Summer for quarter |
| Resolve API version dynamically, don't hardcode | Org's max API version changes over time; a stale hardcoded version drifts from the org's current one |
Check for duplicate terms via SOQL | |
| 问题 | 解决方案 |
|---|---|
| 用户提供相对日期(如“下一个秋季”) | 转换为绝对日期后再插入(如“下一个秋季”→“Fall 2026”及具体日期) |
| 学段重叠被标记为错误 | 与用户确认——许多机构会故意设置学段重叠(如夏季学段1和学段2重叠1周) |
| 同名学期但日期不同 | 询问用户是更新现有记录还是跳过——未经确认请勿自动更新 |
| 注册窗口期晚于学期开始日期 | 此设置无效——请求用户提供正确的注册开放日期 |
| 学年结束日期早于最后一个学期的结束日期 | 延长学年以覆盖所有学期,或调整学期日期 |
| 输入包含学期级退课日期但无学段细分 | AcademicTerm无退课字段——向用户说明学期与学段的字段差异,或建议为每个学期创建一个学段来存储退课日期;切勿将退课日期写入AcademicTerm或静默丢弃该信息 |
| 用户提供三段式学年范围(2025-2026-2027) | 与用户确认——学年仅涵盖两个年份(如2025-2026) |
| 无父学期的学段 | 每个学段必须关联至一个学期——若用户提供学段日期但未指定所属学期,询问该学段属于哪个学期 |
Gotchas
输出预期
| Issue | Resolution |
|---|---|
| User provides relative dates ("next Fall") | Convert to absolute dates before inserting (e.g., "next Fall" → "Fall 2026" with specific dates) |
| Overlapping sessions flagged as error | Confirm with user — overlaps are intentional in many institutions (e.g., Summer Session 1 and 2 overlap by 1 week) |
| Duplicate term with different dates | Ask user whether to update existing or skip — do not auto-update without confirmation |
| Registration window after term start | This is invalid — ask user to provide correct registration open date |
| Academic Year end date before last term end date | Extend Academic Year to cover all terms, or adjust term dates |
| Input carries a term-level add/drop date but no session subdivisions | AcademicTerm has no add/drop field — surface the term-vs-session placement to the user or propose a session per term to carry the date; never write it onto AcademicTerm and never silently drop it |
| User provides 3-part year range (2025-2026-2027) | Clarify with user — Academic Year spans exactly 2 years (e.g., 2025-2026) |
| Session without parent term | Every session must link to a term — if user provides session dates without term, ask which term it belongs to |
交付成果:
- Academic Year记录:单个覆盖所有学期的学年记录(如“Academic Year 2025-2026”)
- Academic Term记录:每年3-4个学期记录(学期制为秋季、春季、夏季;学季制为秋季、冬季、春季、夏季)
- Academic Session记录:0-N个学段记录(学期制通常为2个夏季学段)
- 摘要报告:列出所有已创建记录的名称、日期及关联关系的表格
学期关联至父学年();学段关联至父学期()。这些对象无Account关联字段。
AcademicYearIdAcademicTermIdOutput Expectations
跨Skill集成
Deliverables:
- Academic Year record: Single year record spanning all terms (e.g., "Academic Year 2025-2026")
- Academic Term records: 3-4 term records per year (Fall, Spring, Summer for semester; Fall, Winter, Spring, Summer for quarter)
- Academic Session records: 0-N session records (typically 2 Summer sessions for semester systems)
- Summary report: Table listing all created records with names, dates, and linkages
Terms link to the parent Academic Year (); sessions link to the parent Term (). These objects have no Account reference field.
AcademicYearIdAcademicTermId| 需求 | 委托至 |
|---|---|
| 机构层级(Accounts、校区) | 暂无专用Skill——需手动设置 |
| 课程排期及产品 | 课程产品生成Skill |
Cross-Skill Integration
参考文件索引
| Need | Delegate to |
|---|---|
| Institutional hierarchy (Accounts, campuses) | No dedicated skill yet — set up manually |
| Course scheduling and offerings | Course offering generation skills |
| 文件 | 阅读时机 |
|---|---|
| 步骤0——组织版本、Lightning Experience、EDU许可证、权限集分配、Education Cloud Foundation启用状态;每次独立调用时,在步骤1前运行 |
| 用户的日历体系不明确或非标准时 |
| 验证复杂日期重叠或多学段学期时 |
| 验证学期制的输出结构时 |
| 验证学季制的输出结构时 |
| 查看拟创建结构展示、完成摘要及日历视图表格的示例输出时 |
| 步骤4中调用,用于验证日期范围并确定性计算 |
Reference 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 |
| When user's calendar system is unclear or non-standard |
| When validating complex date overlaps or multi-session terms |
| To verify output structure for semester system |
| To verify output structure for quarter system |
| To see filled-in renderings of the proposed-structure display, completion summary, and calendar-view table |
| Invoked in step 4 to validate date ranges and compute |
—