# Precisione dei calcoli

## TL;DR

L'API di AstroWay utilizza **Swiss Ephemeris** (codice C ufficiale di Astrodienst,
creatori di astro.com) — lo stesso motore su cui i professionisti dell'astrologia
lavorano da oltre 30 anni con **Solar Fire ($495), Kepler ($995), Astro Gold ($29.99/mese)
e Janus**. Lo abbiamo compilato in WebAssembly e esposto tramite un layer REST,
senza markup intermediario. Ogni endpoint di calcolo di base è coperto da test
regressionali snapshot; la precisione del motore è stata verificata tramite
**triangolazione** con tre fonti indipendenti + contro il **NASA 5-Millennium Eclipse Catalog**:

- **Posizioni planetarie**: `< 0.1 arcsec` vs swetest CGI ufficiale di Astrodienst
- **Cuspidi delle case Placidus**: corrispondenza esatta `0.000"`
- **Eclissi**: `< 1 minuto` vs NASA Eclipse Catalog
- **Linee ACG**: `< 1.5 km` all'equatore vs swetest
- **Alba/Tramonto**: `< 10 secondi` vs timeanddate.com
- **VOC della Luna, ingressi, congiunzioni planetarie**: precisione al millesimo di secondo

## Motore

| Componente | Valore |
|------------|--------|
| Libreria | Swiss Ephemeris C code (aloistr/swisseph) |
| Versione | codice C upstream di Astrodienst |
| Bindings | swisseph-wasm (WebAssembly in Node.js) |
| Efemeridi | DE431 JPL ephemeris (tramite file .se1) |
| Fallback | Moshier analitico (per date al di fuori del 1800-2399) |
| Condivisione codice | Shared `@/core` con app.astroway.info — stesso motore, due trasporti |

## Metodologia

La precisione viene verificata tramite **triangolazione** — confronto con tre fonti
indipendenti:

### 1. swetest CGI (reference)

