Dokładność to coś, co użytkownik po cichu sprawdza, porównując cię z Astrodienst. Jeśli horoskop urodzeniowy rozjedzie się o minutę kątową, skarga przyjdzie szybko. A najgorsze jest to, że dokładność łatwo zepsuć niezauważenie: jeden refaktoring w kodzie efemeryd i połowa endpointów po cichu przesuwa się o sekundy łuku.
Oto jak do tego nie dopuszczamy.
Jeden rdzeń dla dwóch środowisk
Dział zatytułowany „Jeden rdzeń dla dwóch środowisk”Pozycje planet liczy Swiss Ephemeris. Kluczowe jest to, że nasza aplikacja i API mają jeden rdzeń obliczeniowy i jedną bazę kodu. Nie ma dwóch implementacji, które mogłyby się rozjechać, więc nie ma czemu się rozjeżdżać.
Dla dat spoza głównego zakresu efemeryd jest analityczny fallback (Moshier), nieco mniej dokładny, ale bez nieciągłości na granicach. Świadoma uczciwość: nie podajemy publicznie konkretnej wersji silnika, bo faktyczna wersja rdzenia jest starsza niż najnowszy upstream, a podawanie efektownej liczby byłoby kłamstwem.
Zamrożone snapshoty
Dział zatytułowany „Zamrożone snapshoty”Każdy endpoint obliczeniowy ma zestaw zamrożonych snapshotów: 873 fikstur JSON w chwili tego buildu. Runner uruchamia endpoint na horoskopach wzorcowych i porównuje wynik z fiksturą bajt po bajcie (w granicach tolerancji). Każde odchylenie długości ekliptycznej planety większe niż 5e-5° (0.18″) wywraca test.
Horoskopy wzorcowe dobrano tak, żeby uderzały w przypadki brzegowe, a nie tylko w “wygodny” środek:
- Monroe, Diana, Einstein, Bowie - historyczne horoskopy ze znanymi danymi urodzenia
- szerokość polarna - gdzie systemy domów się degenerują
- równikowa - gdzie zachowują się inaczej
- półkula południowa - sprawdzenie symetrii lustrzanej
Przypadki brzegowe wyłapują właśnie te regresje, których nie widać na horoskopie przeciętnego mieszkańca Kijowa.
Triangulacja względem źródeł zewnętrznych
Dział zatytułowany „Triangulacja względem źródeł zewnętrznych”Snapshoty wyłapują regresje względem samych siebie. Żeby sprawdzać prawdę bezwzględną, każde wydanie jest porównywane z niezależnymi źródłami:
| Względem czego | Co sprawdza | Rozbieżność |
|---|---|---|
| swetest CGI (Astrodienst) | długości planet, wierzchołki domów | 0.000″ |
| Kerykeion (Python, pyswisseph) | niezależna implementacja SwEph | < 0.2″ |
| Prokerala (sidereal Lahiri) | pozycje syderyczne | 8-17″, systemowa różnica we wzorze ajanamszy, nie w silniku |
| NASA 5-Millennium Eclipse Catalog | czas i typ zaćmień | < 1 min |
Rozbieżność z Prokerala to nie błąd: to różne implementacje wzoru Lahiri, i dokumentujemy to wprost, zamiast ukrywać. Ze swetest, który jest wzorcem w branży, dryf wynosi zero.
Linie astrokartografii są dodatkowo sprawdzane geometrycznie: dokładność na równiku jest lepsza niż 1.5 km.
Co jest uruchamiane przy każdym PR
Dział zatytułowany „Co jest uruchamiane przy każdym PR”Dokładność to bramka CI, a nie jednorazowa kontrola:
api-accuracy.yml- przy każdym PR do kodu backendu uruchamia cały zestaw snapshotów + triangulację. Czerwony test blokuje merge.check-eclipse-accuracy.yml- raz w roku porównuje zaćmienia z katalogiem NASA; rozbieżność powyżej progu automatycznie zakłada issue.check-sweph-updates.yml- co tydzień śledzi upstream Swiss Ephemeris; nowa wersja oznacza issue do przeglądu, bez automatycznego merge (aktualizacja silnika efemeryd to zbyt delikatna sprawa na automatyczny update).
Co to daje integratorowi
Dział zatytułowany „Co to daje integratorowi”Gwarancja jest prosta: pozycje planet mieszczą się w granicach < 0.1 sekundy kątowej od wzorcowego Swiss Ephemeris, a tej granicy pilnuje automatyka, a nie obietnica w README. Jeśli kiedyś pojawi się regresja, wywróci się w naszym CI, a nie w skardze twojego użytkownika.
Publiczna wersja tych liczb, z tabelą rozbieżności dla konkretnych horoskopów, jest na stronie Dokładność.
Ten sam Swiss Ephemeris, co w Solar Fire - w 4 liniach kodu.
Darmowy klucz bez karty. 5 000 wywołań miesięcznie do pierwszej płatności.