2424router = APIRouter (prefix = "/stats" , tags = ["Statistics" ])
2525
2626
27+ def _props (instance : Any ) -> Dict [str , Any ]:
28+ payload = instance .json_addl if isinstance (instance .json_addl , dict ) else {}
29+ props = payload .get ("properties" , {})
30+ return props if isinstance (props , dict ) else {}
31+
32+
33+ def _beta_kind (instance : Any ) -> str :
34+ return str (_props (instance ).get ("beta_kind" ) or "" ).strip ()
35+
36+
2737def get_bdb (username : str = "anonymous" ):
2838 """Get database connection."""
2939 from bloom_lims .db import BLOOMdb3
@@ -44,19 +54,29 @@ async def get_dashboard_stats(user: APIUser = Depends(require_api_auth)):
4454
4555 # Gather statistics
4656 stats = DashboardStatsSchema ()
57+ generic_rows : list [Any ] = []
4758
4859 try :
49- # Workflow/Assay counts
50- wf_class = bdb .Base .classes .workflow_instance
51- stats .workflows_total = (
52- bdb .session .query (wf_class ).filter_by (is_deleted = False ).count ()
53- )
54- stats .assays_total = (
55- bdb .session .query (wf_class )
56- .filter_by (is_deleted = False , is_singleton = True )
57- .count ()
60+ generic_rows = (
61+ bdb .session .query (bdb .Base .classes .generic_instance )
62+ .filter_by (is_deleted = False )
63+ .all ()
5864 )
59- stats .workflows_active = stats .workflows_total
65+ queue_definitions = [
66+ row for row in generic_rows if _beta_kind (row ) == "queue_definition"
67+ ]
68+ work_items = [
69+ row for row in generic_rows if _beta_kind (row ) == "beta_work_item"
70+ ]
71+ open_work_items = [
72+ row
73+ for row in work_items
74+ if str (getattr (row , "bstatus" , "" ) or "" ).strip ().lower () in {"open" , "active" }
75+ ]
76+
77+ stats .assays_total = len (queue_definitions )
78+ stats .workflows_total = len (work_items )
79+ stats .workflows_active = len (open_work_items )
6080
6181 # Equipment counts
6282 eq_class = bdb .Base .classes .equipment_instance
@@ -92,41 +112,33 @@ async def get_dashboard_stats(user: APIUser = Depends(require_api_auth)):
92112 recent_activity = RecentActivitySchema ()
93113
94114 try :
95- wf_class = bdb .Base .classes .workflow_instance
96-
97- # Recent assays (singleton workflows)
98- recent_assays = (
99- bdb .session .query (wf_class )
100- .filter_by (is_deleted = False , is_singleton = True )
101- .order_by (wf_class .created_dt .desc ())
102- .limit (5 )
103- .all ()
104- )
115+ recent_assays = sorted (
116+ [row for row in generic_rows if _beta_kind (row ) == "queue_definition" ],
117+ key = lambda row : row .created_dt or datetime .min .replace (tzinfo = UTC ),
118+ reverse = True ,
119+ )[:5 ]
105120 recent_activity .recent_assays = [
106121 RecentActivityItem (
107122 euid = a .euid ,
108123 name = a .name ,
109- type = a .type or "workflow " ,
124+ type = a .type or "queue_runtime " ,
110125 subtype = a .subtype ,
111126 status = a .bstatus ,
112127 created_dt = a .created_dt ,
113128 )
114129 for a in recent_assays
115130 ]
116131
117- # Recent workflows
118- recent_workflows = (
119- bdb .session .query (wf_class )
120- .filter_by (is_deleted = False )
121- .order_by (wf_class .created_dt .desc ())
122- .limit (5 )
123- .all ()
124- )
132+ recent_workflows = sorted (
133+ [row for row in generic_rows if _beta_kind (row ) == "beta_work_item" ],
134+ key = lambda row : row .created_dt or datetime .min .replace (tzinfo = UTC ),
135+ reverse = True ,
136+ )[:5 ]
125137 recent_activity .recent_workflows = [
126138 RecentActivityItem (
127139 euid = w .euid ,
128140 name = w .name ,
129- type = w .type or "workflow " ,
141+ type = w .type or "queue_runtime " ,
130142 subtype = w .subtype ,
131143 status = w .bstatus ,
132144 created_dt = w .created_dt ,
0 commit comments