Zarządzanie plikami baz: trzy poziomy dostępu (DAN-27) #69

Merged
gitea merged 1 commits from feat/zarzadzanie-plikami into master 2026-08-09 20:45:39 +00:00
Owner

Ekran „Pliki", wpięty w kontrolę dostępu z PRE-27.

poziom co może
files widzi listę, klikaniem decyduje, z których baz program korzysta
files_input + wgrywanie, + archiwizacja
administrator + kasowanie, + przywracanie z archiwum, + reguły walidacji

Stan jest teraz trwały

DAN-15 trzymał go w zmiennej DISABLED_BASES, bo warstwa danych nie miała gdzie zapisywać — udział był montowany read-only. Skoro stan ma być klikany, musi przetrwać restart: udział jest zapisywalny, a stan leży w pliku obok baz (zapis atomowy — plik opisuje cały zbiór, więc obcięcie w połowie skasowałoby wiedzę o wszystkich naraz).

DISABLED_BASES zostaje jako awaryjne wyłączenie z konfiguracji i odsiewa dodatkowo — nie odwrotnie, bo inaczej ktoś z dostępem do ekranu włączyłby bazę wyłączoną świadomie na poziomie wdrożenia.

Archiwizacja nie kasuje

Plik zostaje na dysku, zamrożony, ze znacznikiem czasu; znika wyłącznie z użytku. To najdalej idąca operacja osoby wgrywającej dane. Test sprawdza wprost, że plik po archiwizacji nadal istnieje — bo to jest cała istota tej operacji.

Walidacja jest bramką do użytku, nie filtrem na wejściu

Plik wgrany zostaje niezależnie od wyniku — nie tracimy niczego, co ktoś wgrał. Zmienia się tylko to, czy da się go włączyć. Sprawdzenie biegnie też w chwili włączania, nie tylko przy wgrywaniu: reguły mogą się zmienić po fakcie.

Reguły ustawiane z ekranu: dozwolone rozszerzenia, maksymalny rozmiar, minimalna liczba wierszy, wymagane kolumny (sprawdzane w środku arkusza), odrzucanie duplikatów po sha256.

O walidacji wie tylko administrator

  • pliki wstrzymane są odsiewane w warstwie danych przy for_admin=False, nie ukrywane w szablonie — gdyby dochodziły do przeglądarki, wystarczyłby podgląd źródła, żeby poznać reguły
  • odmowa włączenia wraca do konta bez uprawnień bez powodu, bo powód zdradza regułę
  • sekcja reguł nie trafia nawet do źródła strony

Test parametryzowany po obu niższych poziomach szuka w odpowiedzi śladów mechanizmu (walidacj, reguł, nazwy wymaganych kolumn, komunikaty odrzucenia) i wymaga, żeby żadnego nie było.

Groundwork pod krok drugi

Każdy plik ma policzony sha256 — tożsamość niezależna od nazwy. Wykorzystuje ją już odrzucanie duplikatów, a w kroku drugim posłuży do pilnowania zgodności lustra w SQL.

Przy okazji

Naprawiony błąd, który dopiero co bym wprowadził: Path("") to Path("."), czyli wartość prawdziwa, więc Path(os.getenv(...)) or domyślna zawsze wybierało pustą zmienną i zapisywało stan do katalogu bieżącego.

⚠️ Wymaga zapisywalnego udziału — osobny PR w repo deploy (gałąź feat/pliki-zapis). Opisany tam świadomy koszt: znika jedna warstwa obrony w głąb.

Weryfikacja

15 testów rdzenia w warstwie danych + 12 testów trzech poziomów w prezentacji. Suity: dane 28, prezentacja 299, logika 342, render 41.

🤖 Generated with Claude Code

