mirror of
https://github.com/migatu/astrololo.git
synced 2026-07-14 21:38:37 +00:00
413c46b5dd
Trzy usterki uniemożliwiające uruchomienie stosu lokalnie: 1. Warstwa danych wykładała się na starcie przy zapisie Parquet dla realnych plików (np. Encyclopaedia of Medical Astrology) — kolumny o mieszanych typach (int+str+NaN). frame_cache.put() zapisuje teraz ramkę jako string (warstwa i tak wyszukuje po tekście). Dodatkowo warmup() jest odporny: pojedynczy uszkodzony plik nie blokuje startu usługi. 2. Brakowało kroku instalacji zależności — dev-logic/dev-presentation padały na 'No module named httpx'. Nowy cel `make install` instaluje zależności WSZYSTKICH warstw do aktywnego venv. README zaktualizowane (instalowało wcześniej tylko warstwę danych). 3. `make up` zakładał `docker compose`, którego użytkownik nie ma. Makefile wykrywa `docker compose` lub `docker-compose`, a przy braku obu podaje czytelną instrukcję trybu lokalnego. Dodano `make test` i `make clean-cache`. Zweryfikowane end-to-end na realnym środowisku (.env, Python 3.14) i danych: warmup przechodzi (3 pliki), cały stos wstaje, formularz → logika → silnik Skyfield zwraca poprawne pozycje. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
76 lines
4.4 KiB
Markdown
76 lines
4.4 KiB
Markdown
# astrololo
|
||
|
||
Aplikacja w **modelu trójwarstwowym**, w pełni modułowa: trzy niezależne usługi,
|
||
każda komunikuje się wyłącznie z sąsiadem (nigdy „przez głowę”).
|
||
|
||
```
|
||
┌──────────────────────┐ formularz (w dół) ┌──────────────────────┐ zapytanie (w dół) ┌──────────────────────┐
|
||
│ PREZENTACJA (:8000) │ ───────────────────▶ │ LOGICZNA (:8001) │ ───────────────────▶ │ BAZODANOWA (:8002) │
|
||
│ strona WWW + form │ ◀─────────────────── │ reguły biznesowe │ ◀─────────────────── │ wyszukiwanie danych │
|
||
└──────────────────────┘ wyniki (w górę) └──────────────────────┘ dane (w górę) └──────────────────────┘
|
||
HTML/UI pośrednik + logika Excel(+cache) ▸ SQL
|
||
```
|
||
|
||
Każda warstwa to osobny katalog, osobny `requirements.txt`, osobny `Dockerfile`
|
||
i osobne README. Komunikacja przez HTTP/JSON. Warstwa zna **tylko adres warstwy
|
||
bezpośrednio pod nią** — nic o jej wnętrzu.
|
||
|
||
| Warstwa | Katalog | Zna w dół | Zadanie |
|
||
|--------|---------|-----------|---------|
|
||
| Prezentacji | [`services/presentation`](services/presentation) | `LOGIC_URL` | serwuje stronę, przekazuje formularz, renderuje wyniki |
|
||
| Logiczna | [`services/logic`](services/logic) | `DATA_URL` | reguły biznesowe, tłumaczenie zapytań, opracowanie wyników |
|
||
| Bazodanowa | [`services/data`](services/data) | pliki Excela / SQL | **tylko** wyszukiwanie danych i podanie ich w górę |
|
||
|
||
## Szybki start (Docker)
|
||
```bash
|
||
make sample # przykładowe pliki .xlsx do warstwy bazodanowej
|
||
make up # zbuduj i uruchom 3 warstwy
|
||
# otwórz http://localhost:8000
|
||
```
|
||
|
||
## Szybki start (lokalnie, bez Dockera — zalecane)
|
||
```bash
|
||
python -m venv .env && source .env/bin/activate # venv (jednorazowo)
|
||
make install # zależności WSZYSTKICH warstw
|
||
make sample # opcjonalnie: dane przykładowe
|
||
```
|
||
Potem w 3 osobnych terminalach (w każdym `source .env/bin/activate`):
|
||
```bash
|
||
make dev-data # terminal 1 -> :8002
|
||
make dev-logic # terminal 2 -> :8001
|
||
make dev-presentation # terminal 3 -> :8000 -> http://localhost:8000
|
||
```
|
||
> `make install` instaluje zależności wszystkich trzech warstw do aktywnego venv.
|
||
> Testy silnika: `make test`. Wyczyszczenie cache: `make clean-cache`.
|
||
|
||
## Modułowość — dowód
|
||
- Wymień prezentację (np. na SPA/React) → reszta bez zmian, kontrakt `/api/query` stały.
|
||
- Wymień bazę (Excel → SQL) → prezentacja i logika bez zmian (patrz niżej).
|
||
- Każdą warstwę da się uruchomić, testować i wdrażać osobno.
|
||
|
||
## Wydajność warstwy Excela — cache 4-poziomowy
|
||
Dziś dane to setki dużych `.xlsx`, przeszukiwanych po **wykrytym nagłówku** i
|
||
**układzie kolumn**. To kosztowne, więc warstwa bazodanowa ma cache (szczegóły:
|
||
[`services/data/README.md`](services/data/README.md)):
|
||
|
||
1. **Schemat (L1, SQLite)** — wykryty nagłówek + mapowanie kolumn zapisane raz na wersję pliku.
|
||
2. **Dane (L2, Parquet)** — znormalizowany arkusz; kolejne odczyty 10–100× szybsze niż `.xlsx`.
|
||
3. **Zapytania (L3, in-memory TTL/LRU)** — powtarzalne wyszukiwania natychmiast (łatwo podmienić na Redis).
|
||
4. **Odwrócony indeks (L4, SQLite)** — `wartość → plik`; otwieramy tylko trafione pliki zamiast skanu setek.
|
||
|
||
Unieważnianie automatyczne: klucz cache = **odcisk pliku** (`mtime+rozmiar`,
|
||
opcjonalnie `sha256`). Zmiana pliku → przebudowa tylko jego wpisów.
|
||
|
||
## Droga na przyszłość — migracja do SQL
|
||
Warstwa bazodanowa ukrywa źródło za interfejsem `DataProvider` (wzorzec
|
||
Repository). Migracja:
|
||
|
||
```bash
|
||
make migrate # ETL: tym samym loaderem Excel -> tabela 'records' + indeksy
|
||
export DATA_PROVIDER=sql # przełącz całą warstwę
|
||
```
|
||
|
||
`SqlDataProvider` realizuje ten sam kontrakt `/search`, więc **warstwa logiczna i
|
||
prezentacji nie zmieniają ani jednej linii**. Odwrócony indeks z L4 (SQLite) jest
|
||
już pomostem — rozbudowa o wszystkie kolumny = docelowa baza.
|