# cockpit_project_tasks.dspy - Return clean task list for current project # Used by cockpit project button to show task tree import json uid = await get_user() if not uid: return json.dumps({"tasks": [], "error": "请先登录"}, ensure_ascii=False) dbname = get_module_dbname('pipeline-sdlc') # Get current project and tasks in one session async with DBPools().sqlorContext(dbname) as sor: recs = await sor.sqlExe( "SELECT current_project_id FROM pipeline_agent_settings WHERE user_id=${uid}$", {"uid": uid}) pid = getattr(recs[0], 'current_project_id', '') if recs else '' if not pid: return json.dumps({"tasks": [], "error": "没有当前项目"}, ensure_ascii=False) # Get project name pname = '' precs = await sor.sqlExe( "SELECT name FROM sd_projects WHERE id=${pid}$", {"pid": pid}) if precs and len(precs) > 0: pname = getattr(precs[0], 'name', '') or '' # Get tasks tasks = await sor.sqlExe( "SELECT id, title, state, current_version, created_at, params, role " "FROM pipeline_tasks WHERE tenant_id='0' ORDER BY created_at DESC LIMIT 50", {}) task_list = [] for t in tasks: d = {} raw = vars(t) if hasattr(t, '__dict__') else {} for k, v in raw.items(): if not callable(v) and not k.startswith('_'): if k == 'params' and v: try: p = json.loads(v) if isinstance(v, str) else v desc = p.get('description', '') or p.get('input_text', '') or '' d['description'] = desc[:60] except: d['description'] = '' elif k not in ('clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'to_dict'): v_str = str(v) if v is not None else '' d[k] = v_str task_list.append(d) return json.dumps({ "project_name": pname, "project_id": pid, "tasks": task_list }, ensure_ascii=False)