V1 Web PWA · Surface walkthrough

Nyx · Observation Log — analytic views

A per-surface walkthrough of the V1 Web PWA customer surface: layout, states, interactions, data, and cross-references.

walked
8sections3 minread

On this page

Context. surface customer · domain nyx · route /domains/nyx/observation-log-deep · auth signed-in · source apps/oshun/web/src/app/domains/nyx/observation-log-deep/page.tsx

Last walked. 2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data (2xx), console/page-errors, expected content, screenshot verified; live screen-reader, touch, offline, and telemetry-delivery checks pending a manual AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md; content re-verified 2026-06-03 against current source

Canonical analytics surface (P3, 2026-05-25). This route is the read-side analytic complement to the session-list / CRUD surface at domains-nyx-observation-log.md. Five view modes (list, calendar, statistics, locations map, equipment) over the same observing journal — but recording / editing of entries happens on the sibling surface. The H1 was disambiguated in the same pass; both surfaces now carry mutually-linking subtitle copy.

Purpose#

Analytic complement to the session-list observation log — five view modes (list, calendar, statistics, locations map, equipment) plus filters. Wired via apps/oshun/web/src/app/domains/nyx/observation-log-deep/page.tsx ('use client') which mounts <NyxObservationLogDeep onClose={() => router.back()} />.

Entry points#

  • Direct URL / bookmark — yes (signed-in)
  • In-app navigation — verify whether /observation-log links to the "deep" variant, or whether this is reachable independently
  • Browser back affordance — in-component back button calls router.back()

Layout regions#

NyxObservationLogDeep (apps/oshun/web/src/components/domains/nyx/NyxObservationLogDeep.tsx):

  • Header: back button (aria-label="Go back"), <h1>Observation Log · analytic views</h1> (NyxObservationLogDeep.tsx ~1471) — disambiguated from the session-list variant's "Observation Log · session list"
  • Filter button bar — verify exact filters; one button with styles.filterBtn(false) visible near the header
  • View-mode switcher: five modes from VIEW_MODESObservations (list, List icon), Calendar (calendar, Calendar icon), Statistics (stats, BarChart3 icon), Locations (map, MapIcon), Equipment (equipment, Telescope icon)
  • Per-mode content:
    • list — chronological list with deeper detail
    • calendar — calendar grid of observations
    • stats — analytics dashboard
    • map — location-mapped observations
    • equipment — equipment-grouped observations

States#

  • Loading — bundled fixture; client-only
  • Default modelist (verify initial viewMode)
  • List populated — entries visible
  • List empty — verify empty-state copy
  • Calendar populated — observations rendered on grid days
  • Statistics — analytics render
  • Locations map — verify map provider (Leaflet / Mapbox / SVG)
  • Equipment grouped — entries grouped by gear profile
  • Filter applied — verify each filter narrows the visible set
  • Offline — static bundle; works offline (map tiles may fail)

Interactions#

  • "Go back" button (icon, ArrowLeft) — onCloserouter.back()
  • Filter button (styles.filterBtn(false)) — verify the exact filter affordance

View-mode switcher (five modes)#

  • Observations — sets viewMode='list'
  • Calendar — sets viewMode='calendar'
  • Statistics — sets viewMode='stats'
  • Locations — sets viewMode='map'
  • Equipment — sets viewMode='equipment'

List view#

  • Each observation row — verify whether interactive (detail / edit) or read-only

Calendar view#

  • Day cell — verify whether tapping a day filters to that day

Locations view#

  • Map provider — verify (Leaflet / Mapbox / inline SVG)
  • Marker tap — verify behaviour

Equipment view#

  • Equipment group header — verify whether expandable

Data & contracts#

  • Reads: bundled fixture observations inside the component
  • Writes: verify whether the deep variant adds / edits entries
  • Realtime: none
  • Caching: static client bundle (map tiles, if any, require network)
  • Auth/role check: middleware enforces signed-in for /domains/*

Cross-references#

Open questions / known gaps#

  • Why two observation-log routes — clarify which is the canonical V1 surface and where the other links from
  • Document the Locations map provider and offline behaviour for the map view
  • Confirm whether observations sync between this view and /observation-log or whether they are separate fixtures