From 70ca39efaab0dbb07b65c97f1e050f23f5fa13c6 Mon Sep 17 00:00:00 2001 From: Nameru Thapa Date: Sun, 6 Sep 2026 13:25:51 +0200 Subject: [PATCH 1/2] feat: give each kiosk, admin, and warehouse tab its own permanent URL --- app/routes.py | 42 ++++++--- app/templates/admin_inventory.html | 17 ++-- app/templates/admin_jobs.html | 9 +- app/templates/admin_photos.html | 13 +-- app/templates/job_detail.html | 9 +- app/templates/kiosk_index.html | 45 +++++++++ app/templates/transfer_requests.html | 19 +--- app/templates/worker_kiosk.html | 133 +++++---------------------- 8 files changed, 115 insertions(+), 172 deletions(-) create mode 100644 app/templates/kiosk_index.html diff --git a/app/routes.py b/app/routes.py index b43f7f2..ae9af9e 100644 --- a/app/routes.py +++ b/app/routes.py @@ -267,6 +267,8 @@ def job_detail(job_id): product_units=product_units, transfer_requests=transfer_requests, ) + + @bp.route( "/admin/jobs//activate", methods=["POST"], @@ -294,6 +296,8 @@ def activate_job_route(job_id): return redirect( url_for("main.job_detail", job_id=job.id) ) + + @bp.route("/admin/photos", methods=["GET", "POST"]) def admin_photos(): if request.method == "POST": @@ -328,7 +332,6 @@ def admin_photos(): ) - @bp.route("/admin/inventory", methods=["GET", "POST"]) def admin_inventory(): if request.method == "POST": @@ -457,6 +460,7 @@ def admin_inventory(): inventory_rows=inventory_rows, ) + @bp.route("/warehouse/requests") def warehouse_requests(): transfer_requests = TransferRequest.query.order_by( @@ -497,11 +501,27 @@ def fulfill_request_route(request_id): return redirect( url_for("main.warehouse_requests") ) -@bp.route("/kiosk", methods=["GET", "POST"]) -def worker_kiosk(): + + +@bp.route("/kiosk") +def kiosk_index(): stations = Station.query.order_by(Station.id).all() - selected_station_id = "" + return render_template( + "kiosk_index.html", + stations=stations, + ) + + +@bp.route("/kiosk/", methods=["GET", "POST"]) +def worker_kiosk(station_id): + normalized_station_id = (station_id or "").strip().upper() + + station = db.session.get(Station, normalized_station_id) + + if station is None or not station.enabled: + abort(404, description="Unknown or disabled station.") + entered_barcode = "" step = None current_unit = None @@ -513,11 +533,6 @@ def worker_kiosk(): scan_message = None if request.method == "POST": - selected_station_id = request.form.get( - "station_id", - "", - ).strip() - entered_barcode = request.form.get( "barcode", "", @@ -537,7 +552,7 @@ def worker_kiosk(): else: result, error = complete_current_step( job, - selected_station_id, + normalized_station_id, ) if error is None: @@ -616,19 +631,18 @@ def worker_kiosk(): else: step, error = scan_job_barcode( entered_barcode, - selected_station_id, + normalized_station_id, ) if error is None: current_unit, step = get_current_unit_and_step( step.job, - selected_station_id, + normalized_station_id, ) return render_template( "worker_kiosk.html", - stations=stations, - selected_station_id=selected_station_id, + station=station, entered_barcode=entered_barcode, step=step, current_unit=current_unit, diff --git a/app/templates/admin_inventory.html b/app/templates/admin_inventory.html index fac2184..bf604aa 100644 --- a/app/templates/admin_inventory.html +++ b/app/templates/admin_inventory.html @@ -13,25 +13,22 @@ > +

The Digital Factory Game

Production Jobs | - - Instruction Photos - - | - - Warehouse Requests + + Station Inventory | - - Worker Kiosk + + Instruction Photos

-

Station Inventory

+

Station Inventory

Add Part to Station Inventory

@@ -189,4 +186,4 @@

No station inventory entered yet.

{% endif %} - \ No newline at end of file + diff --git a/app/templates/admin_jobs.html b/app/templates/admin_jobs.html index 3db76c9..efc3b52 100644 --- a/app/templates/admin_jobs.html +++ b/app/templates/admin_jobs.html @@ -13,19 +13,16 @@ > +

The Digital Factory Game

Production Jobs | Station Inventory | Instruction Photos - | - Warehouse Requests - | - Worker Kiosk

-

Production Jobs

+

Production Jobs

Create Production Job

{% if error %} @@ -90,4 +87,4 @@

No production jobs created yet.

{% endif %} - \ No newline at end of file + diff --git a/app/templates/admin_photos.html b/app/templates/admin_photos.html index 14a2328..20f099d 100644 --- a/app/templates/admin_photos.html +++ b/app/templates/admin_photos.html @@ -13,6 +13,7 @@ > +

The Digital Factory Game

Production Jobs @@ -25,17 +26,9 @@ Instruction Photos - | - - Warehouse Requests - - | - - Worker Kiosk -

-

Instruction Photos

+

Instruction Photos

Upload Instruction Photo

@@ -111,4 +104,4 @@

No instruction photos uploaded yet.

{% endif %} - \ No newline at end of file + diff --git a/app/templates/job_detail.html b/app/templates/job_detail.html index 1337f13..57dcbe8 100644 --- a/app/templates/job_detail.html +++ b/app/templates/job_detail.html @@ -13,19 +13,16 @@ > +

The Digital Factory Game

Production Jobs | Station Inventory | Instruction Photos - | - Warehouse Requests - | - Worker Kiosk

-

{{ job.name }}

+

{{ job.name }}

Status: {{ job.status }}

Production Quantity: {{ job.quantity }}

@@ -257,4 +254,4 @@

{% endif %} - \ No newline at end of file + diff --git a/app/templates/kiosk_index.html b/app/templates/kiosk_index.html new file mode 100644 index 0000000..bdfd417 --- /dev/null +++ b/app/templates/kiosk_index.html @@ -0,0 +1,45 @@ + + + + + + MES - Kiosk Directory + + + +

+ Production Jobs + | + Station Inventory + | + Instruction Photos + | + Warehouse Requests + | + Kiosk Directory +

+ +

Kiosk Directory

+

+ Open each link below on its own device/tab and bookmark it. + Each link is a permanent address dedicated to one station. +

+ + + + \ No newline at end of file diff --git a/app/templates/transfer_requests.html b/app/templates/transfer_requests.html index 83c2f24..c1f1b39 100644 --- a/app/templates/transfer_requests.html +++ b/app/templates/transfer_requests.html @@ -13,21 +13,10 @@ > -

- Production Jobs - | - Station Inventory - | - Instruction Photos - | - Warehouse Requests - | - Worker Kiosk -

+

The Digital Factory Game

+

Warehouse Transfer Requests

-

Warehouse Transfer Requests

- -

Manage station replenishment requests.

+

Manage station replenishment requests.

{% if transfer_requests %} @@ -83,4 +72,4 @@

No transfer requests.

{% endif %} - \ No newline at end of file + diff --git a/app/templates/worker_kiosk.html b/app/templates/worker_kiosk.html index 6ea2ca1..4fc5ada 100644 --- a/app/templates/worker_kiosk.html +++ b/app/templates/worker_kiosk.html @@ -6,46 +6,19 @@ name="viewport" content="width=device-width, initial-scale=1" > - MES - Worker Kiosk + MES - Worker Kiosk {{ station.id }} -

- Production Jobs - | - Station Inventory - | - Instruction Photos - | - Warehouse Requests - | - Worker Kiosk -

- -

Worker Kiosk

+

The Digital Factory Game

+

{{ station.name }}

-

-
- -

-


{% if error %} -

- Error: {{ error }} -

+

Error: {{ error }}

{% endif %} {% if message %} -

- {{ message }} -

+

{{ message }}

{% endif %} {% if stock_message %} -

- Material Alert: - {{ stock_message }} -

+

Material Alert: {{ stock_message }}

{% endif %} {% if completion_message %} -

- {{ completion_message }} -

+

{{ completion_message }}

{% endif %} {% if transition_message %} -

- {{ transition_message }} -

+

{{ transition_message }}

{% endif %} {% if scan_message %} -

- {{ scan_message }} -

+

{{ scan_message }}

{% endif %} {% if step and current_unit %}
-

{{ step.job.name }}

- -

- Job Barcode: - {{ step.job.barcode }} -

- -

- Product Unit: - {{ current_unit.unit_number }} - of {{ step.job.quantity }} -

- -

- Station: - {{ step.station.name }} -

- +

Job Barcode: {{ step.job.barcode }}

+

Product Unit: {{ current_unit.unit_number }} of {{ step.job.quantity }}

+

Station: {{ step.station.name }}

Production Step {{ step.step_number }}

- -

- Instruction: - {{ step.instruction }} -

+

Instruction: {{ step.instruction }}

{% if step.photo_url %} - {% if step.photo_url.startswith( - 'uploads/step_photos/' - ) %} -

- Instruction Photo: -

- + {% if step.photo_url.startswith('uploads/step_photos/') %} +

Instruction Photo:

Instruction photo for step {{ step.step_number }} {% else %} -

- Legacy Photo Reference: - {{ step.photo_url }} -

+

Legacy Photo Reference: {{ step.photo_url }}

{% endif %} {% endif %}

Required Parts

- {% if step.parts %}
    {% for usage in step.parts %} -
  • - {{ usage.part.name }} x {{ usage.quantity }} -
  • +
  • {{ usage.part.name }} x {{ usage.quantity }}
  • {% endfor %}
{% else %} @@ -165,26 +92,10 @@ {% endif %} - - - - - + + + {% endif %} - \ No newline at end of file + -- GitLab From 4bc8b61d815034fc4a625649c09d3aa2c7eaf5c7 Mon Sep 17 00:00:00 2001 From: Nameru Thapa Date: Sun, 6 Sep 2026 13:26:01 +0200 Subject: [PATCH 2/2] test: update kiosk tests for station-scoped URLs --- tests/test_parallel_station_flow.py | 16 ++++++++-------- tests/test_photo_upload.py | 3 +-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/tests/test_parallel_station_flow.py b/tests/test_parallel_station_flow.py index bbf5f81..c3209ad 100644 --- a/tests/test_parallel_station_flow.py +++ b/tests/test_parallel_station_flow.py @@ -257,6 +257,8 @@ def test_tc16_upstream_station_can_start_next_unit( assert unavailable_error == ( "This job is not ready at this station." ) + + def test_tc17_kiosk_requires_new_scan_after_completion(app): with app.app_context(): ids = create_parallel_station_job( @@ -267,9 +269,8 @@ def test_tc17_kiosk_requires_new_scan_after_completion(app): client = app.test_client() completion_response = client.post( - "/kiosk", + "/kiosk/ST-03", data={ - "station_id": "ST-03", "barcode": "MES-PARALLEL-001", "action": "complete", }, @@ -302,9 +303,8 @@ def test_tc17_kiosk_requires_new_scan_after_completion(app): assert ready_step.id == ids["upstream_step_id"] scan_response = client.post( - "/kiosk", + "/kiosk/ST-03", data={ - "station_id": "ST-03", "barcode": "MES-PARALLEL-001", "action": "scan", }, @@ -318,6 +318,8 @@ def test_tc17_kiosk_requires_new_scan_after_completion(app): ) assert "Product Unit: 2 of 2" in normalized_page + + def test_tc18_finished_unit_returns_kiosk_to_waiting(app): with app.app_context(): ids = create_parallel_station_job( @@ -339,9 +341,8 @@ def test_tc18_finished_unit_returns_kiosk_to_waiting(app): client = app.test_client() first_finished_response = client.post( - "/kiosk", + "/kiosk/ST-05", data={ - "station_id": "ST-05", "barcode": "MES-PARALLEL-001", "action": "complete", }, @@ -359,9 +360,8 @@ def test_tc18_finished_unit_returns_kiosk_to_waiting(app): ) final_finished_response = client.post( - "/kiosk", + "/kiosk/ST-05", data={ - "station_id": "ST-05", "barcode": "MES-PARALLEL-001", "action": "complete", }, diff --git a/tests/test_photo_upload.py b/tests/test_photo_upload.py index 0630958..21d69da 100644 --- a/tests/test_photo_upload.py +++ b/tests/test_photo_upload.py @@ -356,9 +356,8 @@ def test_tc33_worker_kiosk_displays_uploaded_photo(app): assert ProductUnit.query.count() == 1 kiosk_response = client.post( - "/kiosk", + "/kiosk/ST-04", data={ - "station_id": "ST-04", "barcode": barcode, "action": "scan", }, -- GitLab