Skip to content

Commit 2f8e5a7

Browse files
committed
Hard-retire assay and legacy file_set surfaces
1 parent 1cfaf20 commit 2f8e5a7

File tree

15 files changed

+77
-397
lines changed

15 files changed

+77
-397
lines changed

bloom_lims/api/v1/stats.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ async def get_dashboard_stats(user: APIUser = Depends(require_api_auth)):
4646
"""
4747
Get dashboard statistics and recent activity.
4848
49-
Returns aggregated counts for assays, workflows, equipment, reagents,
49+
Returns aggregated counts for queue runtime, workflows, equipment, reagents,
5050
and recent activity across all object types.
5151
"""
5252
try:
@@ -74,7 +74,21 @@ async def get_dashboard_stats(user: APIUser = Depends(require_api_auth)):
7474
if str(getattr(row, "bstatus", "") or "").strip().lower() in {"open", "active"}
7575
]
7676

77-
stats.assays_total = len(queue_definitions)
77+
queue_statuses = [
78+
str(getattr(row, "bstatus", "") or "").strip().lower()
79+
for row in queue_definitions
80+
]
81+
82+
stats.queue_runtime_total = len(queue_definitions)
83+
stats.queue_runtime_in_progress = len(
84+
[status for status in queue_statuses if status in {"active", "open", "in_progress"}]
85+
)
86+
stats.queue_runtime_complete = len(
87+
[status for status in queue_statuses if status in {"complete", "completed"}]
88+
)
89+
stats.queue_runtime_exception = len(
90+
[status for status in queue_statuses if status in {"exception", "failed", "error"}]
91+
)
7892
stats.workflows_total = len(work_items)
7993
stats.workflows_active = len(open_work_items)
8094

@@ -112,12 +126,12 @@ async def get_dashboard_stats(user: APIUser = Depends(require_api_auth)):
112126
recent_activity = RecentActivitySchema()
113127

