pbl_blueprint/skill/SKILL.md

7.8 KiB
Raw Blame History

name description
pbl_blueprint PBL 蓝图聚合根与子对象、版本、模板M1a。蓝图 CRUD/树/fork、7 类子对象泛化契约、版本 change_delta、模板实例化与离线兜底。所有读写 tenant_id 强制打头,缺失即 fail-closed 拒绝。

pbl_blueprint 模块技能

1. 模块定位

pbl_blueprint 是 PBLProject-Based Learning平台的蓝图域聚合根模块,负责:

  • 蓝图主表 pbl_blueprint 的 CRUD / 列表 / 树 / fork
  • 7 类子对象的泛化契约(一套 CRUD 覆盖 7 张表)
  • 版本快照 pbl_blueprint_version(含 change_delta 增量、diff、rollback
  • 模板 pbl_blueprint_template / pbl_blueprint_template_item(实例化 + 离线兜底)

模块是 Python 包(无 app.py / 无端口 / 无 Dockerfile通过 load_pbl_blueprint(env) 挂到应用 apps/pbls

2. 目录结构

modules/pbl_blueprint/
├── pyproject.toml
├── scripts/load_path.py            # RBAC 路径注册API/页面/表权限)
└── pbl_blueprint/                  # 包目录 = 模块名(禁 src/
    ├── __init__.py                 # 导出 load_pbl_blueprint
    ├── init.py                     # 装配入口 + env 注册 + 契约字典
    ├── db.py                       # 库名解析 / sqlor 获取 / 异常体系 / 建表
    ├── blueprint_crud.py           # 蓝图 CRUD + 树 + fork + 版本契约
    ├── subobjects.py               # 7 类子对象泛化 CRUD
    ├── templates.py                # 模板 CRUD + 实例化 + 离线兜底
    ├── api.py                      # HTTP API 层 + API_PATHS + HANDLERS
    ├── models/*.json               # 表定义(四段式 summary/fields/indexes/codes
    ├── json/*.json                 # CRUD 定义(根键 tblname + params.editable/browserfields
    ├── sql/pbl_blueprint.core.sql       # 核心 4 表 DDL
    ├── sql/pbl_blueprint.subobjects.sql # 子对象 7 表 DDL
    ├── init/data.json              # 初始化数据(内置模板)
    └── wwwroot/index.ui            # 前端页面

3. 数据表11 张)

核心 4 张:pbl_blueprintpbl_blueprint_versionpbl_blueprint_templatepbl_blueprint_template_item 子对象 7 张:pbl_blueprint_taskpbl_blueprint_missionpbl_blueprint_rolepbl_blueprint_learning_goalpbl_blueprint_evidence_specpbl_blueprint_artifact_specpbl_blueprint_reflection_spec

统一约定:

  • 主键 id = varchar(32)32 位无横线 UUIDdb.new_id()
  • tenant_id varchar(32) NOT NULL每个索引首列
  • 软删除 deleted tinyint0 正常 / 1 已删除)
  • 结构化字段用 json 类型(spec / config / snapshot / change_delta / rule / permissions
  • 审计五件套 created_by/created_at/updated_by/updated_at/deleted

4. 子对象泛化契约(重点)

7 类子对象共用一套函数,obj_type 分派到表:

obj_type 编码前缀 特有字段
task pbl_blueprint_task TASK parent_id
mission pbl_blueprint_mission MISSION task_id(必填), unlock_condition
role pbl_blueprint_role ROLE task_id, permissions
learning_goal pbl_blueprint_learning_goal GOAL task_id, dimension, weight
evidence_spec pbl_blueprint_evidence_spec EVI task_id, mission_id, learning_goal_id, evidence_type, collect_mode, rule, weight
artifact_spec pbl_blueprint_artifact_spec ART task_id, mission_id, artifact_type, accept_criteria, required, weight
reflection_spec pbl_blueprint_reflection_spec REF task_id, mission_id, trigger_point, reflection_type, rubric_ref, weight
from pbl_blueprint import load_pbl_blueprint
contract = load_pbl_blueprint(env)
contract['create_subobject'](tenant_id, 'mission', {'blueprint_id': bp_id, 'task_id': t_id, 'name': '关卡1'}, env=env)
contract['list_subobjects'](tenant_id, 'task', bp_id, env=env)
contract['batch_upsert_subobjects'](tenant_id, 'task', bp_id, rows, env=env)  # Designer Agent 整树写入

5. 蓝图契约

create_blueprint(tenant_id, data, env, operator)      # 自动生成 code PBL-{yyyyMMdd}-{seq4}
update_blueprint(tenant_id, blueprint_id, data, ...)  # 状态流转校验 STATUS_FLOW
delete_blueprint(tenant_id, blueprint_id, ...)        # 软删(连带子对象+版本)
get_blueprint(tenant_id, blueprint_id, with_children) # with_children=True 附带 7 类子树
list_blueprints(tenant_id, filters, page, page_size)  # 分页 + keyword/status/subject 过滤
get_blueprint_tree(tenant_id, blueprint_id)           # {obj_type: [rows]}
fork_blueprint(tenant_id, blueprint_id, new_name, target_tenant_id)  # 跨租户复制ID 重映射

状态机:draft → validating → validated → compiling → compiled → published → archived(非法流转抛 PblValidationError)。

6. 版本契约

save_version(tenant_id, blueprint_id, remark)   # 存全量 snapshot + 计算 change_delta主表 version_no 自增
list_versions(tenant_id, blueprint_id, page, page_size)
diff_versions(tenant_id, blueprint_id, version_a, version_b)  # {added, updated, removed}
rollback_version(tenant_id, blueprint_id, version_no)         # 先自动存当前版本再回滚

change_delta 结构:{"added":[{"obj_type","id","name"}], "updated":[{"obj_type","id","fields"}], "removed":[...]}

7. 模板与离线兜底

create_template(tenant_id, {'name':..., 'items':[{'obj_type':'task','ref_key':'T1','name':...}, ...]})
instantiate_template(tenant_id, template_id, name, overrides)  # ref_key/parent_ref 解析为真实 IDuse_count 自增
build_offline_fallback_blueprint(tenant_id, name)              # Agent/网络不可用时的最小可用蓝图9 条子对象)

模板条目用 ref_key / parent_ref模板内相对引用,实例化时按 SUBOBJECT_TYPES 顺序解析为真实 ID父先于子

8. tenant_id 强制打头(铁律)

  • 每个契约函数第一入参 tenant_id,内部 db.require_tenant() 校验
  • 缺失/空/非字符串 → 抛 PblTenantRequiredcode=PBL_TENANT_REQUIREDfail-closed 不放行
  • 所有 where 条件由 _where(tenant_id, extra) 构造,tenant_id= 永远在最前
  • API 层 _tid(params) 从入参或 context.tenant_id 取,取不到直接失败
  • 平台内置模板 tenant_id='platform'list_templates(include_platform=True) 才并入

9. 异常码

code 含义
PBL_TENANT_REQUIRED 租户上下文缺失
PBL_VALIDATION_ERROR 入参校验失败
PBL_NOT_FOUND / PBL_BLUEPRINT_NOT_FOUND / PBL_SUBOBJECT_NOT_FOUND / PBL_VERSION_NOT_FOUND / PBL_TEMPLATE_NOT_FOUND 记录不存在
PBL_UNKNOWN_OBJ_TYPE 未知子对象类型
PBL_DB_UNAVAILABLE sqlor 不可用

10. 数据访问约束

  • 库名:ServerEnv().get_module_dbname('pbl_blueprint')禁止硬编码 DBNAME
  • SQL 只用 sqlor 标准 APIsor.C / sor.U / sor.D / sor.R / sor.sqlExe,禁编造 save/list/insert
  • 建表:db.ensure_tables() 幂等执行 sql/*.sqlCREATE TABLE IF NOT EXISTS

11. API 路径25 个,见 api.py API_PATHS

前缀 /pbl_blueprint/,分四组:blueprint/*(7)、version/*(4)、subobject/*(7)、template/*(7)。 RBAC 注册:python -m pbl_blueprint.scripts.load_path(幂等,注册 API + 页面 + 表权限共 39 条路径)。

12. 下游模块依赖

  • pbl_validationM2get_blueprint_tree 做 14 维校验,回写 quality_level
  • pbl_compilerM3读蓝图树生成 Game Definition
  • pbl_evidenceM5evidence_spec / artifact_spec 采集
  • pbl_assessmentM6learning_goal.weight / reflection_spec.rubric_ref 评分
  • pbl_agent_runtimeM4batch_upsert_subobjects 写 Designer 产出fail-closed 裁决