frontend: search, filters and load-more on Incidents; open Archive to viewers
Incidents page: text search (title, location, summary, units, vehicles, tags, location mentions), status and type filters, and a Load more button that pages the Firestore query 100 at a time. Filtering runs over the loaded window, and the page says so when older incidents exist. Archive (/calls): readable by every org member, not just admins. GET /calls/search now takes any Firebase token scoped to the caller's org — the Firestore rules already let members read every call in their org, so this widens nothing. Attach/detach stays admin-only (UI and routes). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5f85a878fa
commit
fa194e0f0a
@@ -5,6 +5,7 @@ from typing import Optional
|
||||
from app.internal import firestore as fstore
|
||||
from app.internal.auth import (
|
||||
require_admin_token,
|
||||
require_firebase_token,
|
||||
require_service_or_firebase_token,
|
||||
resolve_caller_org_id,
|
||||
reprocess_limiter,
|
||||
@@ -54,7 +55,7 @@ async def search_calls(
|
||||
link: str = Query("any", pattern="^(any|orphan|linked)$"),
|
||||
transcript: str = Query("any", pattern="^(any|yes|no)$"),
|
||||
q: Optional[str] = Query(None, description="case-insensitive substring of the transcript"),
|
||||
decoded: dict = Depends(require_admin_token),
|
||||
decoded: dict = Depends(require_firebase_token),
|
||||
):
|
||||
"""
|
||||
Paged, filterable call archive — the backend for the /calls page.
|
||||
@@ -72,6 +73,11 @@ async def search_calls(
|
||||
|
||||
`window_exhausted` says the scan hit its cap before filling the page, so an
|
||||
empty result means "not in this window", not "none exist".
|
||||
|
||||
Open to every org member (viewer included), not just admins: the Firestore
|
||||
rules already let any member read every call doc in their org
|
||||
(firestore.rules `calls` → docInMyOrg), so this route exposes nothing a
|
||||
viewer's browser couldn't already read directly.
|
||||
"""
|
||||
org_id = await resolve_caller_org_id(decoded)
|
||||
if org_id is None:
|
||||
|
||||
Reference in New Issue
Block a user