refactor: astroklient → astroklient-demo

Nazwa `astroklient` zostaje zarezerwowana dla przyszłej wersji produkcyjnej
programu; obecna, demonstracyjna nazywa się od teraz `astroklient-demo`.

Zmiana obejmuje katalog usługi, nazwę pliku testów, obraz w rejestrze
(astrololo-astroklient-demo), job w CI, pętlę budowania obrazów, tytuł i nagłówek
strony, nazwy loggerów, realm logowania, pole `layer` w /health oraz wymagania
PRE-28/29 w xlsx.

DWIE PUŁAPKI PODMIANY, obie sprawdzone po fakcie:

Zdublowany przyrostek. `astroklient-demo` zawiera `astroklient`, więc powtórna
podmiana dałaby `astroklient-demo-demo`. Sprawdziłem najpierw, że nigdzie nie ma
jeszcze nowej nazwy, i dopiero wtedy podmieniłem raz.

Polska odmiana. Ślepa podmiana zamieniła „astroklienta" na „astroklient-demoa”
w czterech miejscach; poprawione na „astroklienta-demo". Tytuł FastAPI wyszedłby
jako „astroklient-demo · demo", a nazwa jobu jako „Testy astroklienta-demo
(wersja demo)" — oba skrócone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 23:36:55 +02:00
parent caf4fd80d1
commit 16cf25468f
17 changed files with 30 additions and 30 deletions
@@ -1,4 +1,4 @@
# astroklient — wersja demonstracyjna (PRE-28)
# astroklient-demo — wersja demonstracyjna (PRE-28)
Osobna warstwa prezentacji o **dwóch funkcjach**:
@@ -18,7 +18,7 @@ okazji kodu reszty programu.
## Izolacja: własne dane, pula na konto
```
astroklient → logic-demo → data-demo → udział astrololo-demo (pusty na starcie)
astroklient-demo → logic-demo → data-demo → udział astrololo-demo (pusty na starcie)
└── klientA/ ← pula konta
└── klientB/ ← pula konta
```
@@ -42,7 +42,7 @@ w nazwie katalogu: `../..` czy ukośnik wyprowadziłyby zapytanie poza udział.
**Pula klienta to jeden katalog**, więc przejście na pełną wersję nie oznacza
utraty wgrań — procedura importu jest w runbooku wdrożenia (repo `deploy`,
`astrololo/README-astroklient.md`).
`astrololo/README-astroklient-demo.md`).
## Konfiguracja
@@ -66,7 +66,7 @@ cd services/presentation && python scripts/make_user.py demo
## Uruchomienie lokalne
```bash
cd services/astroklient
cd services/astroklient-demo
pip install -r requirements-dev.txt
DEMO_PASSWORD=tajne LOGIC_URL=http://localhost:8001 \
uvicorn app.main:app --port 8005
@@ -75,7 +75,7 @@ DEMO_PASSWORD=tajne LOGIC_URL=http://localhost:8001 \
Testy:
```bash
cd services/astroklient && PYTHONPATH=. pytest tests -q
cd services/astroklient-demo && PYTHONPATH=. pytest tests -q
```
## Co pilnują testy
@@ -45,7 +45,7 @@ class LogicClient:
def report(self, when_utc_iso: str, lat: float, lon: float) -> dict[str, Any]:
"""Interpretacja urodzeniowa: sygnifikatory z obliczeń szukane w bazach.
Jedyne pytanie, jakie astroklient zadaje o treść bez grupowania,
Jedyne pytanie, jakie astroklient-demo zadaje o treść bez grupowania,
bez promptów, bez modelu językowego."""
payload = {"when_utc": when_utc_iso, "lat": lat, "lon": lon,
"limit": settings.report_limit, "group": False,
@@ -1,4 +1,4 @@
"""Konfiguracja astroklienta — wersji demonstracyjnej (PRE-28).
"""Konfiguracja astroklienta-demo — wersji demonstracyjnej (PRE-28).
Zna WYŁĄCZNIE adres warstwy logicznej, tak samo jak pełna prezentacja. Nie wie
nic o bazach, Excelu ani SQL-u.
@@ -1,4 +1,4 @@
"""astroklient — wersja DEMONSTRACYJNA (PRE-28).
"""astroklient-demo — wersja DEMONSTRACYJNA (PRE-28).
DWIE FUNKCJE I ANI JEDNEJ WIĘCEJ:
1. dodanie pliku bazy (wgranie + włączenie do użytku),
@@ -10,7 +10,7 @@ Tutaj pozostałych funkcji NIE MA W OBRAZIE: nie ma tras, nie ma szablonów, nie
nawet metod w kliencie warstwy logicznej. Demo można komuś oddać, nie oddając
przy okazji kodu reszty programu.
UWAGA, ŚWIADOMA DECYZJA WŁAŚCICIELA: astroklient pracuje na TEJ SAMEJ warstwie
UWAGA, ŚWIADOMA DECYZJA WŁAŚCICIELA: astroklient-demo pracuje na TEJ SAMEJ warstwie
danych co produkcja. Kto ma do niego dostęp, czyta oryginalne bazy interpretacyjne,
a pliki przez niego wgrane trafiają do produkcyjnego zbioru. Dlatego konto jest
osobne (DEMO_USER/DEMO_PASSWORD) żeby dało się odciąć demo jedną zmienną, bez
@@ -32,7 +32,7 @@ from app.clients.logic_client import LogicClient
# Automatyczna dokumentacja WYŁĄCZONA — tak samo jak w pełnej aplikacji. /docs
# wypisałoby komplet tras, a demo ma nie zdradzać nawet własnej powierzchni.
app = FastAPI(title="astroklient · demo", docs_url=None, redoc_url=None, openapi_url=None)
app = FastAPI(title="astroklient-demo", docs_url=None, redoc_url=None, openapi_url=None)
security.install(app)
app.mount("/static", StaticFiles(directory="app/static"), name="static")
@@ -48,7 +48,7 @@ def _logic(request: Request) -> LogicClient:
return LogicClient(tenant=getattr(request.state, "user", "") or "")
# Stan pliku „w użyciu" — ta sama nazwa, co w warstwie danych (DAN-27). Wpisana
# tutaj wprost, bo astroklient nie importuje tamtej warstwy; literówka objawiłaby
# tutaj wprost, bo astroklient-demo nie importuje tamtej warstwy; literówka objawiłaby
# się dopiero na żywo, więc pilnuje jej test.
ACTIVE = "active"
@@ -152,4 +152,4 @@ def _wroc(error: str = "", done: str = "") -> RedirectResponse:
@app.get("/health")
def health() -> dict:
return {"status": "ok", "layer": "astroklient"}
return {"status": "ok", "layer": "astroklient-demo"}
@@ -1,4 +1,4 @@
"""Logowanie do astroklienta (PRE-28).
"""Logowanie do astroklienta-demo (PRE-28).
OSOBNE KONTO, NIE WSPÓŁDZIELONE Z GŁÓWNĄ APLIKACJĄ. Demo pracuje na tej samej
warstwie danych co produkcja, więc kto ma do niego dostęp, czyta oryginalne bazy
@@ -26,8 +26,8 @@ from collections import deque
from fastapi import Request
from fastapi.responses import HTMLResponse, JSONResponse
log = logging.getLogger("astroklient.security")
audit_log = logging.getLogger("astroklient.audit")
log = logging.getLogger("astroklient-demo.security")
audit_log = logging.getLogger("astroklient-demo.audit")
_SCRYPT_N, _SCRYPT_R, _SCRYPT_P, _SCRYPT_LEN = 2**14, 8, 1, 32
_HASH_PREFIX = "scrypt$"
@@ -163,7 +163,7 @@ def install(app) -> None:
_setup_audit_logging()
if not auth_enabled():
log.warning(
"UWAGA: brak kont (DEMO_USERS / DEMO_PASSWORD) — astroklient stoi OTWARTY. "
"UWAGA: brak kont (DEMO_USERS / DEMO_PASSWORD) — astroklient-demo stoi OTWARTY. "
"Bez logowania nie ma też PULI: wszyscy pracowaliby na jednym, wspólnym "
"zbiorze baz, widząc nawzajem swoje wgrania."
)
@@ -184,7 +184,7 @@ def install(app) -> None:
if not user:
return HTMLResponse(
"<h1>401 — wymagane logowanie</h1>", status_code=401,
headers={"WWW-Authenticate": 'Basic realm="astroklient"'})
headers={"WWW-Authenticate": 'Basic realm="astroklient-demo"'})
request.state.user = user
response = await call_next(request)
@@ -1,4 +1,4 @@
/* astroklient arkusz CELOWO minimalny. Nie kopiujemy stylów pełnej aplikacji:
/* astroklient-demo arkusz CELOWO minimalny. Nie kopiujemy stylów pełnej aplikacji:
demo ma dwa formularze i tabelę wyników, a każda przeniesiona klasa niosłaby
nazwy funkcji, których tu nie ma. */
:root {
@@ -3,13 +3,13 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>astroklient · {% block title %}{% endblock %}</title>
<title>astroklient-demo · {% block title %}{% endblock %}</title>
<link rel="stylesheet" href="/static/styles.css">
</head>
<body>
<main>
<header class="topbar">
<h1>astroklient</h1>
<h1>astroklient-demo</h1>
{# CELOWO BEZ NAWIGACJI. Dwie funkcje mieszczą się na jednym ekranie,
a pasek zakładek z jedną pozycją tylko sugerowałby, że są inne. #}
</header>
@@ -1,4 +1,4 @@
"""astroklient — wersja demonstracyjna (PRE-28).
"""astroklient-demo — wersja demonstracyjna (PRE-28).
DWIE WŁASNOŚCI, KTÓRYCH PILNUJE TEN PLIK
@@ -104,7 +104,7 @@ def test_without_credentials_nothing_is_served(env, monkeypatch):
def test_demo_account_is_separate_from_the_main_application(env, monkeypatch):
"""Konto astroklienta MUSI być własne: demo pracuje na tej samej warstwie
"""Konto astroklienta-demo MUSI być własne: demo pracuje na tej samej warstwie
danych co produkcja, więc odcięcie go nie może wymagać zmiany haseł
w głównej aplikacji."""
monkeypatch.setenv("APP_USER", "astrololo")