Files
astrololo/services/logic
gitea 4d1daab35a
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m34s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 18s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 10s
build / build (push) Successful in 26s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m37s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m33s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m27s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 17s
Testy / Kontrola składni wszystkich warstw (push) Successful in 10s
feat(domy): warianty od Barana i od MC + obrót kosmogramu — LOG-05 zamknięte
Ostatnie trzy pozycje z treści LOG-05, których wcześniej nie było:

- whole_sign_aries — znaki jako domy, ale dom I ZAWSZE na 0° Barana, niezależnie
  od Ascendentu (tradycja indyjska i część szkół hellenistycznych),
- equal_mc — równe domy zakotwiczone na MC: dom X zaczyna się dokładnie na
  południku, a nie ma go gdzieś w środku,
- obrót kosmogramu: Ascendent albo 0° Barana po lewej stronie koła. Zmienia
  WYŁĄCZNIE rysunek, żadna liczba nie jest przeliczana. Wariant „od Barana"
  unieruchamia koło względem zodiaku, więc dwa horoskopy da się porównać na oko.

Oba nowe systemy zgodne z wyrocznią co do zera od pierwszego uruchomienia.
Razem 13 systemów: 2 833 424 porównania w przemiale, zero przekroczeń.

PRZY OKAZJI — DWA BŁĘDY, KTÓRE SAM WPROWADZIŁEM I KTÓRYCH TESTY NIE WIDZIAŁY:
- linia zbierająca ostrzeżenia o fallbacku trafiła do handlera strony głównej
  zamiast do compile_pdf: odwoływała się do nieistniejącej zmiennej, czyli 500
  na stronie głównej, a do PDF-a ostrzeżenia nie docierały wcale,
- compile_build używał parametru formularza, którego nie miał w sygnaturze.

Oba przeszły przez komplet zielonych testów, bo żaden nie wywoływał POST-a —
testy prezentacji sprawdzały teksty w szablonach i w main.py. Doszły więc testy
uderzające w prawdziwe trasy (POST / i POST /compile ze stubowaną logiką), które
łapią tę klasę błędu.

Z tego samego powodu przepisane dwa testy PDF-a: greppowały z main.py dokładny
kształt wywołania render(chart, theme="print") i pękały przy dopisaniu argumentu,
mimo poprawnego zachowania. Teraz wołają trasę i sprawdzają, że KAŻDY z czterech
rysunków dostaje motyw druku.

LOG-05 i PRE-05 → Zrobione w docs/astrololo_wymagania.xlsx.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 22:38:43 +02:00
..

Warstwa logiczna (logic)

Niezależna usługa pośrednicząca. W górę udostępnia API dla prezentacji, w dół woła warstwę bazodanową. Tu żyją reguły biznesowe — nie w prezentacji i nie w bazie.

API

  • POST /api/queryQueryRequestQueryResponse
  • POST /chart/positions{when_utc, lat, lon, house_system?} → pełny horoskop: pozycje (LOG-01) + osie i domy (LOG-05) + aspekty główne z applying/separating (LOG-06) + opcjonalnie stacje planet (stations:true, LOG-03). Zwraca też sektę i 7 Lots hermetycznych z domami (LOG-08). Obiekty: 10 planet + mean NN/SN/Lilith (LOG-02). house_system: whole_sign (dom.) / equal / porphyry.
  • POST /chart/report{when_utc, lat, lon, limit?} → wynik obliczeń wyszukany w bazie: fasety sygnifikatorów w znaku / w domu / w aspekcie, z rozwinięciem skrótów, odsiewaniem duplikatów (ten sam sygnifikator i opis), rankingiem siły (LOG-21) oraz opcją group (grupowanie identycznych opisów)
  • POST /chart/profections{when_utc, lat, lon, start_age?, count?} → profekcje roczne: wiek, profektowany Asc, Władca Roku (+MC/Su/Mo) (LOG-10)
  • POST /chart/return{when_utc, lat, lon, kind, around?} → Solar/Lunar Return: moment powrotu + pełny horoskop na ten moment (LOG-12)
  • POST /chart/firdaria{when_utc, lat, lon} → Firdaria: sekta (dzień/noc), okresy główne i podokresy time-lordów (LOG-11)
  • POST /chart/timeline{when_utc, lat, lon, from_date, to_date, techniques?} → zbiorcza oś czasu: profekcje + Solar Return + dyrekcje solar-arc + Firdaria, posortowane (technique | significator | start | exact | end); z interpret=true dopina interpretacje z bazy do dat (LOG-14, 1B->2B)
  • POST /chart/compare → jak wyżej → raport różnic dwóch silników (LOG-26; wymaga silnika B)
  • GET /health (sprawdza też warstwę bazodanową)

Silnik efemeryd (LOG-24, „wymienny silnik liczący")

W app/engine/ żyje pluggable silnik za interfejsem EphemerisEngine:

  • SkyfieldEngine — własny, permisywny (Skyfield MIT + dane JPL public domain). Domyślny.
  • RemoteEngine — klient OSOBNEJ, izolowanej usługi engine-swisseph (AGPL), używany tylko w trybie porównawczym.

Wybór: EPHEMERIS_ENGINE=own|swisseph. Silnik B włącza się przez ENGINE_SWISSEPH_URL.

Walidacja (LOG-25/28): app/engine/compare.py zestawia oba silniki z progiem tolerancji; ten sam kontrakt parzystości obowiązuje każdy silnik. Nasz SkyfieldEngine zgadza się ze Swiss Ephemeris co do ~1″ na horoskopie referencyjnym (patrz tests/).

pip install -r requirements-dev.txt
PYTHONPATH=. pytest tests -q            # silnik B pomijany, jeśli ENGINE_SWISSEPH_URL nieustawiony

Zależności w dół

Zna wyłącznie DATA_URL (adres warstwy bazodanowej) i jej kontrakt /search. Nie wie, czy pod spodem jest Excel czy SQL.

Uruchomienie

pip install -r requirements.txt
export DATA_URL=http://localhost:8002
uvicorn app.main:app --port 8001

Gdzie rozbudowywać domenę

service.pyQueryService.handle(): walidacja wejścia, tłumaczenie zapytania, obliczenia i wzbogacanie wyników.