pipeline-sdlc/wwwroot/api/cockpit_context_update.dspy

117 lines
4.9 KiB
Plaintext
Raw Permalink 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.

# cockpit_context_update.dspy - Save user's selected project/iteration to pipeline_agent_settings
# POST params: project_id, iteration_id (at least one required)
# Also looks up names for the newly set values
import json
uid = await get_user()
if not uid:
return json.dumps({"success": False, "error": "请先登录"}, ensure_ascii=False)
pid = (params_kw or {}).get('project_id', '')
iid = (params_kw or {}).get('iteration_id', '')
session_id = (params_kw or {}).get('session_id', '')
if not pid and not iid:
return json.dumps({"success": False, "error": "请提供 project_id 或 iteration_id"}, ensure_ascii=False)
dbname = get_module_dbname('pipeline-sdlc')
# 归属门禁2026-09-18 银联事故实锤):旧版无校验,任何登录用户可把**他机构**
# 项目 id 写进自己的会话指针cockpit 上下文栏直传),随后工作空间列表/读文件
# 端点按指针解析目录 → 看到他机构项目文件。校验对齐 agent_project_popup 切换
# 门禁:同机构 + 本人创建owner.superuser 放行,与 _check_confirm_operator 同口径)。
if pid:
async with DBPools().sqlorContext(dbname) as _gsor:
_pr = await _gsor.sqlExe(
"SELECT org_id, created_by FROM sd_projects WHERE id=${p}$ LIMIT 1", {"p": pid})
await _gsor.sqlExe("COMMIT", {})
if not _pr:
return json.dumps({"success": False, "error": "项目不存在"}, ensure_ascii=False)
_porg = getattr(_pr[0], 'org_id', '') or ''
_pby = getattr(_pr[0], 'created_by', '') or ''
_uorg = await get_userorgid() or ''
if _pby != uid:
from pipeline_service.human_task_capability import _get_user_roles
_roles = await _get_user_roles(_gsor, uid)
if "owner.superuser" not in _roles or (_porg and _uorg != _porg):
return json.dumps({"success": False,
"error": "无权切换到该项目(仅限本人创建的项目)"},
ensure_ascii=False)
async with DBPools().sqlorContext(dbname) as sor:
# Upsert agent_settings
existing = await sor.sqlExe(
"SELECT id, current_project_id, current_iteration_id FROM pipeline_agent_settings WHERE user_id=${uid}$",
{"uid": uid}
)
if existing:
cur_pid = getattr(existing[0], 'current_project_id', '') or ''
cur_iid = getattr(existing[0], 'current_iteration_id', '') or ''
new_pid = pid if pid else cur_pid
new_iid = iid if iid else ('' if pid else cur_iid)
# If project changed but iteration not specified, clear iteration
if pid and pid != cur_pid and not iid:
new_iid = ''
await sor.sqlExe(
"UPDATE pipeline_agent_settings SET current_project_id=${pid}$, current_iteration_id=${iid}$ WHERE user_id=${uid}$",
{"pid": new_pid, "iid": new_iid, "uid": uid}
)
else:
new_pid = pid
new_iid = iid
await sor.C('pipeline_agent_settings', {
'id': getID(),
'user_id': uid,
'current_project_id': new_pid,
'current_iteration_id': new_iid,
})
# 会话级项目上下文(多 tab 隔离):写 pipeline_session_settings
if session_id:
try:
await sor.sqlExe(
"UPDATE pipeline_session_settings SET current_project_id=${pid}$, current_iteration_id=${iid}$ "
"WHERE user_id=${uid}$ AND session_id=${sid}$",
{"pid": new_pid, "iid": new_iid, "uid": uid, "sid": session_id})
sexists = await sor.sqlExe(
"SELECT 1 FROM pipeline_session_settings WHERE user_id=${uid}$ AND session_id=${sid}$",
{"uid": uid, "sid": session_id})
if not sexists:
await sor.C('pipeline_session_settings', {
'id': getID(), 'user_id': uid, 'session_id': session_id,
'current_project_id': new_pid, 'current_iteration_id': new_iid,
})
except Exception:
pass
# Look up names
pname = ''
iname = ''
ws_dir = ''
if new_pid:
precs = await sor.sqlExe(
"SELECT name, workspace_dir FROM sd_projects WHERE id=${pid}$",
{"pid": new_pid}
)
if precs and len(precs) > 0:
pname = getattr(precs[0], 'name', '') or ''
ws_dir = getattr(precs[0], 'workspace_dir', '') or ''
if new_iid:
irecs = await sor.sqlExe(
"SELECT iteration_name FROM sd_iterations WHERE id=${iid}$",
{"iid": new_iid}
)
if irecs and len(irecs) > 0:
iname = getattr(irecs[0], 'iteration_name', '') or ''
return json.dumps({
"success": True,
"project_id": new_pid,
"iteration_id": new_iid,
"project_name": pname,
"iteration_name": iname,
"workspace_dir": ws_dir,
}, ensure_ascii=False)