Files
piano-plan/docs/superpowers/plans/2026-04-23-goal-management.md
hmo b54b6c7aec feat: 添加 Goal, GoalRelation, StudentGoal 三个数据模型
- Goal: 目标表,支持存储学习目标
- GoalRelation: 目标自关联多对多表,支持 DAG 结构
- StudentGoal: 学员目标记录表,关联学员和目标
2026-04-23 20:10:08 +08:00

3.8 KiB
Raw Permalink Blame History

目标管理模块设计

日期:2026-04-23 状态:待评审

概述

目标管理模块用于管理系统化的钢琴学习目标,支持目标间的多对多关联(DAG结构),以及目标与学员的关联记录。

数据模型

1. Goal (目标)

字段 类型 说明
id Integer 主键,自增
name String(100) 目标名称,必填
content Text Markdown 格式详细内容
created_at DateTime 创建时间
updated_at DateTime 更新时间

2. GoalRelation (目标关联 - 自关联多对多)

字段 类型 说明
parent_goal_id Integer 外键 → goals.id
child_goal_id Integer 外键 → goals.id
PRIMARY KEY (parent_goal_id, child_goal_id) 联合主键

约束

  • 禁止循环引用(A→B→C→A
  • 自关联:goal 可以是自身的父/子节点

3. StudentGoal (学员目标记录)

字段 类型 说明
id Integer 主键,自增
student_id Integer 外键 → students.id
goal_id Integer 外键 → goals.id
status String(20) 状态:未开始/进行中/已完成
mastery_level Integer 完成度:1-51最少,5最精通)
deadline DateTime 截止日期
completed_at DateTime 完成日期
created_at DateTime 创建时间

显示规则

  • mastery_level 直接渲染为对应数量的五角星(★)

API 接口

目标管理

GET    /api/goals                      # 获取所有目标
POST   /api/goals                      # 创建目标
GET    /api/goals/<id>                 # 获取目标详情
PUT    /api/goals/<id>                 # 更新目标
DELETE /api/goals/<id>                 # 删除目标

目标关联

GET    /api/goals/<id>/parents          # 获取父目标列表
GET    /api/goals/<id>/children        # 获取子目标列表
POST   /api/goals/<id>/children        # 添加子目标关联
DELETE /api/goals/<id>/children/<child_id>  # 移除关联

学员目标

GET    /api/students/<student_id>/goals      # 获取学员的目标列表
POST   /api/students/<student_id>/goals      # 为学员添加目标
PUT    /api/students/<student_id>/goals/<goal_id>  # 更新学员目标状态
DELETE /api/students/<student_id>/goals/<goal_id>  # 移除学员的目标

循环引用检测

在添加关联时必须检测:

def has_cycle(goal_id, new_child_id):
    """检测添加 new_child_id 作为 goal_id 的子目标是否会形成循环"""
    visited = set()
    stack = [new_child_id]

    while stack:
        current = stack.pop()
        if current == goal_id:
            return True  # 发现循环
        if current in visited:
            continue
        visited.add(current)
        # 获取 current 的所有子目标,继续检测
        for child in get_children(current):
            stack.append(child)

    return False

前端页面

1. 目标管理页面 (/goals)

  • 目标列表(可树状展示)
  • 创建/编辑/删除目标
  • 目标内容 Markdown 编辑器
  • 关联管理(拖拽或选择器添加关联)

2. 学员详情页目标区块

在现有 student.html 中扩展:

  • 显示学员的目标列表
  • 每项目标显示:名称、状态、★完成度、截止日期
  • 可添加/移除/编辑目标
  • 状态变更触发刷新

实现顺序

  1. 数据模型 - goals, goal_relations, student_goals 表
  2. 目标 CRUD API - 基础的增删改查
  3. 目标关联 API - 关联管理 + 循环检测
  4. 学员目标 API - 学员与目标的关联管理
  5. 目标管理页面 - 目标列表 + 关联管理
  6. 学员详情页扩展 - 目标区块

依赖关系

  • 无外部依赖
  • 复用现有的 Markdown 编辑器(EasyMDE)和星级组件