# astroklient — wersja demonstracyjna (PRE-28) Osobna warstwa prezentacji o **dwóch funkcjach**: 1. **dodanie pliku bazy** — wgranie i włączenie do użytku jedną czynnością, 2. **zapytanie o interpretację urodzeniową** dla podanych danych wejściowych. I na tym koniec. Nie ma tu kosmogramu, synastrii, kalendarza, promptów do modelu, eksportu ani kont — nie są ukryte, tylko **nie istnieją w tym obrazie**. ## Dlaczego osobna usługa, a nie konto z ograniczeniami Mechanizm uprawnień z PRE-27 umiałby to ukryć w pełnej aplikacji. Ale **ukrycie a nieobecność to dwie różne rzeczy**: tutaj nie ma tras, nie ma szablonów, nie ma nawet metod w kliencie warstwy logicznej. Demo można komuś oddać, nie oddając przy okazji kodu reszty programu. ## Izolacja: własne dane, pula na konto ``` astroklient → logic-demo → data-demo → udział astrololo-demo (pusty na starcie) └── klientA/ ← pula konta └── klientB/ ← pula konta ``` **Oryginalne bazy interpretacyjne są dla demo nieosiągalne.** Nie chodzi o uprawnienia: demo ma własną warstwę danych, pracującą na osobnym udziale. Osobna jest też warstwa logiczna, bo zna ona JEDEN adres warstwy danych — demo korzystające z produkcyjnej logiki i tak trafiłoby na produkcyjne bazy. **Każde konto ma własną pulę** plików: swój podkatalog na tym udziale. Konta nie widzą swoich baz nawzajem ani w liście, ani w wynikach wyszukiwania. Dlatego demo można rozdawać szeroko. Pula bierze się **z loginu zalogowanej osoby** i z niczego innego. Gdyby przychodziła z żądania, wystarczyłoby podstawić cudzy login, żeby czytać cudze bazy — osobny test wysyła `tenant`, `user` i `login` w formularzu i sprawdza, że nie mają na nią wpływu. Nazwa puli przechodzi przez sito dopuszczające wyłącznie znaki bezpieczne 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`). ## Konfiguracja | zmienna | znaczenie | |---|---| | `LOGIC_URL` | adres warstwy logicznej (domyślnie `http://localhost:8001`) | | `DEMO_USERS` | konta jako `login:sekret`, po przecinku. Sekret jawny albo hash `scrypt$sól$hash`. Każdy login = osobna pula plików | | `DEMO_USER` / `DEMO_PASSWORD` | pojedyncze konto — zgodność wstecz, działa gdy `DEMO_USERS` jest puste. **Brak obu = aplikacja stoi otwarta** i mówi o tym głośno przy starcie | | `INTERNAL_TOKEN` | token międzywarstwowy (LOG-32) — ten sam co reszta usług | | `LINK_KEY_PRESENTATION_LOGIC` | klucz szyfrowanego łącza (PRE-16) — ten sam co prezentacja | | `RATE_LIMIT_PER_MIN` | limit żądań na adres, domyślnie 60; `0` wyłącza | | `REPORT_LIMIT` | górny limit rekordów w jednej odpowiedzi, domyślnie 2000 | | `TRUST_PROXY` | `true` za Ingressem — inaczej limit liczy wszystkich do jednego wiadra | Hash hasła zrobisz tym samym skryptem, co dla głównej aplikacji: ```bash cd services/presentation && python scripts/make_user.py demo ``` ## Uruchomienie lokalne ```bash cd services/astroklient pip install -r requirements-dev.txt DEMO_PASSWORD=tajne LOGIC_URL=http://localhost:8001 \ uvicorn app.main:app --port 8005 ``` Testy: ```bash cd services/astroklient && PYTHONPATH=. pytest tests -q ``` ## Co pilnują testy Poza zwykłą poprawnością — dwie własności, które łatwo zepsuć bez zauważenia: * **powierzchnia**: zbiór tras aplikacji musi być dokładnie taki, jak dwie funkcje wymagają; klient warstwy logicznej ma tylko te metody, których używa. Trasa, o której nikt nie pamiętał, jest tu realnym ryzykiem, bo ta usługa rozmawia z produkcyjną warstwą danych. * **milczenie o regułach walidacji**: plik odrzucony daje komunikat bez powodu. Reguły zna wyłącznie administrator w pełnej aplikacji (DAN-27), a demo nie ma prawa ich zdradzić nawet mimochodem.