V1 Web PWA · Surface walkthrough

Nyx · Observation Log — session list

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

walked
9sections4 minread

On this page

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

Last walked. - 2026-07-02 equipment-boundary addendum — Playwright now opens the Observation Log Equipment tab, verifies the four OBSERVATION_EQUIPMENT fixture profiles, creates a telescope-only profile on /domains/nyx/telescope, and returns to prove the observation-log equipment list is not shared with telescope-control component state. Spec: apps/oshun/web/e2e/nyx-tonight-observation.spec.ts. - '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 recording surface (P3, 2026-05-25). This route is the CRUD/management entry for the observing journal. The H1 was disambiguated from the sister analytics surface (domains-nyx-observation-log-deep.md) which previously also rendered "Observation Log" as its H1. Both surfaces now carry mutually-linking subtitle copy.

Purpose#

Personal sky-observation log — history of sessions, equipment used, conditions captured, with statistics and a new-entry composer. Wired via apps/oshun/web/src/app/domains/nyx/observation-log/page.tsx ('use client') which mounts <NyxObservationLog eventId={searchParams.get('eventId')} onBack={() => router.back()} />. When the route includes ?eventId=..., the New Entry form carries that context into the saved observation.

Entry points#

  • Direct URL / bookmark — yes (signed-in)
  • In-app navigation — Nyx hub "Observations" sub-nav and event-detail "Log observation" shortcut
  • Browser back affordance — in-component back button calls router.back()

Layout regions#

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

  • Header: back button (aria-label="Back"), <h1>Observation Log · session list</h1> (1.125rem, NyxObservationLog.tsx ~1318)
  • Stats strip — computed via computeSessionStats() (verify which KPIs surface)
  • Tab bar: six tabs from local tabs array — History (BookOpen), Sessions (Calendar), New Entry (Plus), Equipment (Telescope), Conditions (Cloud), Statistics (BarChart3)
  • Per-tab content:
    • history — chronological list of past observations
    • sessions — session-grouped view
    • new — form to log a new observation
    • equipment — equipment profiles used
    • conditions — captured sky conditions
    • stats — aggregate metrics

States#

  • Loading — bundled fixture data; client-only
  • History populated — entries visible
  • History empty — verify empty-state copy
  • New Entry — empty form — defaults set
  • New Entry — submitted — entry appears in History and persists to localStorage["oshun.nyx"] via useNyxStore; event-detail handoffs retain eventId on the saved row
  • Statistics — aggregate counts and charts render
  • Equipment fixture profiles — the Equipment tab renders OBSERVATION_EQUIPMENT (8" Dobsonian, 10x50 Binoculars, 4" Refractor, Naked Eye). These are read-only observation-log profiles, not the editable telescope-control profile state.
  • Offline — static bundle; works offline

Interactions#

  • "Back" button (icon, ArrowLeft) — onBackrouter.back()

Tab bar (six tabs)#

  • History tab — sets tab='history'
  • Sessions tab — sets tab='sessions'
  • New Entry tab — sets tab='new'
  • Equipment tab — sets tab='equipment'
  • Conditions tab — sets tab='conditions'
  • Statistics tab — sets tab='stats'

History tab#

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

New Entry tab#

  • Form fields — verify which fields exist (target, time, equipment, conditions, notes)
  • Submit — writes a normalized observation to useNyxStore, closes the form, and returns to the History tab
  • Cancel / Reset — verify whether such a control exists

Equipment tab#

  • Equipment profile cards — read-only cards derived from OBSERVATION_EQUIPMENT; they show usage counts from fixture OBSERVATION_LOGS and do not add/edit telescope-control profiles.
  • Telescope boundary — a profile created in /domains/nyx/telescope remains in that component's equipmentProfiles state only and does not appear in the observation-log equipment list.

Conditions tab#

  • Conditions captured per session — verify display format

Statistics tab#

  • Each KPI tile — number + label

Data & contracts#

  • Reads: bundled fixture observations, persisted local entries from useNyxStore, owner-scoped BFF rows from /v1/nyx/observations, and read-only OBSERVATION_EQUIPMENT profile fixtures for the Equipment tab
  • Writes: new observation entries are persisted local-first to localStorage["oshun.nyx"] and mirrored to /v1/nyx/observations; clearing local Nyx storage and reopening the log reloads synced rows from the BFF. Equipment profiles are not written by this surface.
  • Realtime: none
  • Caching: static client bundle
  • Auth/role check: middleware enforces signed-in for /domains/*

Cross-references#

Automated coverage#

  • apps/oshun/web/e2e/nyx-tonight-observation.spec.ts — event-detail handoff into New Entry, BFF POST/GET and local-cleared reload, Home KPI read-back, tab bar/heading, and the Observation Log Equipment tab versus Telescope Control equipment-profile boundary.
  • apps/oshun/web/e2e/nyx-observations-bff.spec.ts — field-log BFF auth, validation, no-store, defaulting, owner isolation, and durable read-back.

Open questions / known gaps#

  • Document the relationship between /observation-log and /observation-log-deep — why two surfaces; which is canonical for the Nyx sub-nav
  • Confirm whether new entries persist across reloads — local persistence verified 2026-06-23; BFF write/read-back after local storage clear verified 2026-06-24
  • Verify whether equipment profiles are shared with NyxTelescopeControl equipment tab — they are not shared. NyxObservationLog reads OBSERVATION_EQUIPMENT from nyx-extended-simulation, while NyxTelescopeControl owns INITIAL_EQUIPMENT_PROFILES and user-added profiles in local component state.