Explorer: event JSON export (#142) #175

Merged
claude-bot merged 1 commit from feat/event-export into main 2026-08-01 06:02:51 +00:00
Contributor

Closes #142. Stacked on the radar loops (#140/PR #173, merged). Decisions recorded on the issue: JSON-only, authenticated-only (a full export would undo the public pages' deliberate coarsening), media as auth-gated URL references.

What this adds

GET /explorer/event/{event_id}/export.json + an "Export JSON" button on the event page. Content-Disposition attachment named weatherbot-event-{id}-{local-date}.json.

The document (schema_version: 1, generated_at, app_version) carries everything the event page reconstructs: event + location metadata (including archived), members with roles/intervals, the full timeline including complete official product text with per-entry text_captured flags, the delivery record including failures with last_error, AI summaries with source ids, and radar as relative auth-gated URLs (loop + stills + frames) with a note that they require a session.

The design constraint that matters: the export is event_detail()'s output — the same service call the HTML page renders — passed through a pure serializer (explorer_export.py). No parallel queries, so page and export cannot drift; the dataclasses gained a few raw fields (UTC datetimes, member details) that the page never displayed but the underlying queries already fetched. Auth and non-leaking-404 semantics mirror the event page exactly, tested by live comparison rather than hardcoded status codes.

Verification

Full bulk suite on the dev server: 975 passed (9 new export tests: schema/fields, full text + text_captured, failed-delivery row, AI summaries present/absent, radar URLs per loop availability, filename shape, archived export, 404s, unauthenticated behavior matching the page). ruff clean. No migrations, no new JS.

One unrelated observation while verifying: test_cloud_provider_prompt_filters_disallowed_metadata flaked in a single full-suite ordering and passed on isolation + rerun — pre-existing order-dependence, filed as #174 for the #141 test-infrastructure pass.

🤖 Generated with Claude Code

Closes #142. Stacked on the radar loops (#140/PR #173, merged). Decisions recorded on the issue: JSON-only, authenticated-only (a full export would undo the public pages' deliberate coarsening), media as auth-gated URL references. ## What this adds `GET /explorer/event/{event_id}/export.json` + an "Export JSON" button on the event page. `Content-Disposition` attachment named `weatherbot-event-{id}-{local-date}.json`. The document (`schema_version: 1`, `generated_at`, `app_version`) carries everything the event page reconstructs: event + location metadata (including `archived`), members with roles/intervals, the full timeline **including complete official product text** with per-entry `text_captured` flags, the delivery record including failures with `last_error`, AI summaries with source ids, and radar as relative auth-gated URLs (loop + stills + frames) with a note that they require a session. **The design constraint that matters**: the export is `event_detail()`'s output — the same service call the HTML page renders — passed through a pure serializer (`explorer_export.py`). No parallel queries, so page and export cannot drift; the dataclasses gained a few raw fields (UTC datetimes, member details) that the page never displayed but the underlying queries already fetched. Auth and non-leaking-404 semantics mirror the event page exactly, tested by live comparison rather than hardcoded status codes. ## Verification Full bulk suite on the dev server: **975 passed** (9 new export tests: schema/fields, full text + `text_captured`, failed-delivery row, AI summaries present/absent, radar URLs per loop availability, filename shape, archived export, 404s, unauthenticated behavior matching the page). `ruff` clean. No migrations, no new JS. One unrelated observation while verifying: `test_cloud_provider_prompt_filters_disallowed_metadata` flaked in a single full-suite ordering and passed on isolation + rerun — pre-existing order-dependence, filed as #174 for the #141 test-infrastructure pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Add Explorer event JSON export (#142)
All checks were successful
CI / test (pull_request) Successful in 3m34s
c806caab21
GET /explorer/event/{event_id}/export.json serializes the same EventDetail
tree the event-detail page already assembles (app.services.explorer.
event_detail) into a downloadable JSON document -- no parallel queries.
EventDetail gains a few raw fields the HTML page never rendered (UTC
timestamps, location_timezone, per-member kind/role/interval) so the new
app/services/explorer_export.py serializer has everything it needs without
re-querying. Same auth and non-leaking 404 semantics as the event page,
authenticated-only per the issue's recorded decision (no public variant).
Adds an "Export JSON" link to the event page header and tests/test_event_export.py.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/WeatherBot!175
No description provided.