Ekran **„Pliki"**, wpięty w kontrolę dostępu z PRE-27. | poziom | co może | |---|---| | `files` | widzi listę, **klikaniem** decyduje, z których baz program korzysta | | `files_input` | + wgrywanie, + **archiwizacja** | | administrator | + kasowanie, + przywracanie z archiwum, + **reguły walidacji** | ## Stan jest teraz trwały DAN-15 trzymał go w zmiennej `DISABLED_BASES`, bo warstwa danych nie miała gdzie zapisywać — udział był montowany read-only. Skoro stan ma być klikany, musi przetrwać restart: udział jest zapisywalny, a stan leży w pliku obok baz (zapis atomowy — plik opisuje *cały* zbiór, więc obcięcie w połowie skasowałoby wiedzę o wszystkich naraz). `DISABLED_BASES` zostaje jako awaryjne wyłączenie z konfiguracji i odsiewa **dodatkowo** — nie odwrotnie, bo inaczej ktoś z dostępem do ekranu włączyłby bazę wyłączoną świadomie na poziomie wdrożenia. ## Archiwizacja nie kasuje Plik zostaje na dysku, **zamrożony, ze znacznikiem czasu**; znika wyłącznie z użytku. To najdalej idąca operacja osoby wgrywającej dane. Test sprawdza wprost, że plik po archiwizacji nadal istnieje — bo to jest cała istota tej operacji. ## Walidacja jest bramką do użytku, nie filtrem na wejściu Plik wgrany zostaje **niezależnie od wyniku** — nie tracimy niczego, co ktoś wgrał. Zmienia się tylko to, czy da się go włączyć. Sprawdzenie biegnie też **w chwili włączania**, nie tylko przy wgrywaniu: reguły mogą się zmienić po fakcie. Reguły ustawiane z ekranu: dozwolone rozszerzenia, maksymalny rozmiar, minimalna liczba wierszy, wymagane kolumny (sprawdzane w środku arkusza), odrzucanie duplikatów po `sha256`. ## O walidacji wie tylko administrator - pliki wstrzymane są odsiewane **w warstwie danych** przy `for_admin=False`, nie ukrywane w szablonie — gdyby dochodziły do przeglądarki, wystarczyłby podgląd źródła, żeby poznać reguły - odmowa włączenia wraca do konta bez uprawnień **bez powodu**, bo powód zdradza regułę - sekcja reguł nie trafia nawet do źródła strony Test parametryzowany po obu niższych poziomach szuka w odpowiedzi śladów mechanizmu (`walidacj`, `reguł`, nazwy wymaganych kolumn, komunikaty odrzucenia) i wymaga, żeby żadnego nie było. ## Groundwork pod krok drugi Każdy plik ma policzony **`sha256`** — tożsamość niezależna od nazwy. Wykorzystuje ją już odrzucanie duplikatów, a w kroku drugim posłuży do pilnowania zgodności lustra w SQL. ## Przy okazji Naprawiony błąd, który dopiero co bym wprowadził: `Path("")` to `Path(".")`, czyli wartość **prawdziwa**, więc `Path(os.getenv(...)) or domyślna` zawsze wybierało pustą zmienną i zapisywało stan do katalogu bieżącego. ⚠️ **Wymaga zapisywalnego udziału** — osobny PR w repo `deploy` (gałąź `feat/pliki-zapis`). Opisany tam świadomy koszt: znika jedna warstwa obrony w głąb. ## Weryfikacja 15 testów rdzenia w warstwie danych + 12 testów trzech poziomów w prezentacji. Suity: dane 28, prezentacja 299, logika 342, render 41. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
gitea added 1 commit 2026-08-07 12:40:18 +00:00
feat(dane): interfejs zarządzania plikami baz — trzy poziomy dostępu (DAN-27)
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m12s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m33s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 19s
Testy / Kontrola składni wszystkich warstw (push) Successful in 8s
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 12m25s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m33s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 16s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
6466ab89a9
Ekran „Pliki" z trzema poziomami, wpiętymi w kontrolę dostępu z PRE-27:

  „files"        widzi listę i KLIKANIEM decyduje, z których baz program korzysta,
  „files_input"  dokłada wgrywanie i ARCHIWIZACJĘ,
  administrator  kasowanie, przywracanie z archiwum i REGUŁY WALIDACJI.

STAN JEST TERAZ TRWAŁY. DAN-15 trzymał go w zmiennej DISABLED_BASES, bo warstwa
danych nie miała gdzie zapisywać — udział był montowany read-only. Skoro stan ma
być klikany, musi przetrwać restart, więc udział jest zapisywalny, a stan leży
w pliku obok baz (zapis atomowy: plik opisuje CAŁY zbiór, więc obcięcie w połowie
skasowałoby wiedzę o wszystkich naraz). DISABLED_BASES zostaje jako awaryjne
wyłączenie z konfiguracji i odsiewa DODATKOWO — nie odwrotnie, bo inaczej ktoś
z dostępem do ekranu włączyłby bazę wyłączoną świadomie na poziomie wdrożenia.

