Context. surface customer · domain nyx · route /domains/nyx/telescope · auth signed-in · source apps/oshun/web/src/app/domains/nyx/telescope/page.tsx
Last walked. - 2026-07-02 equipment-boundary addendum — Playwright now opens the Telescope Control Equipment tab, verifies seeded telescope-only profiles, creates a new profile through the Add Profile flow, and proves that profile does not leak into /domains/nyx/observation-log equipment fixtures. 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
Purpose#
Telescope-control surface for hardware integration (ASCOM / Alpaca) — connection
profile, current scope status, GoTo target selection, tracking / guiding
configuration, and equipment library. Wired via
apps/oshun/web/src/app/domains/nyx/telescope/page.tsx ('use client') which
mounts <NyxTelescopeControl onClose={() => router.back()} />.
Entry points#
- Direct URL / bookmark — yes (signed-in)
- In-app navigation — verify Nyx hub link, and any "Slew to here" link from catalog or star-chart popups
- Browser back affordance — in-component back button calls
router.back()
Layout regions#
NyxTelescopeControl
(apps/oshun/web/src/components/domains/nyx/NyxTelescopeControl.tsx):
- Header: back button (
aria-label="Back"),Telescopeicon, title<h1>Telescope Control</h1>, connection-status badge (status text + pulsing indicator whenconnecting) - Tab bar (
TABS): five tabs —Connection,Status,GoTo,Tracking,Equipment - Per-tab content:
connection— protocol (ASCOM), host (localhost), port (11111), device name (Telescope Simulator) inputs; Connect / Disconnect actionsstatus— current state: tracking mode, isTracking, isSlewing, isParked, current RA / Dec / altitude / azimuth, sidereal time, pier side, guide rates, settling timegoto— RA H/M/S + Dec D/M/S inputs (defaults05:35:17 / -05:23:28), search box with object suggestions filtered fromCOMMON_OBJECTStracking— slew speed slider, pulse RA / pulse Dec duration inputsequipment— equipment profile list (defaulteq-sct-11), eyepiece selector (25mm), computed magnification + true FOV; "Add profile" flow
States#
- Loading — bundled fixture; client-only
- Disconnected — initial state; status badge "disconnected"
- Connecting — status "connecting" with pulsing indicator
- Connected — status "connected"; telescope state controls become usable
- Connection failed — verify error state copy and recovery
- GoTo search empty — no suggestions visible
- GoTo search with results —
filteredObjectspopulated fromCOMMON_OBJECTSfilter - Slewing — verify visual indication when
isSlewing - Parked — verify visual indication when
isParked - Add profile open —
showAddProfiletrue; new-profile name input appears after clicking "Add Profile" - Offline — bundle is local; an actual ASCOM connection requires LAN reachability
Interactions#
Header#
- "Back" button (icon,
ArrowLeft) —onClose→router.back()
Tab bar (five tabs)#
- Connection tab — sets
activeTab='connection' - Status tab — sets
activeTab='status' - GoTo tab — sets
activeTab='goto' - Tracking tab — sets
activeTab='tracking' - Equipment tab — sets
activeTab='equipment'
Connection tab#
- Protocol selector — verify exact options (ASCOM is the default)
- Host input
- Port input
- Device name input
- Connect button — calls
handleConnect→ sets status toconnecting - Disconnect button — verify
Status tab#
- Tracking mode selector — values include
sidereal - Pier side indicator — read-only
- Guide rate fields — RA / Dec rates
GoTo tab#
- RA H / M / S inputs — three numeric fields
- Dec D / M / S inputs — three numeric fields (allows negative degrees)
- Search input —
gotoSearch; opens suggestion list withshowObjectSuggestions - Object suggestion item (button) — selects target
Tracking tab#
- Slew speed slider (
slewSpeed) - Pulse RA duration input
- Pulse Dec duration input
Equipment tab#
- Equipment profile card (each in
equipmentProfiles) — selecting setsactiveProfileId - Eyepiece selector — sets
selectedEyepiece - Magnification readout —
Math.round(focalLengthMm / selectedEyepiece) - True FOV readout —
52 / magnification - "Add profile" button — toggles
showAddProfile - New profile name input —
newProfileName - Save profile button — "Add" appends a profile to the in-component
equipmentProfilesarray for this mounted telescope-control session
Data & contracts#
- Reads:
INITIAL_EQUIPMENT_PROFILES+COMMON_OBJECTSbundled inside the component - Writes: telescope state held in component (no real network in code; ASCOM
connection is mocked locally per the connection handlers). Added equipment
profiles are component-local and are not shared with
/domains/nyx/observation-log. - Realtime: none in code
- Caching: static client bundle
- Auth/role check: middleware enforces signed-in for
/domains/*
Cross-references#
- Domain hub:
nyx.md - Sibling tools:
domains-nyx-catalogs.md(catalog GoTo handoff),domains-nyx-coordinates.md,domains-nyx-observation-log.md - Component source:
apps/oshun/web/src/components/domains/nyx/NyxTelescopeControl.tsx
Automated coverage#
apps/oshun/web/e2e/nyx-tonight-observation.spec.ts— opens Equipment, verifies the seeded telescope profiles, creates a browser-visible profile via Add Profile, and proves the profile remains separate from the Observation Log equipment fixture list.
Open questions / known gaps#
- Confirm whether the ASCOM / Alpaca client actually reaches a local server or is fully mocked
- Document the catalog → telescope GoTo handoff (no entry-point query param
is consumed by
page.tsx) - Confirm whether
Add to telescope GoTois an action surfaced on catalog or star-chart popups - Verify keyboard semantics on RA / Dec multi-field inputs (single tab stop vs six)