下一轮第 2 波的契约骨架:用户加 kind(服务账号)、剖析任务加上传表格的快照 id、工件按种类的索引;新模型文件 models_sources、models_eval(整模块导入);评测、访问密钥的路由模块和口径账本按运行读的路由先登记好权限(评测只给搭建者,访问密钥登录即可,账本按运行读的和证据同一道门)

This commit is contained in:
ThearchyHelios
2026-10-16 13:07:40 +08:00
parent 6854909dcd
commit 898e95a3ef
9 changed files with 50 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
"""访问密钥与服务账号(docs/design/next-round/04-对外集成与触达.md A1–A7)。
main.py 挂登录即可(require_role("user")):本人的个人密钥本人管,服务账号和全部密钥在接口里要管理员。第 2 波 W2-d 填。
"""
from __future__ import annotations
from fastapi import APIRouter
router = APIRouter(prefix="/api/access-keys", tags=["access-keys"])
+9
View File
@@ -0,0 +1,9 @@
"""评测接口(docs/design/next-round/01-效果度量与回归评测.md):题集、题目、期望答案试算、评测、结果、对比。
整组只给搭建者及以上(main.py 挂 require_role("builder"))。第 2 波 W2-c 起填。
"""
from __future__ import annotations
from fastapi import APIRouter
router = APIRouter(prefix="/api/evals", tags=["evals"])
+3
View File
@@ -16,6 +16,9 @@ from app.db.models import Workflow
from app.db.models_process import ActionRecord
router = APIRouter(prefix="/api/ledger", tags=["ledger"])
#: 口径账本里按运行读的那几个(一个答案里每个数的口径标签等,docs/design/next-round/02-口径账本.md):挂在
#: /api/runs/{run_id}/ledger… 下,和证据接口同一道门(main.py 挂 evidence_scope:使用者只读、而且要能读这次运行)
runs_router = APIRouter(prefix="/api/runs", tags=["ledger"])
@router.get("/workflow-versions/{workflow_id}/{version}")
+5
View File
@@ -245,6 +245,9 @@ _COLUMN_MIGRATIONS: list[tuple[str, str, str]] = [
("schedules", "target_kind", "VARCHAR(20) DEFAULT 'workflow'"),
("schedules", "target_id", "VARCHAR(32)"),
("schedule_fires", "eval_run_id", "VARCHAR(32)"),
# 第 2 波:服务账号(users.kind);剖析上传表格源时的快照
("users", "kind", "VARCHAR(20) DEFAULT 'person'"),
("catalog_profile_tasks", "snapshot_id", "VARCHAR(32)"),
]
#: 迁移补上的列要建的索引:(索引名, 表, 列或多列)。create_all 不碰已有的表,表上新列的索引也就不会建。
@@ -259,6 +262,8 @@ _INDEX_MIGRATIONS: list[tuple[str, str, str | tuple[str, ...]]] = [
("ix_runs_wf_ver_status", "runs", ("workflow_id", "version", "status")),
("ix_conversations_app_id", "conversations", "app_id"),
("ix_conversations_created_by", "conversations", "created_by"),
# 口径账本按种类反查工件(kind=caliber_match,next-round 02 做法 2)
("ix_artifacts_kind", "artifacts", "kind"),
]
+5
View File
@@ -521,6 +521,8 @@ class CatalogProfileTask(Base):
version: Mapped[int] = mapped_column(Integer, default=0)
# 整张表的原因:表结构里没有、视图、空表、没有可剖析的项、写入一直冲突、停止 / 中断 / 止损
error: Mapped[str | None] = mapped_column(Text, default=None)
# 剖析上传表格源时那一刻的快照(数据库源为空):上传表格换了版本之后,旧版本的剖析事实不再交给 look(next-round 遗留 e)
snapshot_id: Mapped[str | None] = mapped_column(String(32), default=None)
started_at: Mapped[datetime | None] = mapped_column(UTCDateTime, default=None)
finished_at: Mapped[datetime | None] = mapped_column(UTCDateTime, default=None)
@@ -1081,3 +1083,6 @@ from app.db.models_process import ( # noqa: E402,F401
from app.db.models_blueprints import ( # noqa: E402,F401
Blueprint, BlueprintEvent, PublishPlan, RecordsTable, StoredFile,
)
# 下一轮第 2 波(docs/design/next-round):数据源对象索引与后台探查(models_sources)、评测(models_eval)。整模块导入,
# 各自的模型类由那两个文件自己登记,这里不逐个列名
from app.db import models_eval, models_sources # noqa: E402,F401
+5
View File
@@ -0,0 +1,5 @@
"""评测:题集、题目、评测、结果(docs/design/next-round/01-效果度量与回归评测.md 做法 7)。
第 2 波 W2-c 填。由 app/db/models.py 末尾整模块导入,create_all 建表。
"""
from __future__ import annotations
+2
View File
@@ -28,6 +28,8 @@ class User(Base, TimestampMixin):
display_name: Mapped[str] = mapped_column(String(100), default="")
email: Mapped[str | None] = mapped_column(String(200), default=None)
role: Mapped[str] = mapped_column(String(20), default="user")
# person 人;service 服务账号(next-round 04 A1):管理员建,没有口令、不能登录,只持有访问密钥
kind: Mapped[str] = mapped_column(String(20), default="person")
# local 模式:hashlib.scrypt 的结果(含盐和参数);OIDC 用户为空
password_hash: Mapped[str | None] = mapped_column(Text, default=None)
oidc_issuer: Mapped[str | None] = mapped_column(String(300), default=None)
+5
View File
@@ -0,0 +1,5 @@
"""数据源的对象索引、探查范围、后台探查任务(docs/design/next-round/03-数据接入与目录维护.md A1)。
第 2 波 W2-a 填。由 app/db/models.py 末尾整模块导入,create_all 建表。
"""
from __future__ import annotations
+7
View File
@@ -18,6 +18,8 @@ from app.api import (
actions as actions_api, apps as apps_api, auth as auth_api, capabilities as capabilities_api, hooks as hooks_api,
identity as identity_api, ledger as ledger_api, notify as notify_api, tasks as tasks_api,
)
# 下一轮第 2 波(docs/design/next-round):评测、访问密钥
from app.api import access_keys as access_keys_api, evals as evals_api
# 普通用户建应用(docs/design/normal-user-apps.md §3.10):蓝图、模板、文件、个人应用。权限在接口里按蓝图的范围和拥有者判
from app.api import (
blueprints as blueprints_api, copilot_blueprint, files as files_api, personal as personal_api,
@@ -214,6 +216,8 @@ for router, guard in (
(bundle.router, [*_BUILDER, private_run_scope]),
(inquiry.router, [*_BUILDER, private_run_scope]),
(whatif.router, [*_BUILDER, private_run_scope]),
# 口径账本按运行读的接口(/api/runs/{run_id}/ledger…):和证据同一道门
(ledger_api.runs_router, [evidence_scope]),
(runs.router, [run_scope]),
(runs.approvals_router, _BUILDER),
(evidence.router, [evidence_scope]),
@@ -262,6 +266,9 @@ for router, guard in (
(hooks_api.router, []),
(notify_api.router, _USER),
(ledger_api.router, _BUILDER),
# 下一轮第 2 波:评测只给搭建者;访问密钥登录即可,接口里再按本人 / 管理员判
(evals_api.router, _BUILDER),
(access_keys_api.router, _USER),
):
app.include_router(router, dependencies=guard)