feat(nav,stats): Events sidebar entry + 'Overall Peak' excludes false triggers

Two related operator-facing improvements after the nav reorg.

1) Events as a top-level sidebar entry.

The /sfm page (fleet-wide event database) was demoted to Settings →
Developer in the previous reorg.  Bringing it back to main nav as
"Events" — operators do reach for the cross-project, sortable
event list, so it earns a top-level slot.

Sidebar now (7 items):
  Dashboard · Devices · Projects · Events · Tools · Job Planner · Settings

Settings → Developer card pointing at /sfm is removed.  /sfm page
title/subtitle updated from "SFM Event Data" to just "Events".  URL
unchanged.

2) "Peak PVS" KPI tile becomes "Overall Peak" and excludes false
   triggers from the calculation.

When operators ask "what's the biggest event at this location/unit/
project?" they mean the biggest REAL event, not the biggest sensor
glitch.  A single mis-flagged false trigger could otherwise dominate
the tile (the 14.13 in/s spike at Loc 1 was a prime example).

backend/services/sfm_events.py:
- _compute_stats() skips false_trigger=True events when computing
  peak_pvs / peak_pvs_at / peak_pvs_serial.  Continues counting them
  in false_trigger_count so the separate "False Triggers" tile still
  reflects what got filtered out.  last_event unchanged (recency, not
  magnitude).
- Same change automatically propagates to events_for_unit() and
  vibration_summary_for_project() — both call _compute_stats().

Templates: "Peak PVS" → "Overall Peak" in 3 KPI tile locations
(vibration_location_detail.html, partials/projects/vibration_summary
.html, unit_detail.html).  The physical-quantity name "Peak Vector
Sum" in the event-detail modal stays — that's the actual physics
term, not a summary stat.

Verified end-to-end: Overall Peak renders on real data; peak event
false_trigger flag confirmed False.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-13 16:13:37 +00:00
parent 737901c962
commit e15481884a
7 changed files with 36 additions and 27 deletions
@@ -23,7 +23,7 @@
<span class="text-2xl font-bold text-gray-900 dark:text-white mt-1">{{ "{:,}".format(summary.total_events) }}</span>
</div>
<div class="bg-gray-50 dark:bg-slate-900/50 rounded-lg p-3 flex flex-col">
<span class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider">Peak PVS</span>
<span class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider">Overall Peak</span>
{% if summary.peak_pvs is not none %}
<span class="text-2xl font-bold text-gray-900 dark:text-white mt-1">{{ "%.4f"|format(summary.peak_pvs) }} <span class="text-sm font-normal">in/s</span></span>
<a href="/projects/{{ summary.project_id }}/nrl/{{ summary.peak_pvs_location_id }}"