Files
Edu/apps/portal-shell/src/lib/api/operations/elective.graphql.ts
SpecialX 80cc1d2461 feat(portal-shell): course-plans + elective 模块 5 页迁移(教师域 §9.1 B2)
§9.1 line 635-636 教师域:
- /shell/teacher/course-plans (列表) + /[id] (详情) — 2 页
- /shell/teacher/elective (列表) + /create (表单) + /[id]/edit (编辑表单) — 3 页
契约:全  schema 无 → MSW 兜底 + @contract-pending

新增文件:
- src/lib/api/{course-plans,elective}.ts (8 hooks 合计)
- src/lib/api/operations/{course-plans,elective}.graphql.ts (8 documents)
- src/features/teacher/{course-plans,elective}/ (clients + transformations + tests)
- src/app/shell/teacher/{course-plans,elective}/ (5 page.tsx + 2 loading + 2 error)

修改文件:
- src/mocks/graphql-data.ts (3 mock 数据 + 8 handler cases)
- src/messages/{zh-CN,en}.json (coursePlans/elective i18n 命名空间)
- src/lib/api/{index,operations/index}.ts (导出 course-plans/elective)
- src/shared/lib/route-permissions.ts (2 EXACT + 2 PREFIX 条目)
- scripts/check-page-count.ts (baseline 48 → 53)

DoD 验收(§11.3 11 项):
- typecheck 0 errors
- lint 0 errors
- vitest 645 tests passed
- lint:tokens 0 errors
- check:pages 53 PASS
- route-permissions 已声明
- 三态齐备
- @contract-pending + MSW 兜底
- i18n zh-CN + en 同步

设计决策:
- COURSE_PLAN_* 权限点不存在于 PERMISSION_BITMAP_ORDER,复用 LESSON_PLAN_READ/CREATE/UPDATE(同备课域语义对齐)
- elective 使用已存在的 ELECTIVE_READ/ELECTIVE_MANAGE
- 编辑表单用 useEffect + initialized state guard 预填数据

关联:ARCHITECTURE.md §5.3 / §5.4 / §9.1 / §10 P2 / §11.3 / §11.4
契约工单:docs/architecture/issues/contracts/core-edu_contract.md
2026-07-22 23:15:45 +08:00

85 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Elective domain GraphQL documents (ARCHITECTURE.md §5.3 契约纪律 / §9.1)
//
// 拆分原则:
// - 全部操作:❌ schema 无 electives / elective(id) 根字段,也无 Mutation 类型
// → 走 MSW 兜底(@contract-pending等待后端补齐契约
//
// 契约工单docs/architecture/issues/contracts/core-edu_contract.md#elective
// 关联ARCHITECTURE.md §5.3 / §5.4 / §9.1 / §11.4
import { gql } from "@apollo/client";
// ── 假契约查询(@contract-pending─────────────────────────────
// 列表查询schema 无 electives(...) 根字段
// 页面通过 MSW 兜底获取列表数据,后端补齐后切换 fetcher 指向真实查询
// 契约工单core-edu_contract.md#electives-list
export const GET_ELECTIVES_DOC = gql`
query GetElectives($status: String, $q: String, $limit: Int, $offset: Int) {
electives(status: $status, q: $q, limit: $limit, offset: $offset) {
items {
id
name
description
capacity
enrolledCount
semester
gradeLevel
subject
teacherId
teacherName
status
createdAt
updatedAt
}
total
}
}
`;
// ── 单查(@contract-pending────────────────────────────────────
// schema 无 elective(id) 根字段 → MSW 兜底
// 用于 /shell/teacher/elective/[id]/edit 编辑表单页预填
// 契约工单core-edu_contract.md#elective-by-id
export const GET_ELECTIVE_DOC = gql`
query GetElective($id: ID!) {
elective(id: $id) {
id
name
description
capacity
enrolledCount
semester
gradeLevel
subject
teacherId
teacherName
status
createdAt
updatedAt
}
}
`;
// ── 假契约变更(@contract-pending─────────────────────────────
// 创建选修课schema 无 Mutation 类型
// 页面通过 MSW 兜底提交,后端补齐 mutation 后切换 fetcher
// 契约工单core-edu_contract.md#create-elective
export const CREATE_ELECTIVE_DOC = gql`
mutation CreateElective($input: CreateElectiveInput!) {
createElective(input: $input) {
id
}
}
`;
// ── 更新选修课 mutation@contract-pending────────────────────
// schema 无 Mutation 类型 → MSW 兜底
// 用于 /shell/teacher/elective/[id]/edit 编辑表单页保存
// 契约工单core-edu_contract.md#update-elective
export const UPDATE_ELECTIVE_DOC = gql`
mutation UpdateElective($input: UpdateElectiveInput!) {
updateElective(input: $input) {
id
}
}
`;