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
tabsarray —History(BookOpen),Sessions(Calendar),New Entry(Plus),Equipment(Telescope),Conditions(Cloud),Statistics(BarChart3) - Per-tab content:
history— chronological list of past observationssessions— session-grouped viewnew— form to log a new observationequipment— equipment profiles usedconditions— captured sky conditionsstats— 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"]viauseNyxStore; event-detail handoffs retaineventIdon 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#
Header#
- "Back" button (icon,
ArrowLeft) —onBack→router.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 fixtureOBSERVATION_LOGSand do not add/edit telescope-control profiles. - Telescope boundary — a profile created in
/domains/nyx/telescoperemains in that component'sequipmentProfilesstate 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-onlyOBSERVATION_EQUIPMENTprofile 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#
- Deep / detailed variant:
domains-nyx-observation-log-deep.md - Domain hub:
nyx.md— sub-nav includes "Observations" - Sibling tools:
domains-nyx-telescope.md,domains-nyx-catalogs.md - Component source:
apps/oshun/web/src/components/domains/nyx/NyxObservationLog.tsx
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-logand/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
NyxTelescopeControlequipment tab — they are not shared.NyxObservationLogreadsOBSERVATION_EQUIPMENTfromnyx-extended-simulation, whileNyxTelescopeControlownsINITIAL_EQUIPMENT_PROFILESand user-added profiles in local component state.