---
path: /domains/nyx/observation-log-deep
surface: customer
domain: nyx
auth: signed-in
source: apps/oshun/web/src/app/domains/nyx/observation-log-deep/page.tsx
status: walked
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'
---

# Nyx · Observation Log — analytic views

> **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`](./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_MODES` — `Observations` (`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 mode** — `list` (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

### Header

- [ ] **"Go back" button** (icon, `ArrowLeft`) — `onClose` → `router.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

- Lighter variant:
  [`domains-nyx-observation-log.md`](./domains-nyx-observation-log.md)
- Domain hub: [`nyx.md`](./nyx.md)
- Sibling tools: [`domains-nyx-telescope.md`](./domains-nyx-telescope.md),
  [`domains-nyx-sky-conditions.md`](./domains-nyx-sky-conditions.md)
- Component source:
  `apps/oshun/web/src/components/domains/nyx/NyxObservationLogDeep.tsx`

## 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