Implementazione ufficiale di riferimento di Swiss Ephemeris di Astrodienst — i
creatori di **Astro.com** e fornitore di milioni di astrologi in tutto il mondo.
La fonte pubblica più autorevole. Il nostro motore è **identico** (0.00–0.07 secondi
d'arco di drift).

### 2. Kerykeion (Python)

Libreria Python indipendente che utilizza i bindings `pyswisseph` invece del nostro
WASM. Conferma che il nostro layer WASM non distorce i dati.

### 3. Prokerala API

API remota Swiss Ephemeris (Lahiri sidereal). Un drift sistemico di 8–17 secondi
d'arco è legato alle diverse versioni della formula Lahiri ayanamsa, e **non**
alla precisione del motore.

## Risultati della triangolazione

| Carta | vs swetest (Astrodienst) | vs Kerykeion (Python) | vs Prokerala API |
|-------|---------------------------|------------------------|------------------|
| Monroe 1926   | **0.00"** | 0.19" | 16.95" (sistemico) |
| Diana 1961    | **0.00"** | 0.69" | 8.18" (sistemico)  |
| Einstein 1879 | 0.07"     | Artefatto LMT di Kerykeion | 14.96" (sistemico) |

## Suite di regressione a livello di endpoint

Ogni endpoint di calcolo di base è coperto da test snapshot congelati su 3 carte
di riferimento (Monroe / Diana / Einstein) = **{siteMeta.snapshotCount} snapshot**.

La suite di snapshot rileva:

- **Bug di mappatura dei dati di input** — ID pianeta errato, UT, sistema di case
- **Post-elaborazione** — arrotondamenti, conversione delle unità, perdita del segno
- **Divergenza dei valori predefiniti** — nodo medio vs vero, geocentrico vs topocentrico
- **Schema drift** — la validazione ha permesso uno schema errato
- **Deploy obsoleto** — la dist prod non corrisponde al codice

Tolleranza: `5e-5°` (≈0.18 secondi d'arco) per impostazione predefinita per tutti i campi numerici.

## Benchmark dettagliati

### Posizioni planetarie (tropicale, vs swetest)

| Carta | Data | Drift massimo |
|-------|------|---------------|
| Marilyn Monroe  | 1926-06-01 | **0.00"** |
| Princess Diana  | 1961-07-01 | **0.00"** |
| Albert Einstein | 1879-03-14 | 0.07"     |

### Cuspidi delle case Placidus (vs swetest)

| Carta | drift ASC | drift MC | Drift massimo della cuspide |
|-------|-----------|----------|-----------------------------|
| Monroe | 0.000" | 0.000" | 0.000" |
| Diana  | 0.000" | 0.000" | 0.000" |

### Eclissi (vs NASA 5-Millennium Catalog)

| Evento | Massimo NASA | Il nostro massimo | Drift |
|--------|--------------|-------------------|-------|
| 2025-03-14 Lunare Totale  | 06:58 UT | 06:58 UT | 0.8 min |
| 2025-03-29 Solare Parziale | 10:47 UT | 10:47 UT | 0.5 min |
| 2025-09-07 Lunare Totale  | 18:11 UT | 18:11 UT | 0.8 min |
| 2025-09-21 Solare Parziale | 19:41 UT | 19:42 UT | 1.0 min |

### Astrocartografia (vs formula RA di swetest)

Tutte le linee MC/IC/ASC/DSC utilizzano la formula corretta `longitude = RA − GMST`
(standard di Kenneth Bowser). Drift rispetto al riferimento: **< 1.5 km** all'equatore
per tutti i pianeti.

### Alba / Tramonto del Sole (vs timeanddate.com)

| Località | Data | Parametro | Drift |
|----------|------|-----------|-------|
| Londra | 2026-04-15 | Alba | 0.6 s |
| Londra | 2026-04-15 | Tramonto  | 9 s   |

**Località polari** (|lat| > 66.5°) restituiscono automaticamente `polarState` +
un avviso che le consuete planetary hours non sono definite.

### Orbite degli aspetti

AstroWay utilizza **orbite variabili** per pianeta (regola MIN di due pianeti),
come in ZET9 e astro.com. Orbite predefinite (per una carta natale):

| Aspetto | Sole | Luna | Pianeti interni | Giove | Pianeti esterni |
|---------|------|------|-----------------|-------|-----------------|
| Congiunzione | 12°  | 10° | 5° | 8° | 5° |
| Sestile     | 6.5° | 6°  | 5° | 5° | 5° |
| Quadratura  | 10°  | 8°  | 5° | 7° | 5° |
| Trino       | 12°  | 8°  | 5° | 5° | 5° |
| Opposizione | 12°  | 10° | 5° | 8° | 5° |

Gli aspetti minori (36°, 40°, 45°, 72°, 108°, 135°, 144°) sono **disabilitati per
impostazione predefinita**. Si possono abilitare esplicitamente tramite `ALL_ASPECTS`.

## Latitudini polari

Per |lat| > 66.5° i sistemi Placidus / Koch / Regiomontanus sono matematicamente
indefiniti. In questi casi Swiss Ephemeris restituisce automaticamente Porphyry,
e la nostra API aggiunge un avviso:

```json
{
  "system": "P",
  "warning": "Il sistema Placidus è indefinito per lat=68.96° (> 66.5°). Swiss Ephemeris ha sostituito con Porphyry..."
}
```

## Verifica continua

La regressione viene verificata **ad ogni PR** tramite CI:

- `api-calc/tests/endpoints/` — {siteMeta.snapshotCount} snapshot contro carte di riferimento (Monroe / Diana / Einstein) + synastry / composite / davison
- `.github/workflows/api-accuracy.yml` — esecuzione automatica al PR
- Triangolazione vs swetest CGI + Kerykeion — settimanalmente
- Monitoraggio upstream Swiss Ephemeris tramite Dependabot

## Limitazioni note

- **Date fuori range** (prima del 1800 e dopo il 2399): viene utilizzato Moshier
  analitico, precisione ~0.1" (vs < 0.01" per SWIEPH con file DE431)
- **Lilith Vera (id=13) vs Lilith Media (id=12)**: differenza fino a 12° — per
  impostazione predefinita viene usata Lilith Media (comportamento stabile),
  Lilith Vera è disponibile tramite `planetIds: [13]`
- **Topocentrico vs geocentrico**: per impostazione predefinita geocentrico

## Link

- Swiss Ephemeris: https://www.astro.com/swisseph/
- swetest CGI: https://www.astro.com/swisseph/swetest.htm
- Catalogo delle eclissi NASA: https://eclipse.gsfc.nasa.gov/
- Kerykeion: https://github.com/g-battaglia/kerykeion
- Astrodienst: https://www.astro.com/

## Contatti

Per domande sulla precisione: scrivi a support@astroway.info con i dati della carta
e il riferimento atteso (astro.com o altra fonte autorevole).
