From c5c478bef6c3b8d934d78318ef50fc1fe914f96a Mon Sep 17 00:00:00 2001 From: Mathieu Moran Date: Tue, 11 Aug 2026 02:07:59 -0400 Subject: [PATCH] fix(phase26): add Pi trip deletion (BUG-08) --- app.py | 7 +++++++ modules/app_sql.py | 11 +++++++++++ server/templates/history.html | 1 + static/js/history.js | 3 ++- templates/base.html | 7 +++++++ templates/components.html | 4 ++-- templates/history.html | 4 +++- 7 files changed, 33 insertions(+), 4 deletions(-) diff --git a/app.py b/app.py index 792d9e5..6dd7540 100644 --- a/app.py +++ b/app.py @@ -146,6 +146,13 @@ def trip_route(trip_id): return jsonify(error=f"Trip not found: {trip_id}"), 404 return jsonify(trip) +@app.route('/api/trip/', methods=['DELETE']) +def delete_trip(trip_id): + deleted = app_sql.delete_trip(trip_id) + if not deleted: + return jsonify(error=f"Trip not found: {trip_id}"), 404 + return jsonify(status="deleted"), 200 + import functools import urllib.request diff --git a/modules/app_sql.py b/modules/app_sql.py index c6815c6..9b454b5 100644 --- a/modules/app_sql.py +++ b/modules/app_sql.py @@ -540,6 +540,17 @@ def get_trip_route(trip_id, max_points=2000): } +def delete_trip(trip_id): + """Delete a computed trip record. Raw tracking rows are NOT removed.""" + conn = get_conn() + if conn is None: + return False + with _conn_lock: + cur = conn.execute("DELETE FROM trips WHERE id = ?", (trip_id,)) + conn.commit() + return cur.rowcount > 0 + + def get_setting(key, default=None): """Read a persisted UI/app setting (e.g. the dashcam-upload toggle).""" conn = get_conn() diff --git a/server/templates/history.html b/server/templates/history.html index 5b97e9c..b4491b8 100644 --- a/server/templates/history.html +++ b/server/templates/history.html @@ -37,6 +37,7 @@ "Trips appear once the Pi has uploaded tracking data.", true ) }} + diff --git a/static/js/history.js b/static/js/history.js index 56c8cb6..0111c74 100644 --- a/static/js/history.js +++ b/static/js/history.js @@ -182,6 +182,7 @@ const tripList = document.getElementById("trip-list"); const deletable = tripList && tripList.dataset.deletable === "1"; + const deleteUrl = (tripList && tripList.dataset.deleteUrl) || "/api/trip/"; function renderTrips(trips) { body.replaceChildren(); @@ -225,7 +226,7 @@ window.confirmDelete(`Delete trip from ${date}?\n\nThe raw GPS data is kept — only this computed trip record is removed.`) .then(function(confirmed) { if (!confirmed) return; - return fetch(`/api/v1/portal/trip/${tripId}`, { method: "DELETE" }) + return fetch(deleteUrl + tripId, { method: "DELETE" }) .then(function(res) { if (!res.ok) throw new Error("Delete failed"); deleteBtn.closest("tr").remove(); diff --git a/templates/base.html b/templates/base.html index 0226c15..3a6340d 100644 --- a/templates/base.html +++ b/templates/base.html @@ -131,6 +131,13 @@ + + {# ── Shared confirmation helper ────────────────────────────────────────── #} + {% block scripts %}{% endblock %} diff --git a/templates/components.html b/templates/components.html index 324d25d..97e79e1 100644 --- a/templates/components.html +++ b/templates/components.html @@ -1,5 +1,5 @@ -{% macro data_table(id, columns, empty_title, empty_message) %} -
+{% macro data_table(id, columns, empty_title, empty_message, deletable=false) %} +