mirror of
https://github.com/migatu/astrololo.git
synced 2026-07-14 13:34:38 +00:00
16d35c16dc
Trzy niezależne usługi FastAPI komunikujące się przez HTTP/JSON, każda zna tylko adres warstwy bezpośrednio pod nią: - presentation (:8000) — strona WWW + formularz - logic (:8001) — reguły biznesowe, pośrednik - data (:8002) — wyszukiwanie danych za interfejsem DataProvider Warstwa danych: czytanie setek plików .xlsx z wykrywaniem nagłówka i mapowaniem układu kolumn na schemat kanoniczny, z 4-poziomowym cache (schemat L1, Parquet L2, wyniki zapytań L3, odwrócony indeks L4) i unieważnianiem po odcisku pliku. Gotowa ścieżka migracji do SQL (ingest/to_sql.py + SqlDataProvider, przełączane przez DATA_PROVIDER). Zawiera docker-compose, Makefile, generator danych przykładowych. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
44 lines
1.6 KiB
Python
44 lines
1.6 KiB
Python
"""Logika biznesowa — serce warstwy logicznej.
|
|
|
|
Tu (a nie w prezentacji ani w bazie) żyją reguły: walidacja/normalizacja danych
|
|
z formularza, tłumaczenie zapytania użytkownika na znormalizowane zapytanie do
|
|
bazy, oraz opracowanie/wzbogacenie wyników w drodze w górę.
|
|
|
|
To jest miejsce do rozbudowy o właściwą domenę (obliczenia, reguły, agregacje).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from app.clients.data_client import DataClient
|
|
from app.models import QueryRequest, QueryResponse
|
|
|
|
|
|
class QueryService:
|
|
def __init__(self, data_client: DataClient | None = None) -> None:
|
|
self.data = data_client or DataClient()
|
|
|
|
def handle(self, req: QueryRequest) -> QueryResponse:
|
|
# 1) normalizacja wejścia z formularza (reguła biznesowa)
|
|
value = req.query.strip()
|
|
key = req.field.strip().lower()
|
|
|
|
# 2) zapytanie w dół do warstwy bazodanowej
|
|
raw = self.data.search(key=key, value=value, exact=req.exact, limit=req.limit)
|
|
|
|
# 3) opracowanie wyników w górę (tu można liczyć/wzbogacać/sortować)
|
|
results = raw.get("rows", [])
|
|
results = sorted(results, key=lambda r: str(r.get(key, "")))
|
|
|
|
return QueryResponse(
|
|
status="ok",
|
|
query=value,
|
|
count=len(results),
|
|
results=results,
|
|
meta={
|
|
"field": key,
|
|
"exact": req.exact,
|
|
"data_cache": raw.get("cache"),
|
|
"data_provider": raw.get("provider"),
|
|
"data_elapsed_ms": raw.get("elapsed_ms"),
|
|
},
|
|
)
|