mirror of
https://github.com/migatu/astrololo.git
synced 2026-07-18 13:02:10 +00:00
Szkielet aplikacji trójwarstwowej (prezentacja / logika / dane)
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>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
"""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"),
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user