From c16ad7c7376bc4989a82c2241a06ab3d704ad1bd Mon Sep 17 00:00:00 2001 From: kaushik Date: Thu, 10 Sep 2026 15:14:11 +0530 Subject: [PATCH] ui tweaks with new frequency column --- CLAUDE.md | 10 + index.html | 13 ++ serve.cjs | 70 +++++++ src/api/adminService.ts | 40 ++++ src/components/common/TopFilterBar.tsx | 72 +++++-- src/components/common/parseSites.ts | 38 ++++ src/constants/media.ts | 14 ++ src/pages/activity-feeds/FeedFilters.tsx | 80 ++++++- src/pages/activity-feeds/GlobalFeed.tsx | 23 +- src/pages/admin/AdminConsole.tsx | 5 + src/pages/admin/AnomalyBrowser.tsx | 254 +++++++++++++++++++++++ src/pages/audit-session/AuditSession.tsx | 70 ++++++- src/pages/dashboard/Dashboard.tsx | 8 +- src/store/feedStore.ts | 20 ++ 14 files changed, 687 insertions(+), 30 deletions(-) create mode 100644 serve.cjs create mode 100644 src/components/common/parseSites.ts create mode 100644 src/pages/admin/AnomalyBrowser.tsx diff --git a/CLAUDE.md b/CLAUDE.md index 86fd67d..9b733cd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,9 +13,18 @@ root [CLAUDE.md](../CLAUDE.md); backend contracts in [auditor-backend/CLAUDE.md] ## Architecture notes (the non-obvious ones) +### Analytics (Microsoft Clarity) +`index.html` carries the Clarity snippet (project `y7dltvy3kb`), **gated to +`window.location.hostname === 'audit-frontend.seekright.com'`** — dev servers, +LAN-IP visits and test flows deliberately never record. If the production +domain ever changes, update the gate or Clarity silently stops collecting. + ### API layer (`src/api/`) - `axiosClient` auto-attaches the logged-in user's `db_name` as the `dbName` query param on every request (multi-tenancy), rewrites `/api/audit` → `VITE_AUDIT_API_URL`, and coalesces concurrent JWT refreshes (rotation-safe). Services (`activityFeedsService`, `adminService`) return the response body directly, not the axios envelope. +### Filter lock-step rule (learned via chainage/sort, applies to every new filter) +Any feed filter (chainage, assets, the frequency threshold `filterFrequencyGt` — a free numeric "Frequency > N" input, digits-only sanitized, backed by the pipeline's occurrence marker on audits/rectification, NOT anomaly.frequency; the session metadata row shows a FREQUENCY chip, hidden when the field is absent on stale cached rows; `filterHasCompleteImage` — the Complete Image Any/Present/Absent select (`hasCompleteImage` param, whitelisted server-side); and `filterAuditValues` — the Features multi-select over the fixed audit-option vocabulary exported from AuditSession (ANOMALY/SAFE/RECT_SAFE_CATEGORIES + rect-true 'Others'), matched case-insensitively server-side, options follow the audits/rectification toggle; NOTE it matches nothing on un-audited pending rows — Audit_value is NULL there — so it's effectively a history/date-tab + AI-audit filter) must flow to ALL of: FeedFilters (draft + seed + clear + apply + its filterKey), GlobalFeed (destructure + the IDENTICAL filterKey + every getHistory call + effect deps), AuditSession (both session page-load calls + both deps arrays), and Dashboard (currentFilterKey + its getHistory call) — plus the backend's page AND count queries in `anomalyModel` (they must never drift or pagination breaks). The two filterKey templates in FeedFilters and GlobalFeed must stay character-identical or the cache guard double-fetches. + ### Feed store cache is a write-through cache — keep it in sync `useFeedStore` caches each tab's rows (`anomalies` + `anomaliesCopy`) and the audit session is (re-)entered FROM that cache (`location.state.anomalies` passed by the feeds table, or `activeTab.anomalies`). Any mutation a session makes to a record must therefore be written to BOTH the session's local `anomalies` state AND the feed store tabs, or the change "disappears" on re-entry while the DB is actually fine. Existing write-throughs to mirror: `applyAuditedLocally`/`purgePendingCaches` (audit save), `handleSaveAnnotations` (bounding boxes — this one was learned the hard way). Match tabs per mode via `tabMatchesMode` in AuditSession — NOT `!!t.isRectificationTab === isRectActive` alone: the pending/review tabs are created with `isRectificationTab: false` even in rectification mode (their content follows the global `isRectificationEnabled` toggle), so the naive flag comparison silently skips them in rect mode while working in audits mode. Audits and rectification ids come from different tables and can collide, so a mode check is still mandatory. @@ -26,6 +35,7 @@ root [CLAUDE.md](../CLAUDE.md); backend contracts in [auditor-backend/CLAUDE.md] - **Save guards**: `submittingRef` blocks overlapping saves; `lastActionIdRef` blocks back-to-back saves of the SAME record id (Enter + click both firing). **Any flow that makes a locked record editable again (revert!) must clear both refs** or the next save is silently swallowed until the user navigates away and back. - **Keyboard shortcuts** (`handleKeyDown`) fire on single letters/digits (S = Safe, A = Anomaly, …). They are paused by an explicit list of open-dialog states AND a generic guard (target is INPUT/TEXTAREA/contentEditable). Every new dialog with a text field must keep at least one of those true — the generic guard covers it, but add the dialog's open-state to the list (and to the "Shortcuts Paused" footer indicator) for visibility. ⚠️ The listener is registered in **CAPTURE phase** — required by the video Space/F branch, which must `stopPropagation()` before the focused `