diff --git a/server.py b/server.py
index a88430c..d5044bb 100644
--- a/server.py
+++ b/server.py
@@ -1270,6 +1270,24 @@ def delete_asset(asset_id: int):
conn.close()
+@app.delete("/api/assets/{asset_id}/gps", status_code=204)
+def clear_asset_gps(asset_id: int):
+ """Clear GPS coordinates from an asset (sets latitude/longitude to NULL)."""
+ conn = get_db()
+ existing = conn.execute("SELECT id, name FROM assets WHERE id = ?", (asset_id,)).fetchone()
+ if existing is None:
+ conn.close()
+ raise HTTPException(status_code=404, detail="Asset not found")
+ conn.execute(
+ "UPDATE assets SET latitude = NULL, longitude = NULL, updated_at = datetime('now') WHERE id = ?",
+ (asset_id,),
+ )
+ _log_activity(conn, "updated", "asset", asset_id,
+ f"GPS data cleared for '{existing['name']}'")
+ conn.commit()
+ conn.close()
+
+
# ─── Task 8: POST /api/checkins ─────────────────────────────────────────────
diff --git a/static/index.html b/static/index.html
index 508558d..813d5e9 100644
--- a/static/index.html
+++ b/static/index.html
@@ -1249,6 +1249,7 @@
+
@@ -3605,6 +3606,14 @@
navBtn.style.display = 'none';
}
+ // Clear GPS button — show when asset has GPS
+ const clearGpsBtn = document.getElementById('detailClearGpsBtn');
+ if (a.latitude != null && a.longitude != null) {
+ clearGpsBtn.style.display = '';
+ } else {
+ clearGpsBtn.style.display = 'none';
+ }
+
// Keys + Badges
const keys = a.keys || [];
const badges = a.badges || (Array.isArray(a.badge_names) ? a.badge_names : []);
@@ -3996,6 +4005,24 @@
}
}
+ // ── Clear GPS ──────────────────────────────────────────────────────────
+ async function clearAssetGps() {
+ if (!AppState.currentAssetId) return;
+ const confirmed = await showModal(
+ 'Clear GPS Data',
+ 'Remove GPS coordinates from this asset?',
+ 'Clear GPS'
+ );
+ if (!confirmed) return;
+ try {
+ await api('/api/assets/' + AppState.currentAssetId + '/gps', { method: 'DELETE' });
+ showToast('GPS data cleared');
+ viewAsset(AppState.currentAssetId);
+ } catch (e) {
+ showToast(e.message, true);
+ }
+ }
+
// ── Delete ────────────────────────────────────────────────────────────
async function deleteAsset() {
if (!AppState.currentAssetId) return;
diff --git a/tests/test_server.py b/tests/test_server.py
index 262e933..1abedfd 100644
--- a/tests/test_server.py
+++ b/tests/test_server.py
@@ -432,6 +432,31 @@ class TestDeleteAsset:
assert response.status_code == 404
+class TestClearAssetGps:
+ """Clear GPS endpoint."""
+
+ def test_clear_gps_returns_204(self, client):
+ """Clear GPS returns 204 and sets lat/lng to null."""
+ r = client.post("/api/assets", json={
+ "machine_id": "GPS001", "name": "Has GPS",
+ "latitude": 28.5, "longitude": -81.3
+ })
+ asset_id = r.json()["id"]
+ response = client.delete(f"/api/assets/{asset_id}/gps")
+ assert response.status_code == 204
+
+ # Verify lat/lng are cleared
+ r2 = client.get(f"/api/assets/{asset_id}")
+ assert r2.status_code == 200
+ data = r2.json()
+ assert data["latitude"] is None
+ assert data["longitude"] is None
+
+ def test_clear_gps_not_found_returns_404(self, client):
+ response = client.delete("/api/assets/99999/gps")
+ assert response.status_code == 404
+
+
# ─── Task 7: GET /api/assets/search?machine_id= ───────────────────────────