feat: przegląd baz na udziale + globalne włączanie/wyłączanie (DAN-15/PRE-09)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m30s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m29s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 12s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 40s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m3s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m35s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m29s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 14s
Testy / Kontrola składni wszystkich warstw (push) Successful in 10s
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m30s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m29s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 12s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 40s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m3s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m35s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m29s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 14s
Testy / Kontrola składni wszystkich warstw (push) Successful in 10s
Wymaganie przedefiniowane pod model serwerowy (#47): nie wybiera się folderu — pliki leżą na stałym NFS. Potrzeba za to WIDZIEĆ, jakie bazy są dostępne i móc zdecydować, które biorą udział w interpretacji. Warstwa danych: `bases.py` (lista plików + metaopis: nazwa, ścieżka, rozmiar, data, stan) i endpoint `/bases`. Wyłączone bazy są ODSIEWANE z kandydatów przy wyszukiwaniu, więc naprawdę nie biorą udziału w interpretacji — nie tylko znikają z listy. Lista wyłączonych wchodzi do klucza cache zapytań: bez tego zmiana ustawień oddawałaby wynik sprzed zmiany, czyli treść bazy uznanej za wyłączoną. `list_bases()` doszło do interfejsu dostawcy jako OPCJONALNE (SQL nie operuje na plikach → pusto, zamiast wywrotki). Przelot logika → prezentacja i ekran „Ustawienia" z tabelą baz. Przez łącze idą SAME METADANE — podgląd listy nie jest kolejną drogą do wyniesienia treści. Stan przełączników jest DEKLARATYWNY (`DISABLED_BASES`), nie klikalny — i to jest świadome: udział z bazami montujemy read-only, a katalog cache to `emptyDir`, więc zapisany przełącznik ginąłby przy restarcie poda i po cichu włączał z powrotem wyłączoną bazę. Ekran mówi wprost, jak wyłączyć bazę i dlaczego nie klikaniem. Tryb klikalny wymagałby dołożenia trwałego wolumenu. Weryfikacja na żywym łańcuchu: `/bases` przechodzi przez SZYFROWANE łącze (logic→data), pokazuje 3 bazy z metaopisem i stanem; wyszukiwanie daje 3 → 2 → 0 wierszy w miarę wyłączania baz. Testy: dane +6, prezentacja +6. Dane 13, logika 277, prezentacja 249. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit was merged in pull request #55.
This commit is contained in:
@@ -152,6 +152,12 @@ class LogicClient:
|
||||
client, f"{self.base_url}/chart/horoscope/stream",
|
||||
payload=payload, headers=_auth_headers(), link=_link())
|
||||
|
||||
def bases(self) -> dict[str, Any]:
|
||||
"""Bazy dostępne na udziale + metaopis i stan włączenia (DAN-15/PRE-09)."""
|
||||
with httpx.Client(timeout=settings.http_timeout) as client:
|
||||
return link_crypto.call_json(client, "GET", f"{self.base_url}/bases",
|
||||
headers=_auth_headers(), link=_link())
|
||||
|
||||
def llm_models(self) -> dict[str, Any]:
|
||||
"""Katalog modeli per dostawca (podpowiedzi do pola wyboru w UI)."""
|
||||
with httpx.Client(timeout=settings.http_timeout) as client:
|
||||
|
||||
@@ -289,6 +289,23 @@ def compile_pdf(payload: dict):
|
||||
headers={"Content-Disposition": 'attachment; filename="raport.pdf"'})
|
||||
|
||||
|
||||
# ---------------- Ustawienia: bazy na udziale (DAN-15/PRE-09) ----------------
|
||||
@app.get("/settings", response_class=HTMLResponse)
|
||||
def settings_view(request: Request):
|
||||
"""Podgląd baz dostępnych na udziale + które biorą udział w interpretacji.
|
||||
|
||||
Same metadane (nazwa, rozmiar, data) — bez treści baz. Przełączniki są
|
||||
DEKLARATYWNE (`DISABLED_BASES`), bo warstwa danych nie ma trwałego zapisu:
|
||||
udział jest read-only, a cache to emptyDir. Zapis do pliku ginąłby po
|
||||
restarcie, po cichu włączając z powrotem wyłączoną bazę."""
|
||||
ctx: dict = {"result": None, "error": None}
|
||||
try:
|
||||
ctx["result"] = logic.bases()
|
||||
except httpx.HTTPError as e:
|
||||
ctx["error"] = _logic_error(e)
|
||||
return templates.TemplateResponse(request, "settings.html", ctx)
|
||||
|
||||
|
||||
# ---------------- Synastria (technika relacyjna) ----------------
|
||||
@app.get("/synastry", response_class=HTMLResponse)
|
||||
def synastry_form(request: Request):
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<a href="/synastry" class="{% block nav_synastry %}{% endblock %}">Synastria</a>
|
||||
<a href="/significators" class="{% block nav_sig %}{% endblock %}">Sygnifikatory</a>
|
||||
<a href="/compile" class="{% block nav_compile %}{% endblock %}">Skompiluj</a>
|
||||
<a href="/settings" class="{% block nav_settings %}{% endblock %}">Ustawienia</a>
|
||||
</nav>
|
||||
</header>
|
||||
{% block content %}{% endblock %}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Ustawienia{% endblock %}
|
||||
{% block nav_settings %}active{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p class="sub">Bazy interpretacyjne dostępne na udziale sieciowym — i to, które biorą udział w interpretacji.</p>
|
||||
|
||||
{% if error %}<div class="error">{{ error }}</div>{% endif %}
|
||||
|
||||
{% if result %}
|
||||
<div class="meta">Bazy na udziale: <strong>{{ result.total }}</strong> ·
|
||||
biorą udział w interpretacji: <strong>{{ result.enabled }}</strong>
|
||||
{% if result.total and result.enabled < result.total %}
|
||||
· wyłączonych: <strong>{{ result.total - result.enabled }}</strong>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if result.bases %}
|
||||
<table>
|
||||
<thead><tr><th>Baza</th><th>Ścieżka</th><th>Rozmiar</th><th>Zmieniono</th><th>W interpretacji</th></tr></thead>
|
||||
<tbody>
|
||||
{% for b in result.bases %}
|
||||
<tr>
|
||||
<td>{{ b.name }}</td>
|
||||
<td class="muted small">{{ b.path }}</td>
|
||||
<td class="mono">{% if b.size_mb is not none %}{{ b.size_mb }} MB{% else %}—{% endif %}</td>
|
||||
<td class="mono">{{ b.modified or '—' }}</td>
|
||||
<td>{% if b.enabled %}tak{% else %}<span class="badge">wyłączona</span>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p class="muted">Na udziale nie widać żadnych baz (albo aktywny dostawca nie operuje na plikach).</p>
|
||||
{% endif %}
|
||||
|
||||
<div class="meta">Jak wyłączyć bazę</div>
|
||||
<p class="muted small">
|
||||
Lista wyłączonych jest <strong>deklaratywna</strong> — trzyma ją zmienna
|
||||
<span class="mono">DISABLED_BASES</span> usługi danych (nazwy plików po przecinku,
|
||||
np. <span class="mono">stara_baza.xlsx,archiwum/testowa.xlsx</span>). Po zmianie
|
||||
zrestartuj warstwę danych.
|
||||
</p>
|
||||
<p class="muted small">
|
||||
Dlaczego nie klikaniem: udział z bazami jest montowany tylko do odczytu, a katalog
|
||||
cache to <span class="mono">emptyDir</span> — zapisany przełącznik ginąłby przy
|
||||
restarcie poda i po cichu włączał z powrotem wyłączoną bazę. Przełączanie z tego
|
||||
ekranu wymagałoby dołożenia trwałego wolumenu.
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user