# cockpit_stats.dspy - Returns dashboard stat cards as Bricks widget JSON dbname = get_module_dbname('pipeline-sdlc') async with DBPools().sqlorContext(dbname) as sor: # Active projects proj = await sor.sqlExe( "SELECT COUNT(*) as active FROM sd_projects WHERE status='active'", {}) active_projects = proj[0].active if proj else 0 # Active iterations iters = await sor.sqlExe( "SELECT COUNT(*) as cnt FROM sd_iterations WHERE status='in_progress'", {}) active_iters = iters[0].cnt if iters else 0 # Open bugs bugs = await sor.sqlExe( "SELECT COUNT(*) as cnt FROM sd_bugs WHERE status NOT IN ('closed','resolved')", {}) open_bugs = bugs[0].cnt if bugs else 0 # Pending reviews (human tasks) reviews = await sor.sqlExe( "SELECT COUNT(*) as cnt FROM pipeline_human_tasks WHERE status='pending'", {}) pending_reviews = reviews[0].cnt if reviews else 0 return { "widgettype": "ResponsableBox", "options": {"gap": "16px", "minWidth": "180px", "width": "100%"}, "subwidgets": [ { "widgettype": "VBox", "options": { "css": "card", "cwidth": 23, "cheight": 12, "padding": "20px", "bgcolor": "#fff", "borderRadius": "8px", "border": "1px solid #e2e8f0", "alignItems": "center", "gap": "6px", "cursor": "pointer" }, "binds": [{ "wid": "self", "event": "click", "actiontype": "urlwidget", "target": "app.main_content", "options": {"url": entire_url("/pipeline-sdlc/sd_projects/")}, "mode": "replace" }], "subwidgets": [ {"widgettype": "Text", "options": { "text": f"{active_projects}", "cfontsize": 2.2, "color": "#3b82f6", "fontWeight": "bold" }}, {"widgettype": "Text", "options": { "text": "活跃项目", "cfontsize": 0.9, "color": "#64748b" }} ] }, { "widgettype": "VBox", "options": { "css": "card", "cwidth": 23, "cheight": 12, "padding": "20px", "bgcolor": "#fff", "borderRadius": "8px", "border": "1px solid #e2e8f0", "alignItems": "center", "gap": "6px", "cursor": "pointer" }, "binds": [{ "wid": "self", "event": "click", "actiontype": "urlwidget", "target": "app.main_content", "options": {"url": entire_url("/pipeline-sdlc/sd_iterations/")}, "mode": "replace" }], "subwidgets": [ {"widgettype": "Text", "options": { "text": f"{active_iters}", "cfontsize": 2.2, "color": "#22c55e", "fontWeight": "bold" }}, {"widgettype": "Text", "options": { "text": "进行中迭代", "cfontsize": 0.9, "color": "#64748b" }} ] }, { "widgettype": "VBox", "options": { "css": "card", "cwidth": 23, "cheight": 12, "padding": "20px", "bgcolor": "#fff", "borderRadius": "8px", "border": "1px solid #e2e8f0", "alignItems": "center", "gap": "6px", "cursor": "pointer" }, "binds": [{ "wid": "self", "event": "click", "actiontype": "urlwidget", "target": "app.main_content", "options": {"url": entire_url("/pipeline-sdlc/sd_bugs/")}, "mode": "replace" }], "subwidgets": [ {"widgettype": "Text", "options": { "text": f"{open_bugs}", "cfontsize": 2.2, "color": "#f59e0b", "fontWeight": "bold" }}, {"widgettype": "Text", "options": { "text": "待处理Bug", "cfontsize": 0.9, "color": "#64748b" }} ] }, { "widgettype": "VBox", "options": { "css": "card", "cwidth": 23, "cheight": 12, "padding": "20px", "bgcolor": "#fff", "borderRadius": "8px", "border": "1px solid #e2e8f0", "alignItems": "center", "gap": "6px", "cursor": "pointer" }, "subwidgets": [ {"widgettype": "Text", "options": { "text": f"{pending_reviews}", "cfontsize": 2.2, "color": "#8b5cf6", "fontWeight": "bold" }}, {"widgettype": "Text", "options": { "text": "待审批", "cfontsize": 0.9, "color": "#64748b" }} ] } ] }