ARCHIWIZACJA NIE KASUJE. Plik zostaje na dysku, zamrożony, ze znacznikiem czasu;
znika wyłącznie z użytku. To najdalej idąca operacja osoby wgrywającej dane —
kasować może tylko administrator. Test sprawdza, że plik po archiwizacji nadal
istnieje, bo to jest cała istota tej operacji.

WALIDACJA JEST BRAMKĄ DO UŻYTKU, NIE FILTREM NA WEJŚCIU. Plik wgrany zostaje
NIEZALEŻNIE od wyniku — nie tracimy niczego, co ktoś wgrał. Zmienia się tylko to,
czy da się go włączyć. Sprawdzenie biegnie też w chwili włączania, nie tylko przy
wgrywaniu: reguły mogą się zmienić po fakcie.

O WALIDACJI WIE TYLKO ADMINISTRATOR. Pliki wstrzymane są odsiewane W WARSTWIE
DANYCH przy for_admin=False, a nie ukrywane w szablonie — gdyby dochodziły do
przeglądarki, wystarczyłby podgląd źródła, żeby poznać reguły. Odmowa włączenia
wraca do konta bez uprawnień BEZ POWODU, bo powód zdradza regułę. Sekcja reguł
nie trafia nawet do źródła strony. Test parametryzowany po obu niższych poziomach
szuka w odpowiedzi śladów mechanizmu i wymaga, żeby żadnego nie było.

Każdy plik ma policzony sha256 — tożsamość niezależna od nazwy. Wykorzystuje ją
już odrzucanie duplikatów, a w kroku drugim posłuży do pilnowania zgodności
lustra w SQL.

Przy okazji naprawiony błąd, który dopiero co bym wprowadził: Path("") to
Path("."), czyli wartość PRAWDZIWA, więc `Path(os.getenv(...)) or domyślna`
zawsze wybierało pustą zmienną i zapisywało stan do katalogu bieżącego.

Wymaga zapisywalnego udziału — osobny PR w repo deploy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gitea added 1 commit 2026-08-09 09:59:02 +00:00
fix(dane): bazy zastane na udziale zostają w użyciu po przejściu na rejestr
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m57s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m39s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m44s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 40s
Testy / Kontrola składni wszystkich warstw (push) Successful in 16s
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 11m26s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Failing after 3h18m22s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 12m9s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 51s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 16s
a299cdad3c
Bez tego wdrożenie DAN-27 WYŁĄCZYŁOBY WYSZUKIWANIE. Dotąd bazy działały domyślnie
(wyłączało się je jawnie przez DISABLED_BASES). Po przejściu na rejestr plik bez
wpisu w stanie dostaje `ready`, czyli NIE w użyciu — a stan po wdrożeniu jest
pusty. Efekt: żadna baza nie jest aktywna i program nagle niczego nie znajduje.

Ta cicha zmiana zachowania byłaby gorsza od awarii, bo wygląda jak pusta baza,
a nie jak zepsuty deploy — i szukałoby się jej w warstwie danych albo w indeksie.

Teraz brak PLIKU stanu oznacza pierwsze uruchomienie i bazy zastane są przyjmowane
jako aktywne. Pusty słownik przy ISTNIEJĄCYM pliku to co innego: ktoś świadomie
wszystko odstawił, więc nie wskrzeszamy — osobny test tego pilnuje.

Rozróżnienie jest celowe i też pod testem: `ready` dotyczy plików WGRANYCH przez
ekran (te ktoś musi świadomie włączyć), a nie zastanych przy przejściu na rejestr.
Inaczej nowa baza wchodziłaby do wyników sama, bez niczyjej decyzji.

Przyjęcie działa też na udziale tylko do odczytu: zapis stanu wtedy nie przechodzi,
więc powtórzy się przy każdym uruchomieniu — zachowanie to samo, koszt żaden.

Dwa testy opisujące STARE zachowanie zostały poprawione, bo to one były błędne.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gitea merged commit b838cf4723 into master 2026-08-09 20:45:39 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gitea/astrololo#69