You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

12 KiB

Class Management V1 Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Implement the first working slice of the merged class-management requirements: administrative/teaching class types, school-wide class-name uniqueness, teaching-class membership, dependency-safe deletes, and teaching-class data initialization entry points.

Architecture: Keep the existing UserController endpoints compatible while adding small focused model objects and mapper methods. school_class remains the class master table and gains type/source fields; a new teaching_class_student table records many-to-many student membership/history for teaching classes. Frontend class management remains under the teacher end but is split into administrative and teaching tabs.

Tech Stack: Spring Boot, MyBatis XML mappers, JUnit 5 + Mockito, Vue 3, Element Plus, Vite.


File Structure

  • Backend SQL:
    • Create docs/sql/2026-06-23-class-management-v1.sql with new columns and new mapping tables.
  • Backend model:
    • Modify src/main/java/com/sztzjy/linkCommerce/entity/SchoolClass.java for classType, dataSource, and sourceClassIds.
    • Modify src/main/java/com/sztzjy/linkCommerce/entity/SchoolClassExample.java for class-type criteria.
    • Create src/main/java/com/sztzjy/linkCommerce/entity/TeachingClassStudent.java.
    • Create src/main/java/com/sztzjy/linkCommerce/entity/ExternalResourceMapping.java.
  • Backend mapper:
    • Modify src/main/java/com/sztzjy/linkCommerce/mapper/SchoolClassMapper.java and src/main/resources/mappers/SchoolClassMapper.xml.
    • Create src/main/java/com/sztzjy/linkCommerce/mapper/TeachingClassStudentMapper.java.
    • Create src/main/resources/mappers/TeachingClassStudentMapper.xml.
    • Create src/main/java/com/sztzjy/linkCommerce/mapper/ExternalResourceMappingMapper.java.
    • Create src/main/resources/mappers/ExternalResourceMappingMapper.xml.
  • Backend service/controller:
    • Modify src/main/java/com/sztzjy/linkCommerce/controller/stu/UserController.java for type-aware create/update/delete/list and initialization endpoints.
    • Reuse existing /api/cptf/restartTrainingByAll for current class initialization, and add user/controller endpoints that explicitly check teaching-class ownership before calling it in frontend.
  • Backend tests:
    • Modify src/test/java/com/sztzjy/linkCommerce/controller/stu/UserControllerTeacherAdminTest.java.
    • Create src/test/java/com/sztzjy/linkCommerce/entity/TeachingClassStudentModelTest.java.
  • Frontend API:
    • Modify E:/workspace/dianshang/e-commerce-internet/src/api/teacher.js.
  • Frontend views:
    • Modify E:/workspace/dianshang/e-commerce-internet/src/views/teacherEnd/class/index.vue.
    • Modify E:/workspace/dianshang/e-commerce-internet/src/views/teacherEnd/student/index.vue.

Task 1: Backend Model And SQL

Files:

  • Create: docs/sql/2026-06-23-class-management-v1.sql

  • Modify: src/main/java/com/sztzjy/linkCommerce/entity/SchoolClass.java

  • Modify: src/main/resources/mappers/SchoolClassMapper.xml

  • Modify: src/main/java/com/sztzjy/linkCommerce/entity/SchoolClassExample.java

  • Create: src/main/java/com/sztzjy/linkCommerce/entity/TeachingClassStudent.java

  • Create: src/main/java/com/sztzjy/linkCommerce/mapper/TeachingClassStudentMapper.java

  • Create: src/main/resources/mappers/TeachingClassStudentMapper.xml

  • Create: src/main/java/com/sztzjy/linkCommerce/entity/ExternalResourceMapping.java

  • Create: src/main/java/com/sztzjy/linkCommerce/mapper/ExternalResourceMappingMapper.java

  • Create: src/main/resources/mappers/ExternalResourceMappingMapper.xml

  • Test: src/test/java/com/sztzjy/linkCommerce/entity/TeachingClassStudentModelTest.java

  • Step 1: Write failing model tests

Add tests asserting SchoolClass can store ADMIN/TEACHING class types and TeachingClassStudent stores member status.

Run: mvn -Dtest=TeachingClassStudentModelTest test

Expected before implementation: compilation fails because TeachingClassStudent does not exist and SchoolClass#getClassType does not exist.

  • Step 2: Implement model fields and mapper XML

Add:

private String classType;
private String dataSource;
private String sourceClassIds;

to SchoolClass; map columns class_type, data_source, and source_class_ids.

Create TeachingClassStudent with fields:

private String id;
private String teachingClassId;
private String studentUserId;
private String adminClassId;
private String status;
private String joinReason;
private Date joinTime;
private Date exitTime;
private Date createTime;

Create mapper methods:

long countByTeachingClassId(String teachingClassId);
long countByStudentUserIdAndTeachingClassId(@Param("studentUserId") String studentUserId, @Param("teachingClassId") String teachingClassId);
int insertSelective(TeachingClassStudent record);
int deleteByTeachingClassId(String teachingClassId);

Create ExternalResourceMapping and mapper as the reserved foundation for Zhiyun duplicate external account mapping.

  • Step 3: Run model tests

Run: mvn -Dtest=TeachingClassStudentModelTest test

Expected after implementation: tests pass.


Task 2: Backend Class Rules

Files:

  • Modify: src/main/java/com/sztzjy/linkCommerce/controller/stu/UserController.java

  • Modify: src/test/java/com/sztzjy/linkCommerce/controller/stu/UserControllerTeacherAdminTest.java

  • Step 1: Write failing controller tests

Add tests for:

addSchoolClassRejectsDuplicateNameInSameSchool()
addSchoolClassDefaultsToTeachingClassWhenTeacherCreatesIt()
deleteFacultyRejectsWhenMajorExists()
deleteMajorRejectsWhenClassExists()
deleteClassRejectsWhenStudentsExist()