114128
try:
115-
recent_assays = sorted(
129+
recent_queue_runtime = sorted(
116130
[row for row in generic_rows if _beta_kind(row) == "queue_definition"],
117131
key=lambda row: row.created_dt or datetime.min.replace(tzinfo=UTC),
118132
reverse=True,
119133
)[:5]
120-
recent_activity.recent_assays = [
134+
recent_activity.recent_queue_runtime = [
121135
RecentActivityItem(
122136
euid=a.euid,
123137
name=a.name,
@@ -126,7 +140,7 @@ async def get_dashboard_stats(user: APIUser = Depends(require_api_auth)):
126140
status=a.bstatus,
127141
created_dt=a.created_dt,
128142
)
129-
for a in recent_assays
143+
for a in recent_queue_runtime
130144
]
131145

132146
recent_workflows = sorted(
Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1 @@
1-
{
2-
"add-file": {
3-
"1.0": {
4-
"action_definition": {
5-
"action_name": "Add File To Set",
6-
"method_name": "do_action_add_file_to_file_set",
7-
"action_executed": "0",
8-
"max_executions": "-1",
9-
"action_enabled": "1",
10-
"capture_data": "yes",
11-
"captured_data": {},
12-
"deactivate_actions_when_executed": [],
13-
"executed_datetime": [],
14-
"action_order": "0",
15-
"action_simple_value": "",
16-
"action_user": [],
17-
"curr_user": "",
18-
"description": "Add a file to a file set.",
19-
"ui_schema": {
20-
"title": "Add File To Set",
21-
"fields": []
22-
}
23-
}
24-
}
25-
},
26-
"remove-file": {
27-
"1.0": {
28-
"action_definition": {
29-
"action_name": "Remove File From File Set",
30-
"method_name": "do_action_remove_file_from_file_set",
31-
"action_executed": "0",
32-
"max_executions": "-1",
33-
"action_enabled": "1",
34-
"capture_data": "yes",
35-
"captured_data": {},
36-
"deactivate_actions_when_executed": [],
37-
"executed_datetime": [],
38-
"action_order": "0",
39-
"action_simple_value": "",
40-
"action_user": [],
41-
"curr_user": "",
42-
"description": "Remove a file from a file set.",
43-
"ui_schema": {
44-
"title": "Remove File From File Set",
45-
"fields": []
46-
}
47-
}
48-
}
49-
}
50-
}
1+
{}

bloom_lims/config/action/test_requisitions.json

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,4 @@
11
{
2-
"add_container_to_assay_q": {
3-
"1.0": {
4-
"action_definition": {
5-
"action_enabled": "1",
6-
"action_executed": "0",
7-
"action_name": "Add Specimen to Assay Queue",
8-
"action_order": "0",
9-
"action_simple_value": "",
10-
"action_user": [],
11-
"capture_data": "yes",
12-
"captured_data": {},
13-
"curr_user": "",
14-
"deactivate_actions_when_executed": [],
15-
"executed_datetime": [],
16-
"max_executions": "-1",
17-
"method_name": "do_action_add_container_to_assay_q",
18-
"printer_opts": {
19-
"label_style": "",
20-
"printer_name": ""
21-
},
22-
"workflow_obj": {
23-
"workflow/assay/generic/1.0": {
24-
"json_addl": {
25-
"properties": {
26-
"step_number": "1"
27-
}
28-
}
29-
}
30-
},
31-
"ui_schema": {
32-
"title": "Add Specimen to Assay Queue",
33-
"fields": [
34-
{
35-
"name": "assay_selection",
36-
"type": "select",
37-
"required": true,
38-
"options_source": "workflow_assays"
39-
}
40-
]
41-
}
42-
},
43-
"properties": {
44-
"comments": "",
45-
"name": ""
46-
}
47-
}
48-
},
49-
"add_container_to_assay_q__pan_cancer_panel": {
50-
"1.0": {
51-
"action_definition": {
52-
"action_enabled": "1",
53-
"action_executed": "0",
54-
"action_name": "Add Specimen to Assay Queue",
55-
"action_order": "0",
56-
"action_simple_value": "",
57-
"action_user": [],
58-
"capture_data": "yes",
59-
"captured_data": {},
60-
"curr_user": "",
61-
"deactivate_actions_when_executed": [],
62-
"executed_datetime": [],
63-
"max_executions": "-1",
64-
"method_name": "do_action_add_container_to_assay_q",
65-
"printer_opts": {
66-
"label_style": "",
67-
"printer_name": ""
68-
},
69-
"workflow_obj": {
70-
"workflow/assay/generic/1.0": {
71-
"json_addl": {
72-
"properties": {
73-
"step_number": "1"
74-
}
75-
}
76-
}
77-
},
78-
"ui_schema": {
79-
"title": "Add Specimen to Assay Queue",
80-
"fields": [
81-
{
82-
"name": "assay_selection",
83-
"type": "select",
84-
"required": true,
85-
"options_source": "workflow_assays"
86-
}
87-
]
88-
}
89-
},
90-
"properties": {
91-
"comments": "",
92-
"name": ""
93-
}
94-
}
95-
},
962
"set_verification_state": {
973
"1.0": {
984
"action_definition": {

bloom_lims/config/test_requisition/clinical.json

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
"1.0": {
44
"action_groups": {},
55
"action_imports": {
6-
"add_container_to_assay_q": "action/test_requisitions/add_container_to_assay_q__pan_cancer_panel/1.0",
76
"add_relationships": "action/core/add-relationships/1.0",
87
"create_subject_and_anchor": "action/core/create-subject-and-anchor/1.0",
98
"print_barcode_label": "action/core/print_barcode_label/1.0",
@@ -28,14 +27,7 @@
2827
"name": "pan-cancer 239 Gene Panel Requisition"
2928
},
3029
"singleton": "0",
31-
"valid_parents": [
32-
{
33-
"workflow/assay/hla-typing/1.2/": {}
34-
},
35-
{
36-
"workflow/assay/carrier-screen/3.9/": {}
37-
}
38-
]
30+
"valid_parents": []
3931
}
4032
}
4133
}

bloom_lims/config/test_requisition/research.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
"1.0": {
44
"action_groups": {},
55
"action_imports": {
6-
"add_container_to_assay_q": "action/test_requisitions/add_container_to_assay_q/1.0",
7-
"add_container_to_assay_q_pan_cancer_panel": "action/test_requisitions/add_container_to_assay_q__pan_cancer_panel/1.0",
86
"add_relationships": "action/core/add-relationships/1.0",
97
"create_subject_and_anchor": "action/core/create-subject-and-anchor/1.0",
108
"print_barcode_label": "action/core/print_barcode_label/1.0",

bloom_lims/gui/actions.py

Lines changed: 11 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
from __future__ import annotations
22

33
import copy
4-
from html import escape as html_escape
54

65
from bloom_lims.bobjs import BloomObj
76

87

9-
def _build_assay_selection_options(_bobdb: BloomObj) -> list[dict]:
10-
"""Workflow-backed assay selection is retired in queue-centric Bloom beta."""
11-
return []
12-
13-
148
def _normalize_action_slug(action_data: dict) -> str:
159
method_name = str(action_data.get("method_name") or "").strip()
1610
if method_name.startswith("do_action_"):
@@ -66,27 +60,13 @@ def _default_ui_fields_for_action(action_data: dict) -> list[dict]:
6660
return []
6761

6862

69-
def _build_assay_selection_html(options: list[dict]) -> str:
70-
rendered_options = []
71-
for option in options:
72-
option_value = html_escape(str(option.get("value", "")), quote=True)
73-
option_label = html_escape(str(option.get("label", "")))
74-
rendered_options.append(f'<option value="{option_value}">{option_label}</option>')
75-
76-
if not rendered_options:
77-
rendered_options.append('<option value="" disabled selected>No assay workflows available</option>')
78-
79-
return '<select name="assay_selection" required>' + "".join(rendered_options) + "</select>"
80-
81-
8263
def hydrate_dynamic_action_groups(action_groups: dict, bobdb: BloomObj) -> dict:
83-
"""Hydrate dynamic UI bits inside action groups (assay dropdown, etc)."""
64+
"""Hydrate dynamic UI bits for active action surfaces only."""
65+
del bobdb # Legacy assay/workflow hydration is retired.
8466
if not isinstance(action_groups, dict):
8567
return {}
8668

8769
hydrated = copy.deepcopy(action_groups)
88-
assay_selection_options = None
89-
assay_selection_html = None
9070

9171
for group_data in hydrated.values():
9272
if not isinstance(group_data, dict):
@@ -117,23 +97,14 @@ def hydrate_dynamic_action_groups(action_groups: dict, bobdb: BloomObj) -> dict:
11797
ui_schema["fields"] = copy.deepcopy(default_fields)
11898
fields = ui_schema["fields"]
11999

120-
if isinstance(captured, dict) and "___workflow/assay/" in captured:
121-
if assay_selection_options is None:
122-
assay_selection_options = _build_assay_selection_options(bobdb)
123-
if assay_selection_html is None:
124-
assay_selection_html = _build_assay_selection_html(assay_selection_options)
125-
captured["___workflow/assay/"] = assay_selection_html
126-
127-
for field in fields:
128-
if not isinstance(field, dict):
129-
continue
130-
if field.get("options_source") == "workflow_assays":
131-
if assay_selection_options is None:
132-
assay_selection_options = _build_assay_selection_options(bobdb)
133-
if assay_selection_html is None:
134-
assay_selection_html = _build_assay_selection_html(assay_selection_options)
135-
field["options"] = copy.deepcopy(assay_selection_options)
136-
if field.get("name") == "assay_selection":
137-
captured.setdefault("___workflow/assay/", assay_selection_html)
100+
# Hard-cut: remove retired assay/workflow-assay capture/UI selectors.
101+
captured.pop("___workflow/assay/", None)
102+
ui_schema["fields"] = [
103+
field
104+
for field in fields
105+
if isinstance(field, dict)
106+
and field.get("options_source") != "workflow_assays"
107+
and field.get("name") != "assay_selection"
108+
]
138109

139110
return hydrated

bloom_lims/gui/routes/operations.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -250,14 +250,6 @@ async def lims(request: Request, _=Depends(require_auth)):
250250
return RedirectResponse(url="/", status_code=303)
251251

252252

253-
@router.get("/assays", response_class=HTMLResponse)
254-
async def assays(request: Request, show_type: str = "all", _auth=Depends(require_auth)):
255-
raise HTTPException(
256-
status_code=410,
257-
detail="Assay workflow pages are retired in queue-centric Bloom beta.",
258-
)
259-
260-
261253
@router.get("/calculate_cogs_children")
262254
async def Acalculate_cogs_children(euid, request: Request, _auth=Depends(require_auth)):
263255
try:

bloom_lims/schemas/base.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,14 @@ class ErrorResponse(BloomBaseSchema):
153153
class DashboardStatsSchema(BloomBaseSchema):
154154
"""Dashboard statistics response schema."""
155155

156-
assays_total: int = Field(default=0, description="Total number of assays")
157-
assays_in_progress: int = Field(default=0, description="Assays in progress")
158-
assays_complete: int = Field(default=0, description="Completed assays")
159-
assays_exception: int = Field(default=0, description="Assays with exceptions")
156+
queue_runtime_total: int = Field(default=0, description="Total queue runtime objects")
157+
queue_runtime_in_progress: int = Field(
158+
default=0, description="Queue runtime objects in progress"
159+
)
160+
queue_runtime_complete: int = Field(default=0, description="Completed queue runtime objects")
161+
queue_runtime_exception: int = Field(
162+
default=0, description="Queue runtime objects with exceptions"
163+
)
160164

161165
workflows_total: int = Field(default=0, description="Total number of workflows")
162166
workflows_active: int = Field(default=0, description="Active workflows")
@@ -188,8 +192,8 @@ class RecentActivityItem(BloomBaseSchema):
188192
class RecentActivitySchema(BloomBaseSchema):
189193
"""Recent activity response schema."""
190194

191-
recent_assays: List[RecentActivityItem] = Field(
192-
default_factory=list, description="Recent assay activities"
195+
recent_queue_runtime: List[RecentActivityItem] = Field(
196+
default_factory=list, description="Recent queue runtime activities"
193197
)
194198
recent_workflows: List[RecentActivityItem] = Field(
195199
default_factory=list, description="Recent workflow activities"

0 commit comments

Comments
 (0)