Domain · Specifications

Nyx Domain — Technical Specifications

The table below lists the key technology choice at each architectural layer.

13sections22 minread

On this page

Technical specification for the Nyx cosmic-observatory platform: astronomical type system, REST and WebSocket APIs, database schema, data pipelines, the library and application surface, and configuration. Every entity, enum, endpoint, and table below is traceable to source in libs/nyx/* and apps/nyx/*.


This document is the authoritative technical reference for engineers working on or integrating with the Nyx domain. It covers the exact TypeScript types, REST endpoints, WebSocket message protocol, database schema, and environment configuration — the level of detail needed to implement a new feature, add a migration, or write client code against the API.

The sections follow a natural dependency order: the technology stack and algorithm standards first (since everything else builds on them), then the type system, then the API surface, then persistence, then the pipeline workers, and finally the full library and application inventories.


Technology Stack#

The table below lists the key technology choice at each architectural layer. Understanding this stack is essential before reading the sections that follow, since the API, schema, and validation patterns all flow directly from these choices.

Layer Technology
REST API framework Hono + @hono/zod-openapi (OpenAPIHono), @hono/swagger-ui
HTTP runtime @hono/node-server
Real-time WebSocket (ws library), custom Nyx WS server + update scheduler
Database PostgreSQL, accessed via pg; schema as Zod models in @nyx/database
Migrations Knex migrations (@nyx/database migrations/)
Cache / rate limit Redis (ioredis) for API rate-limit windows; in-process fallback
Pipeline runtime Node.js workers (pino logging, prom-client metrics, undici)
Ephemeris kernel astronomy-engine plus in-domain Meeus/VSOP-style implementations
Web clients Vite + React + Three.js (@react-three/fiber, drei, xr)
Validation Zod (catalog version) throughout
Testing Vitest

Note: the API uses raw pg, not Drizzle. @nyx/database defines schema as Zod object schemas and ships Knex migration files; there is no Drizzle ORM layer.


Astronomical Algorithm Standards#

The computation libraries in Nyx implement classical positional-astronomy algorithms throughout, rather than delegating all calculation to an external dependency. This is a deliberate choice: it makes the algorithms independently testable against known-correct reference values and keeps the domain's accuracy guarantees under its own control.

Ephemeris, coordinate, and event code implements Meeus-style analytic series, Besselian-element eclipse prediction, SGP4 TLE propagation, and Kepler-equation solvers. The domain additionally depends on the astronomy-engine package for high-precision solar-system positions where the Meeus approximations reach their accuracy limits. Coordinate types carry their reference frame and epoch explicitly so equatorial, horizontal, galactic, and ecliptic frames cannot be silently mixed.


Core Type System (@nyx/types)#

@nyx/types is the shared TypeScript type library that every other @nyx/* package imports from. It exports six modules — coordinates, celestial, time, observer, orbital, visualization — re-exported from src/index.ts. All types below are exact as they appear in source.

Coordinate Types (coordinates.ts)#

The coordinate types encode all the information needed to identify a location in the sky unambiguously — including the reference frame and epoch, which are frequently omitted by naive implementations and lead to subtle cross-library bugs.

Angular unit aliases (all number): Degrees, Radians, Arcminutes, Arcseconds, Hours, Milliarcseconds.

Sexagesimal representations encode angles in base-60 notation as astronomers traditionally record them:

  • SexagesimalAngledegrees, minutes, seconds, sign (1 | -1)
  • HMSAnglehours, minutes, seconds
  • DMSAngledegrees, arcminutes, arcseconds, sign (1 | -1)

CoordinateFrame union: ICRS | J2000 | B1950 | GALACTIC | ECLIPTIC | HORIZONTAL | SUPERGALACTIC.

Epoch union: 'J2000.0' | 'B1950.0' | 'J2050.0' | number.

Coordinate interfaces:

  • EquatorialCoordinatesra (Degrees, 0–360), dec (Degrees, −90..+90), optional frame, optional epoch
  • AstrometricCoordinates extends EquatorialCoordinates — adds pmRA, pmDec (mas/yr), parallax (mas), radialVelocity (km/s), observationEpoch (Julian year)
  • HorizontalCoordinatesaltitude, azimuth (Degrees)
  • ApparentHorizontalCoordinates extends it — trueAltitude, refraction (Arcminutes), airMass
  • GalacticCoordinatesl, b; SupergalacticCoordinatessgl, sgb
  • EclipticCoordinateslambda, beta, optional epoch
  • CartesianPositionx, y, z, unit: DistanceUnit
  • CartesianVelocityvx, vy, vz, unit: VelocityUnit
  • StateVectorposition, velocity, frame, epoch

Unit unions: DistanceUnit = km | AU | pc | kpc | Mpc | ly | m; VelocityUnit = km/s | AU/day | m/s | c.

Derived geometry: AngularSeparation (degrees/arcminutes/arcseconds), PositionAngle (degrees + from/to), FieldOfView (rectangular), CircularFieldOfView, GreatCircleArc, SphericalTriangle.

Transformation records: CoordinateTransformResult<T> and CoordinateCorrection whose type is one of precession | nutation | aberration | parallax | proper_motion | refraction | light_time.

Celestial Object Types (celestial.ts)#

The celestial object types form a discriminated union that covers every class of object in the domain's catalogs. Code that works generically on any catalog query result uses CelestialObject; code that knows it is handling, say, an exoplanet uses Exoplanet directly.

CelestialObjectType union (18 values): star, double_star, variable_star, planet, dwarf_planet, moon, asteroid, comet, galaxy, nebula, cluster, quasar, pulsar, black_hole, supernova_remnant, satellite, meteor_shower, unknown.

CelestialObjectBaseid, type, coordinates (EquatorialCoordinates), catalogs (CatalogIdentifiers), optional magnitudes, optional updatedAt.

Magnitudes — optional photometric bands: apparent, absolute, B, V, R, I, J, H, K, U, G.

ColorIndicesBV, UB, VR, VI, JH, HK, BPRP.

CatalogIdentifiers — cross-reference IDs: hip, tyc, gaia, hd, hr, sao, flamsteed, bayer, name, variable, ngc, ic, messier, simbad, twoMass.

StarsSpectralClassification (class is one of O B A F G K M L T Y W C S; optional subclass, luminosityClass of Ia Ib II III IV V VI VII, peculiarities); StellarProperties (temperature, luminosity, mass, radius, surfaceGravity, metallicity, age, rotationPeriod); Star extends CelestialObjectBase with astrometry, spectralType, properties, colorIndices, distance, constellation.

Double starsDoubleStar (primary: Star, companions: StarCompanion[], separation, positionAngle, orbitalPeriod, isPhysical); StarCompanion (designation, magnitude, spectralType, separation, positionAngle).

Variable starsVariableStarType = ECLIPSING | PULSATING | ERUPTIVE | ROTATING | X-RAY | OTHER; VariableStarClass = EA EB EW CEP DCEP RR DSCT MIRA SR NOVA SN FLARE GCAS MISC; VariableStar with variableType, variableClass, maxMagnitude, minMagnitude, period, epochMax, spectralType, gcvsName.

Solar-system bodiesSolarSystemBodyType = planet | dwarf_planet | moon | asteroid | comet; SolarSystemBodyProperties (mass, radius, density, surfaceGravity, escapeVelocity, rotationPeriod, axialTilt, albedo, surfaceTemperature, atmosphere); AtmosphericComposition (compound/percentage); Planet, Moon, Asteroid (taxonomicClass, isPHA, orbitFamily), Comet (cometType = periodic | non_periodic | great | sungrazer), DiscoveryInfo.

ExoplanetsExoplanetDetectionMethod = transit | radial_velocity | direct_imaging | microlensing | astrometry | timing | disk_kinematics; Exoplanet (typed as type: 'planet') with hostStar, detectionMethod, mass, massIsMinimum, radius, orbitalPeriod, semiMajorAxis, eccentricity, equilibriumTemp, inHabitableZone, distance.

Deep-sky objectsDeepSkyObjectType = galaxy | nebula | cluster | quasar | pulsar | black_hole | supernova_remnant; GalaxyMorphology (Hubble sequence: E0–E7, S0, Sa–Sd, SBa–SBd, Irr, cD, BCD, dE, dSph); Galaxy, NebulaType (emission | reflection | dark | planetary | supernova_remnant | protoplanetary), Nebula, ClusterType (open | globular | association | moving_group), StarCluster.

SearchCelestialSearchParams (types, magnitude limits, cone-search center/radius, catalogId, namePattern, constellation, limit, offset); CelestialSearchResult<T> (objects, totalCount, queryTimeMs). The discriminated union CelestialObject covers Star, DoubleStar, VariableStar, Planet, Moon, Asteroid, Comet, Exoplanet, Galaxy, Nebula, StarCluster.

Time Types (time.ts)#

These types cover every time representation used in astronomical computation. Astronomical code uses multiple incompatible time scales, and making them distinct types prevents mixing them accidentally.

Exports JulianDate, ModifiedJulianDate, JulianDayNumber, JulianDateSpec, TimeScale, TimeScaleConversion, sidereal-time types (SiderealHours, SiderealDegrees, GreenwichSiderealTime, LocalSiderealTime), epochs (StandardEpoch, BesselianYear, JulianYear, EpochSpec), calendar types (GregorianDate, JulianCalendarDate, DateRange), DeltaT/DeltaTSource, LeapSecond, TimeInterval/TimeUnit, TimeConstants, phenomena types (RiseTransitSetTimes, TwilightTimes, MoonPhase, LunarPhaseInfo), TimeZoneInfo, and formatting types.

Observer Types (observer.ts)#

Observer types describe the physical context of a human observing session — location, equipment, atmospheric conditions, and the session record itself.

Exports GeographicCoordinates, ObserverLocation, Observer, AtmosphericConditions, ObserverEquipment, horizon types (HorizonProfile, HorizonPoint, HorizonCheckResult), site types (ObservingSite, TelescopeInfo, TelescopeType, MountType), visibility types (VisibilityAssessment, VisibilityFactor, SeasonalVisibility), weather types (ObservingForecast, HourlyForecast, SkyBrightness), and session types (ObservationSession, SessionTarget).

Orbital Types (orbital.ts)#

Orbital types represent everything needed to describe and propagate an orbit: element sets, state vectors, perturbation models, and the events that occur at specific orbital configurations.

  • KeplerianElementsa, e, i, node (Ω), peri (ω), M, epoch, optional frame (ecliptic | equatorial)
  • ExtendedOrbitalElements — adds longPeri, meanLong, q, Q, period, n, trueAnomaly, eccentricAnomaly, T
  • TwoLineElement / TLELine1 / TLELine2 — full parsed TLE structure (classification = U | C | S, BSTAR drag, mean motion, RAAN, etc.)
  • EphemerisPoint, EphemerisTable, EphemerisRequeststepUnit is days | hours | minutes; frame is heliocentric | geocentric | topocentric; aberration is none | apparent | astrometric
  • Perturbation / PerturbationType (gravitational | oblateness | solar_radiation | atmospheric_drag | relativistic | tidal); ElementType = osculating | mean
  • OrbitalEventType = perihelion | aphelion | ascending_node | descending_node | opposition | conjunction | greatest_elongation | quadrature | stationary_point | eclipse | transit | occultation; OrbitalEvent, Conjunction, Opposition
  • EclipseType = total_solar | partial_solar | annular_solar | hybrid_solar | total_lunar | partial_lunar | penumbral_lunar; Eclipse (Besselian-style fields: contacts C1–C4, gamma, sarosNumber, pathCoordinates)
  • PlanetaryTransit, ExoplanetTransit, SatellitePass, SatelliteFlare
  • OrbitDeterminationInput, OrbitDeterminationResult (orbitType = elliptic | parabolic | hyperbolic)

Visualization Types (visualization.ts)#

Visualization types describe everything needed to configure and render a sky chart — from the projection algorithm to individual renderable objects and their display symbols.

Exports projection/grid types (Projection, GridType), chart configuration (SkyChartConfig, SkyChartDisplayOptions, SkyChartColors), renderable objects (RenderableObject, RenderableStar, RenderableDeepSkyObject, DSOSymbol, RenderablePlanet), constellation render types (RenderableConstellation, ConstellationLine, ConstellationBoundary), interactivity types, animation types, 3D-scene types (Scene3DConfig, Camera3D, Lighting3D, Background3D, Scale3D), export types, and accessibility types.


REST API (apps/nyx/api)#

The API is an OpenAPIHono application. apps/nyx/api/src/index.ts boots an HTTP server (@hono/node-server) and attaches the WebSocket server on the same port. The static OpenAPI document is loaded from libs/openapi/docs/nyx/openapi.yaml (validated as OpenAPI 3.1.0, title Nyx Astronomy API).

Middleware Chain#

The middleware chain is defined in app.ts and runs in this fixed order for every request. Understanding the order matters when adding new middleware, because earlier middleware can short-circuit later ones.

Applied in order: secureHeaderscors (methods GET, OPTIONS) → loggertimingprettyJSONrequestIdonError(errorHandler). On /api/* two further middlewares run after the above: apiKeyAuth then rateLimit.

Authentication#

API keys are passed via the X-API-Key header (the middleware also accepts Authorization: Bearer <key> and an optional query parameter). Anonymous access is allowed by default — a missing key yields tier anonymous. Keys must match ^nyx_(free|pro|enterprise)_[a-zA-Z0-9]{6,32}$.

There are two validator implementations, used in different environments:

  • Default validator: an in-memory map of three demo keys (nyx_free_demo123456, nyx_pro_testkey789, nyx_enterprise_corp456) plus any keys supplied via NYX_LOCAL_API_KEYS. This is the validator that runs when no database URL is configured.
  • Production validator: createPgApiKeyValidator(databaseUrl) performs a SHA-256-hashed lookup against the api_keys table, supporting revocation, expiry, and feature scoping.
  • Tier feature sets: free → basic, search, ephemeris; pro → adds events, satellites, batch; enterprise → adds webhook, priority.
  • Helpers: getApiKeyInfo, hasFeature, requireTier.

Rate Limiting#

Rate limits are enforced by a tiered fixed-window limiter (rate-limit.ts). Redis is used when NYX_REDIS_URL or REDIS_URL is set; otherwise an in-process store is used. The limits below are requests per minute with a burst allowance:

RATE_LIMIT_TIERS (requests per minute / burst): anonymous 60/10, free 300/30, pro 1000/100, enterprise 5000/500. Responses expose X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset headers.

Error Format#

All API errors follow RFC 7807 Problem Details (application/problem+json). ProblemDetailSchema fields: type (URI), title, status, optional detail, instance, requestId, timestamp, code. ValidationErrorSchema extends it with a per-field errors array.

Endpoint Surface#

All routes are mounted under /api/v1. Success responses use the envelope { success: true, data, [pagination], meta: { requestId, timestamp } }.

Service-info and health (unauthenticated):

Method Path Description
GET / Service metadata + endpoint index
GET /health Health check (status, uptime)
GET /api/v1 API version + endpoint list
GET /api/v1/openapi.json Static OpenAPI document
GET /api/docs Swagger UI

Objects (routes/objects.ts) — catalog queries for celestial objects:

Method Path Description
GET /api/v1/objects Paginated celestial-object list with filters
GET /api/v1/objects/search Relevance-scored search by name/designation
GET /api/v1/objects/{id} Single object by ID or catalog designation

/objects query params (ObjectQueryParamsSchema + PaginationParamsSchema): type (ObjectTypeSchema), catalog (CatalogSchema), constellation, minMagnitude, maxMagnitude, page, limit (max 100). /objects/search params: q (required), type, limit. Search results carry score (0–1) and matchedField.

Ephemeris (routes/ephemeris.ts) — position and visibility calculations for celestial objects at a given time and location:

Method Path Description
GET /api/v1/ephemeris Position/visibility over a time range
GET /api/v1/ephemeris/position Current position of an object
GET /api/v1/ephemeris/rise-set Rise / transit / set times for a date

/ephemeris query (EphemerisRequestSchema): objectId, startTime, endTime, step (default 1h), latitude, longitude, elevation. The response (EphemerisResponseSchema) contains entries[] (EphemerisEntrySchema: timestamp, jd, equatorial, optional horizontal, ecliptic, distance {au, km, lightTime}, magnitude, phase {illumination, angle}, angularSize, elongation, constellation, isVisible, riseTime, transitTime, setTime) and a summary block.

Events (routes/events.ts) — upcoming and past celestial events such as eclipses, conjunctions, and meteor showers:

Method Path Description
GET /api/v1/events Events in a date range with filters
GET /api/v1/events/upcoming Events in the next 7 days
GET /api/v1/events/types Catalog of event types with categories
GET /api/v1/events/{id} Single event by ID

/events query (EventQueryParamsSchema + pagination): startDate, endDate, type (comma-separated), types (deprecated alias), importance, latitude, longitude. Event categories returned by /events/types: lunar, solar, planetary, meteor, eclipse, seasonal.

Satellites (routes/satellites.ts) — real-time satellite positions and pass predictions:

Method Path Description
GET /api/v1/satellites Paginated satellite list
GET /api/v1/satellites/categories Satellite category catalog
GET /api/v1/satellites/passes Pass predictions for a location
GET /api/v1/satellites/{id} Single satellite by NORAD ID
GET /api/v1/satellites/{id}/passes Pass predictions for one satellite

/satellites query (SatelliteQueryParamsSchema): category (SatelliteCategorySchema), status (SatelliteStatusSchema), search, minAltitude, maxAltitude. /satellites/passes query (SatellitePassQueryParamsSchema): satelliteId (default ISS), latitude, longitude (required), elevation, days (max 14), minElevation, visibleOnly.

API Schema Enums#

These enums are used across the request validation schemas and appear in the OpenAPI document. They are the complete, canonical lists as of the current source.

  • ObjectTypeSchema: star, planet, moon, asteroid, comet, galaxy, nebula, cluster, constellation, satellite, other
  • CatalogSchema: messier, ngc, ic, hipparcos, tycho, gaia, sao, hd, yale, gcvs, mpc, jpl, norad, other
  • EventTypeSchema (33 values): solar_eclipse, lunar_eclipse, planetary_conjunction, planetary_opposition, planetary_transit, greatest_elongation, meteor_shower, comet_perihelion, asteroid_close_approach, new_moon, first_quarter, full_moon, last_quarter, supermoon, lunar_occultation, solstice, equinox, perihelion, aphelion, iss_pass, satellite_flare, satellite_decay, variable_star_maximum, variable_star_minimum, nova, supernova, conjunction, opposition, occultation, transit, rise, set, meridian_transit, other
  • EventVisibilitySchema: global, regional, local, not_visible
  • EventImportanceSchema: major, moderate, minor
  • SatelliteCategorySchema: space_station, starlink, weather, communication, navigation, earth_observation, scientific, military, amateur, debris, other
  • SatelliteStatusSchema: active, inactive, decayed, unknown

API Data Sources#

The API services back their responses with bundled-catalog libraries and sample data rather than a live database read path. This is important to understand when debugging: a query against /api/v1/objects does not hit PostgreSQL; it filters an in-memory array.

  • objects-service builds its catalog from ALL_MESSIER_OBJECTS (@nyx/messier) mapped into the API CelestialObject shape; queries filter that in-memory array.
  • events-service serves a fixed in-module list of sample events (ASTRONOMICAL_EVENTS, ~11 entries for 2024).
  • satellites-service uses createSatelliteTracker and parseTLE from @nyx/realtime-satellites with vendored TLE data for pass prediction.
  • ephemeris-service orchestrates @nyx/ephemeris and @nyx/constellations.

The celestial_events table and createPgApiKeyValidator exist for production deployments; the default request path is catalog/sample-data backed.


WebSocket API (apps/nyx/api/src/websocket)#

The WebSocket API provides real-time pushes for position updates, satellite passes, and visibility alerts. It uses a custom server rather than a generic pub/sub layer so that the subscription model (with per-tier budgets) and the update scheduling logic can be kept fully under the domain's control.

A custom WebSocket server (NyxWSServer, created by createNyxWSServer) is attached to the HTTP server at path /ws (configurable via WS_PATH). The setupNyxWebSocket helper wires the server, registers position/satellite/alert handlers, and starts an UpdateScheduler. Ping interval 30 s, ping timeout 10 s.

Message Types (NyxMessageType)#

The complete set of message types, grouped by purpose:

  • System: ping, pong, error, auth, auth_response
  • Subscription: subscribe, unsubscribe, subscribed, unsubscribed
  • Position: position:update, position:batch
  • Satellite: satellite:position, satellite:pass:start, satellite:pass:update, satellite:pass:end, satellite:batch
  • Alerts: alert:event, alert:pass, alert:visibility, alert:iss
  • Time: time:sync, time:tick

Channels (NyxChannel)#

Channels determine what data a client is subscribed to. The {id} and {type} patterns allow narrowing to a specific object or event type.

objects:*, objects:{id}, satellites:*, satellites:{id}, events:*, events:{type}, passes:*, passes:{observer}, time:sync.

Message Envelope#

All messages use the NyxMessage<T> envelope: type, optional payload, channel, id, timestamp. Subscription messages carry options { updateInterval, precision: 'low'|'medium'|'high', observer }.

Push Payloads#

The payload type for each push message:

  • PositionUpdate / PositionBatch — object positions with equatorial, optional horizontal, distance, magnitude, phase, isVisible
  • SatellitePosition / SatelliteBatch — geodetic lat/lon/altitude, velocity, footprint, optional observer-relative horizontal/range
  • SatellitePassEventphase (start | rising | culmination | setting | end), azimuth/elevation/range, progress
  • EventAlert, PassAlert, VisibilityAlertAlertSeverity is info | notice | warning | urgent
  • TimeSyncPayload, TimeTickPayload — server time, Julian date, sidereal time

Tier Limits (DEFAULT_TIER_LIMITS)#

Per-tier TierLimits control how many concurrent connections and subscriptions a client may hold, how frequently updates are sent, and how many messages per minute the server will push. Higher tiers get higher frequencies — enterprise gets 10 ms minimum intervals compared to 5000 ms for anonymous.

Tier Connections Subscriptions Min interval Msgs/min
anonymous 1 5 5000 ms 60
free 3 20 1000 ms 300
pro 10 100 100 ms 1000
enterprise 100 1000 10 ms 10000

The WS API-key validator in index.ts maps key prefixes to tiers (nyx_pro_ → pro, nyx_ent_ → enterprise, other nyx_ → free).


Database Schema (@nyx/database)#

@nyx/database exports Zod schema models (src/schema/) and Knex migration files (src/migrations/, exported as the migrations namespace). PostgreSQL extensions and enum types are created in the first migration.

Migration Tables#

The 9 migrations (2026011800000120260118000009) create the ~36 tables below. They are grouped here by the domain concern each group addresses.

  • Celestial objects: celestial_objects, stars, solar_system_objects, exoplanets, galaxies, nebulae, star_clusters
  • Orbital mechanics: orbital_elements, tle_elements, ephemeris_entries, rise_transit_set_times, eclipse_data, celestial_events, lunar_phases, meteor_showers, perturbation_records
  • Catalog cross-reference: catalog_metadata, catalog_cross_references, name_aliases, constellations, constellation_boundaries, constellation_star_patterns, artificial_satellites
  • User data: observation_logs, saved_views, custom_annotations, tour_definitions, tour_stops, tour_progress, observing_lists, observing_list_items, user_preferences, achievement_definitions, user_achievements, user_statistics
  • API: api_keys

Migration 6 creates indexes; migration 7 seeds initial data; migration 8 adds a uniqueness index used by the event-calculator pipeline; migration 9 creates api_keys (PK key_hash, tier check constraint of free/pro/enterprise, feature text[], expiry/revocation columns).

Schema Models — Celestial Objects (schema/celestial-objects.ts)#

These Zod schemas are the authoritative definitions for each object type stored in the database. Each model has a Create…InputSchema variant that omits id and timestamp fields.

Common Zod schemas: EquatorialCoordinatesSchema (ra 0–360, dec −90..+90, epoch default 2000.0, frame of ICRS|FK5|FK4|galactic|ecliptic), ProperMotionSchema, ParallaxSchema, RadialVelocitySchema, MagnitudeSchema (bands V B U R I G BP RP J H K), CatalogIdentifiersSchema (20+ catalog IDs), NameAliasesSchema.

Object models — each with a Create…InputSchema (omits id/timestamps):

  • StarSchemaStarTypeSchema (main_sequence, giant, supergiant, hypergiant, subgiant, subdwarf, white_dwarf, neutron_star, brown_dwarf, red_dwarf, blue_dwarf, carbon_star, wolf_rayet, pulsar, magnetar, black_hole, unknown), SpectralClassificationSchema, StellarPropertiesSchema, VariableStarDataSchema (VariableTypeSchema — 22 classes), and MultipleStarDataSchema
  • ExoplanetSchemaPlanetTypeSchema (terrestrial, super_earth, mini_neptune, neptune_like, gas_giant, hot_jupiter, hot_neptune, ice_giant, ocean_world, lava_world, dwarf_planet, unknown), DetectionMethodSchema (10 methods), PlanetaryOrbitSchema, PlanetaryPropertiesSchema, HabitabilityMetricsSchema (inHabitableZone, esi, phi, potentialWater, insolation)
  • SolarSystemPlanetSchema — physical and orbital properties, moon count, rings, atmosphere/surface composition records
  • GalaxySchemaGalaxyMorphologySchema (Hubble sequence incl. LIRG, ULIRG), GalaxyActivitySchema (normal, seyfert1, seyfert2, liner, quasar, blazar, radio_galaxy, starburst, agn, ulirg, unknown), GalaxyPropertiesSchema
  • NebulaSchemaNebulaTypeSchema (15 values incl. hii_region, bok_globule, herbig_haro), NebulaPropertiesSchema
  • StarClusterSchemaClusterTypeSchema (open_cluster, globular_cluster, stellar_association, asterism, moving_group, embedded_cluster, unknown), TrumplerClassSchema, ClusterPropertiesSchema
  • DeepSkyObjectSchema — generic unified-query model with DeepSkyObjectTypeSchema (15 values)

Search schemas: CoordinateSearchBoxSchema, ConeSearchSchema, MagnitudeFilterSchema, PaginationSchema (limit max 1000), SortOrderSchema.

Schema Models — Catalogs (schema/catalogs.ts)#

Catalog schemas handle identifier cross-referencing — the logic of knowing that HD 19445, HIP 14544, and Gaia DR3 2534784854721380352 all refer to the same object.

  • CatalogTypeSchema — ~55 catalog identifiers across star, variable-star, double-star, deep-sky, planetary, satellite, and database categories (hipparcos, gaia_dr3, messier, ngc, ic, mpc, simbad, ned, norad, …)
  • CatalogObjectTypeSchema — 31 object classifications
  • DataQualitySchemaexcellent, good, fair, poor, suspect, unknown
  • CatalogMetadataSchema, CatalogIdentifierSchema, CatalogCrossReferenceSchema, NameAliasSchema (NameTypeSchema — 16 name types including arabic, chinese, indigenous), ConstellationInfoSchema
  • ConstellationAbbreviationSchema — all 88 three-letter IAU abbreviations
  • Query schemas: CatalogSearchQuerySchema, NameSearchQuerySchema, CrossReferenceQuerySchema, CrossReferenceResultSchema

Schema Models — Orbital Mechanics (schema/orbital-mechanics.ts)#

OrbitalBodyTypeSchema (15 values incl. centaur, tno, kuiper_belt, oort_cloud), OrbitalReferenceFrameSchema (heliocentric_j2000, teme, gcrf, …), KeplerianElementsSchema with full element set and per-element uncertainties.

Schema Models — User Data (schema/user-data.ts)#

User data schemas cover the full observing session lifecycle: site conditions when the session was conducted, equipment used, per-object observation notes, saved views and annotations, educational tour progress, and achievement records.

  • Observation logsSeeingConditionsSchema, TransparencySchema, BortleScaleSchema (1–9), WeatherConditionsSchema, EquipmentTypeSchema (11 types), EquipmentUsedSchema, ObservationTypeSchema (15 types), ObservationLogSchema
  • Saved viewsViewTypeSchema, ProjectionTypeSchema (8 projections incl. mollweide, aitoff, hammer, gnomonic), ViewConfigurationSchema, SavedViewSchema
  • AnnotationsAnnotationTypeSchema (9 types), AnnotationPointSchema, AnnotationStyleSchema, CustomAnnotationSchema
  • Educational toursTourDifficultySchema (beginner, intermediate, advanced, expert), TourCategorySchema (15 categories), TourStepTypeSchema (9 step types), StepStatusSchema, TourStepDefinitionSchema, TourDefinitionSchema, TourProgressSchema
  • AchievementsAchievementTypeSchema (13 types), AchievementDefinitionSchema (rarity common…legendary), UserAchievementSchema
  • User preferencesUserPreferencesSchema (default location, units, notification flags, theme incl. night_vision)
  • Observing listsObservingListItemSchema, ObservingListSchema

Data Pipelines (apps/nyx/pipelines)#

The pipelines application contains four independent Node.js worker entry points. Each pipeline runs on its own schedule and writes results to PostgreSQL for the API to serve. They are intentionally kept separate so that a slow catalog sync does not block satellite pass predictions, and a failing ephemeris generation does not affect event calculations.

The four pipelines, registered in PIPELINES (src/index.ts):

Pipeline Entry point Purpose
tle-updater tle-updater.ts Fetch TLE data, refresh satellite orbital state
catalog-syncer catalog-syncer.ts Sync Gaia/Hipparcos catalog data into object tables
ephemeris-generator ephemeris-generator.ts Pre-compute solar-system positions
event-calculator event-calculator.ts Predict conjunctions/eclipses and persist to celestial_events

The event-calculator works by walking pairs of visible bodies with the @nyx/events conjunction scanner and Bessel-element eclipse predictors, then upserting results into the celestial_events table via pg (INSERT INTO celestial_events …). Each pipeline can run directly or as a Kubernetes CronJob. Shared common/ modules provide a pino logger, a prom-client metrics registry, and an HTTP health server gated by METRICS_ENABLED. Pipeline dependencies include @nyx/gaia, @nyx/hipparcos, @nyx/coordinates, @nyx/database, @nyx/ephemeris, @nyx/events, @nyx/orbital, @nyx/realtime-satellites, @nyx/time, and astronomy-engine.


Library Surface (libs/nyx/*)#

The Nyx domain ships 75 published packages organised into nested groups. Package names below are the canonical npm-style identifiers.

Core / Foundation#

Package Path Purpose
@nyx/types libs/nyx/types Shared TypeScript type system (six modules)
@nyx/constants libs/nyx/constants Physical and astronomical constants
@nyx/coordinates libs/nyx/coordinates Coordinate-system transforms
@nyx/time libs/nyx/time Time scales, Julian date, sidereal time, Delta-T
@nyx/utils libs/nyx/utils Angular and magnitude math helpers
@nyx/database libs/nyx/database Zod schema models + Knex migrations

Astronomical Computation#

Package Path Purpose
@nyx/ephemeris libs/nyx/ephemeris Solar-system position computation
@nyx/orbital libs/nyx/orbital Kepler/n-body, perturbations, Lagrange points, propagation
@nyx/positional libs/nyx/positional Topocentric correction, refraction, rise/set
@nyx/events libs/nyx/events Eclipse / conjunction / occultation / transit / meteor / aurora / satellite-pass / supermoon / deep-sky event prediction, plus calendar sync (largest computation library)
@nyx/constellations libs/nyx/constellations Multi-cultural constellation database + artwork
@nyx/mythology libs/nyx/mythology Constellation mythology data
@nyx/time-travel libs/nyx/time-travel Historical/future sky reconstruction
@nyx/sky-clock libs/nyx/sky-clock Sky-event materialiser, observer-location bucketing

Catalogs — Star Catalogs (libs/nyx/catalogs)#

@nyx/hipparcos, @nyx/gaia, @nyx/tycho, @nyx/bright-stars, @nyx/simbad, @nyx/star-query (multi-catalog unified query).

Catalogs — Deep Sky (libs/nyx/catalogs/deep-sky)#

@nyx/messier, @nyx/ngc-ic, @nyx/nebulae, @nyx/clusters, @nyx/snr, @nyx/pulsars, @nyx/neutron-stars, @nyx/black-holes, @nyx/quasars, @nyx/gravitational-waves. Plus @nyx/supernovae, @nyx/ned, @nyx/sdss.

Catalogs — Exoplanets and Solar System#

Exoplanets: @nyx/nasa-exoplanets, @nyx/open-exoplanets. Solar system (libs/nyx/catalogs/solar-system): @nyx/planets, @nyx/moons, @nyx/horizons, @nyx/mpc, @nyx/neo, @nyx/comets. Plus @nyx/spacecraft.

Analysis (libs/nyx/analysis)#

@nyx/galaxy-classification, @nyx/habitability (habitable zone, Earth Similarity Index, atmospheric retention, tidal locking), @nyx/visualization (chart generation).

Real-Time (libs/nyx/realtime)#

@nyx/realtime-satellites (TLE parsing + SGP4 satellite tracker), @nyx/realtime-solar, @nyx/realtime-neo, @nyx/realtime-events.

Renderer (libs/nyx/renderer)#

12 WebGL/Three.js rendering packages: @nyx/renderer-core, @nyx/renderer-background, @nyx/renderer-stars (published as @nyx/star-colors), @nyx/renderer-planets, @nyx/renderer-galaxies, @nyx/renderer-nebulae, @nyx/renderer-clusters, @nyx/renderer-exotic, @nyx/renderer-hdr, @nyx/renderer-lod, @nyx/renderer-scale, @nyx/renderer-post-processing.

Widgets, Audio, Education, Integrations, Visualization#

  • Widgets (libs/nyx/widgets): @nyx/widget-iss-tracker, @nyx/widget-moon-phase, @nyx/widget-star-map
  • Audio (libs/nyx/audio): @nyx/audio-sonification, @nyx/audio-ambient
  • Education (libs/nyx/education): @nyx/lesson-framework, @nyx/quiz-system
  • Integrations (libs/nyx/integrations): @nyx/telescope, @nyx/stellarium, @nyx/planetarium
  • Visualization (libs/nyx/visualization): @nyx/galaxy-distribution

Clients and Cross-Domain#

Package Path Purpose
@nyx/client libs/nyx/client Hand-written typed HTTP client for the API
@nyx/api-client libs/nyx/api-client Client with OpenAPI-generated types
@nyx/lilith-integration libs/nyx/lilith-integration Cosmic-meditation content bridge to Lilith

libs/nyx/client-python exists as a Python client package (pyproject.toml, no TypeScript sources). libs/nyx/docs contains design documents (architecture.md, caching-strategy.md) — it is not a published package.

@nyx/lilith-integration — Cosmic Meditation Bridge#

@nyx/lilith-integration does not handle Lilith domain events. It is a content/state library: it provides curated meditation material derived from cosmic imagery, which Lilith can consume without needing to understand astronomical algorithms. Nothing in this package computes positions or queries catalogs.

  • CosmicMeditationTheme (8), SessionIntensity (gentle | moderate | deep | transcendent), AwarenessPhase (6 phases), CosmicBreathPattern (5)
  • Content collections: COSMIC_VISUALIZATIONS (8 visualizations), SPACE_PARALLELS (8 inner/outer-space parallels), CONSCIOUSNESS_EXERCISES (6 exercises), BREATH_PATTERNS
  • LilithBridgeManager — session lifecycle, breath-phase animation, exercise navigation; emits LilithBridgeEventType events (session_started, phase_changed, breath_cycle_completed, …)
  • Zod schemas: SessionStateSchema, UserPreferencesSchema, SessionConfigSchema

Application Surface (apps/nyx/*)#

The Nyx domain ships 22 packaged applications. Six are top-level apps; the education directory holds 12 packaged apps and the tools directory holds 4.

Top-Level Applications#

Application Package Path Stack
API @nyx/api apps/nyx/api Hono + OpenAPI + ws
Star Map @nyx/star-map apps/nyx/star-map Vite + React + Three.js
VR Planetarium @nyx/vr-planetarium apps/nyx/vr-planetarium React-Three-Fiber + WebXR
AR Sky @nyx/ar-sky apps/nyx/ar-sky React-Three-Fiber + WebXR
Mobile @nyx/mobile apps/nyx/mobile React + idb-keyval
Pipelines @nyx/pipelines apps/nyx/pipelines Node.js workers

star-map is the largest application (~189 source files) and contains feature modules for navigation, planning, collections, constellations, spacecraft, satellites, mythology, time-travel, filters, tonight-view, journal, audio, meditation, solar, NEO, and bookmarks. ar-sky and vr-planetarium depend on @nyx/realtime-solar and the React-Three ecosystem.

Education Applications (apps/nyx/education)#

  • Courses: @nyx/fundamentals-course, @nyx/solar-system-course, @nyx/stellar-course, @nyx/galactic-course, @nyx/cosmology-course
  • Challenges: @nyx/star-identification, @nyx/orbital-mechanics
  • Demos: @nyx/hr-diagram, @nyx/spectroscopy, @nyx/distance-ladder, @nyx/light-speed, @nyx/gravity-well

Tools Applications (apps/nyx/tools)#

@nyx/astrophotography, @nyx/light-curves, @nyx/observation-planner, @nyx/orbit-determination.


Cross-Domain Integration#

Nyx interoperates with the wider Oshun monorepo through @nyx/lilith-integration, which surfaces cosmic-meditation content for the Lilith consciousness domain. The @nyx/orbital library includes a kalika-relativity module and a solar-system-integration module that provide thin touchpoints with the Kalika mathematics/physics domain.

The boundary with Lilith is intentionally content-level rather than data-level: Lilith receives pre-composed meditation material (visualizations, breath patterns, awareness phases) rather than raw ephemeris data or catalog objects. This prevents Lilith from taking an indirect dependency on the entire astronomical computation stack.

The earlier specification claimed Kafka event publishing via @oshun/event-bus and nyx.* event contracts in @oshun/contracts. No such Kafka publisher or NyxEventTypes contract exists in the current code; that claim has been removed.


Configuration Reference#

Configuration is supplied through environment variables read at process startup; there is no single NyxConfig object in code. The variables below are the complete set observed across the API and pipeline source.

Variable Component Effect
PORT (default 3000) API HTTP + WebSocket listen port
HOST (default 0.0.0.0) API Bind address
WS_PATH (default /ws) API WebSocket endpoint path
NYX_REDIS_URL / REDIS_URL API Redis backing for the rate limiter
NYX_LOCAL_API_KEYS API Comma-separated key:tier:owner local key entries
NODE_ENV API/pipelines Environment selection
METRICS_ENABLED Pipelines Set to false to disable the health/metrics server

Tier rate limits, WebSocket tier limits, ping intervals, and pipeline registry entries are defined as constants in code (RATE_LIMIT_TIERS, DEFAULT_TIER_LIMITS, PIPELINES) rather than configuration.


Acceptance Criteria#

A change to the Nyx domain is acceptance-complete when all of the following conditions hold. They are ordered to mirror the dependency chain: types first, then API, then persistence, then tests.

  1. All @nyx/types exports type-check and consumers compile against them.
  2. New API routes are defined with @hono/zod-openapi createRoute, validate input with Zod schemas, and return the standard success/ProblemDetail envelopes.
  3. New persistent entities are added both as Zod schema models in @nyx/database and as Knex migrations, with the migration's table covered by migrations/20260118000006_create_indexes.ts where query patterns need indexes.
  4. Astronomical computations are unit-tested with Vitest against known-correct reference values (eclipse contacts, planet positions, separation angles), not merely shape assertions.
  5. WebSocket message and channel additions extend NyxMessageType / NyxChannel and respect the per-tier DEFAULT_TIER_LIMITS.
  6. Pipeline changes preserve the independent-worker model and the shared health/metrics server.
  7. npx tsc --noEmit, npx vitest run, and lint pass for each affected package.

Source Grounding#

This specification was reconstructed from source: libs/nyx/types/src/* (coordinates, celestial, time, observer, orbital, visualization, index), libs/nyx/database/src/schema/* and src/migrations/*, apps/nyx/api/src/* (app, index, routes, schemas, middleware, websocket), libs/nyx/events/src/index.ts, libs/nyx/lilith-integration/src/lilith-integration.ts, libs/nyx/constellations/src/index.ts, libs/nyx/sky-clock/src/*, apps/nyx/pipelines/src/*, the 75 libs/nyx/**/package.json files, the 22 apps/nyx/**/package.json files, deploy/nyx/*, and TODOS/phase-21.md. Every enum value, field, endpoint, table, and package name is present in that source.