Run: mvn -Dtest=UserControllerTeacherAdminTest test

Expected before implementation: duplicate-by-school and dependency-delete tests fail.

  • Step 2: Implement class uniqueness and class type

Change addSchoolClass to accept optional classType; default to TEACHING when a teacher creates the class and to ADMIN when omitted by platform/admin contexts. Check duplicates by school_id + class_name, not by school_major_id + class_name.

Change updateSchoolClass to reject updates that would duplicate school_id + class_name on a different school_class_id.

  • Step 3: Implement dependency delete checks

Before deleting:

deleteSchoolFaculty -> reject if SchoolMajor exists under faculty
deleteSchoolMajor -> reject if SchoolClass exists under major
deleteSchoolClass -> reject if Userinfo students exist in admin class or TeachingClassStudent members exist in teaching class

Expected error messages can be simple Chinese user-facing strings such as 院系下存在专业,不能删除.

  • Step 4: Run controller tests

Run: mvn -Dtest=UserControllerTeacherAdminTest test

Expected after implementation: tests pass.


Task 3: Backend Teaching-Class Membership And Initialization

Files:

  • Modify: src/main/java/com/sztzjy/linkCommerce/controller/stu/UserController.java

  • Modify: src/test/java/com/sztzjy/linkCommerce/controller/stu/UserControllerTeacherAdminTest.java

  • Step 1: Write failing tests

Add tests for:

addStudentToTeachingClassCreatesMembershipInsteadOfChangingAdminClass()
teacherCannotInitializeTeachingClassCreatedByAnotherTeacher()
teacherCanInitializeSingleStudentOnlyInOwnedTeachingClass()

Run: mvn -Dtest=UserControllerTeacherAdminTest test

Expected before implementation: tests fail because membership mapper/initialization endpoints are missing.

  • Step 2: Add membership creation

When adding a student to a teaching class, preserve the student schoolClassId as the administrative class and insert a TeachingClassStudent row linking student_user_id to teaching_class_id.

For compatibility, keep existing student account creation working for administrative classes.

  • Step 3: Add initialization endpoints

Add:

@PostMapping("/initializeTeachingClassTrainingData")
ResultEntity initializeTeachingClassTrainingData(@RequestParam String teachingClassId, @RequestParam String operatorId)

@PostMapping("/initializeTeachingClassStudentTrainingData")
ResultEntity initializeTeachingClassStudentTrainingData(@RequestParam String teachingClassId, @RequestParam String studentUserId, @RequestParam String operatorId)

Both endpoints must check that the class is TEACHING and owned by operatorId. The first initializes all teaching-class members; the second initializes one member. In V1, return success after validation and keep the actual existing training cleanup call delegated to current module endpoints until training-data table ownership is mapped in a follow-up.

  • Step 4: Run controller tests

Run: mvn -Dtest=UserControllerTeacherAdminTest test

Expected after implementation: tests pass.


Task 4: Frontend Class Tabs And Init Buttons

Files:

  • Modify: E:/workspace/dianshang/e-commerce-internet/src/api/teacher.js

  • Modify: E:/workspace/dianshang/e-commerce-internet/src/views/teacherEnd/class/index.vue

  • Step 1: Update API helpers

Add:

export function initializeTeachingClassTrainingData(params) {
  return request({ url: "/api/user/initializeTeachingClassTrainingData", method: "POST", params });
}

Update class list requests to pass classType.

  • Step 2: Split UI into tabs

Use el-tabs with ADMIN and TEACHING. Administrative tab hides data initialization. Teaching tab shows edit/delete/member/data-init actions according to ownership.

  • Step 3: Verify build

Run: npm run build:prod

Expected: build exits 0.


Task 5: Frontend Student Teaching-Class Actions

Files:

  • Modify: E:/workspace/dianshang/e-commerce-internet/src/api/teacher.js

  • Modify: E:/workspace/dianshang/e-commerce-internet/src/views/teacherEnd/student/index.vue

  • Step 1: Update API helper

Add:

export function initializeTeachingClassStudentTrainingData(params) {
  return request({ url: "/api/user/initializeTeachingClassStudentTrainingData", method: "POST", params });
}
  • Step 2: Scope student initialization to teaching class

Require a teaching class selection before single-student data initialization. Send teachingClassId, studentUserId, and operatorId.

  • Step 3: Verify build

Run: npm run build:prod

Expected: build exits 0.


Task 6: Full Verification And Restart

Files:

  • No new source files unless verification reveals failures.

  • Step 1: Run backend tests

Run: mvn test

Expected: all tests pass.

  • Step 2: Run frontend build

Run: npm run build:prod

Expected: build exits 0.

  • Step 3: Restart services

Stop listeners on ports 7548 and 147, then start backend and frontend dev server:

cd E:\workspace\dianshang\link_commerce
mvn spring-boot:run -Dspring-boot.run.profiles=dev

cd E:\workspace\dianshang\e-commerce-internet
npm run dev -- --host 0.0.0.0 --port 147

Expected: backend listens on 7548, frontend listens on 147.


Plan Self-Review

  • Spec coverage in V1: class tabs, class type, school-wide class-name uniqueness, delete dependency checks, teaching-class membership foundation, student one-admin-class/many-teaching-class model, initialization entry points, and Zhiyun external mapping foundation.
  • Deferred by design: full historical migration of existing student/class data, actual deletion of every training module table during initialization, complete Zhiyun pull/push synchronization policy, and score-center query rewrites across every report. These require a separate implementation plan after V1 lands because they touch many scoring/training modules.
  • No placeholder tasks remain in this plan; every task has concrete files, commands, and expected results.