Files
astrololo/services/logic
gitea 8ed8d9fb7a
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m4s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m56s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 32s
Testy / Kontrola składni wszystkich warstw (push) Successful in 20s
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 11m9s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 10m15s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 37s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 20s
feat(logic): tabele pomocnicze horoskopu (LOG-23)
Komplet wyliczen, ktore astrolog czyta „obok" pozycji:

- bilans zywiolow i jakosci w czterech wariantach (7 klasycznych / 10 z nowozytnymi,
  z Ascendentem i bez) + wykrywanie BRAKUJACYCH zywiolow — klasyczne „no air",
  podstawa pod scoring sily (LOG-21),
- faza Ksiezyca: elongacja, nazwa fazy, procent oswietlenia, przybywa/ubywa,
- stopnie krytyczne wg jakosci znaku (kardynalne 0/13/26, stale 8/21, zmienne
  4/17) + 29 stopien anaretyczny i 0 stopni wejscia w znak,
- dzien i godziny planetarne w porzadku chaldejskim,
- syzygia prenatalna (ostatni now albo pelnia przed urodzeniem),
- podzialy: dwunastniki (D12) i nawamsa (D9).

Dwie rzeczy wymagaly prawdziwego liczenia, nie tabelki:
* godziny planetarne sa NIEROWNE — dzien od wschodu do zachodu dzieli sie na 12,
  noc osobno. Bez faktycznego wschodu/zachodu wynik bylby zmyslony, wiec szukamy
  ich numerycznie (przejscie wysokosci Slonca przez -0°50', bisekcja jak przy
  stacjach z LOG-03). Doba planetarna startuje o WSCHODZIE, nie o polnocy.
* syzygia prenatalna — szukanie wstecz przejscia elongacji przez 0/180 stopni.

Walidacja wobec faktow NIEZALEZNYCH od naszego kodu:
- 30.04.1984 to poniedzialek -> wladca dnia Ksiezyc; 5. godzina poniedzialku
  w porzadku chaldejskim to Slonce (Mo, Sa, Ju, Ma, Su) — zgadza sie,
- wschod/zachod dla Krakowa: 03:18 / 17:57 UTC = 5:18 / 19:57 lokalnie — zgodne
  z rzeczywistoscia dla konca kwietnia,
- syzygia: pelnia 15.04.1984 19:10:45 UTC; rzeczywista byla 19:11 — roznica
  ponizej minuty,
- bilans przeliczony recznie: Ogien 4, Ziemia 4, Woda 3, Powietrze 0.

UI: checkbox „tabele dodatkowe" na ekranie Horoskop (opt-in, bo szuka numerycznie)
i sekcja wynikow. Endpoint: /chart/positions?tables=true.

Testy: 28 nowych (w tym noc polarna -> brak godzin planetarnych, oraz sprawdzenie,
ze w znalezionej syzygii elongacja FAKTYCZNIE wynosi 0/180). Calosc: 202 passed /
1 skipped + 17 (prezentacja). Zweryfikowane e2e w UI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 23:09:57 +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.