Skip to content

Panel: dzieci i urządzenia domu - #86

Merged
mbeczynski merged 3 commits into
mainfrom
feat/ekran-urzadzenia
Oct 23, 2026
Merged

mbeczynski merged 3 commits into
mainfrom
feat/ekran-urzadzenia

Conversation

@mbeczynski

Copy link
Copy Markdown
Contributor

Co

Ekran Ustawienia → Dzieci i urządzenia (uprawnienie dom.urzadzenia, dotąd nieużywane): właściciel domu i zarządca sami dodają, zmieniają i usuwają dzieci i urządzenia swojego domu. Administrator instalacji ma to samo w każdym domu.

  • API: GET /api/domy/<id>/urzadzenia, POST /api/domy/<id>/urzadzenia/zapisz (src/kidwatch/panel_urzadzenia.py, trasy w panel.py, prefiks domu w web/src/utils/domy.js).
  • Rola domu zmienia: nazwę, dziecko, rodzaj (ipad, iphone, phone-android; bez tv), source_ids („Nazwa w NextDNS”), nextdns_profile.
  • udid, host, unifi_mac, unifi_ip, mdm, ustawienia (known_apps): ustawia administrator instalacji. Rola domu widzi tylko flagi („ustawione przez administratora”), nie może ich wysłać (403), a zapis przepisuje je z bazy bez zmian. Wiersze dopasowane po urzadzenia.id, więc zmiana nazwy nie gubi UDID-u.
  • Urządzenia z polami administratora usuwa tylko administrator: usunięcie odpięłoby iPada od MDM i od odczytu wprost.
  • Telewizor (rodzaj='tv') nie jest pokazywany i nie jest zmieniany. Ustawienia domu, strefa, integracje, sekrety i dozwolone_sieci też zostają bez zmian, co sprawdza się po zapisie w tej samej transakcji.
  • Front: web/src/components/DzieciUrzadzenia.jsx (pod Zaproszeniami, nad Integracjami), web/src/utils/urzadzenia.js. Dla Androida ekran wylicza host Prywatnego DNS (Nazwa--z--myslnikami-<ID profilu>.dns.nextdns.io) z przyciskiem „Kopiuj”. Zapis wymaga hasła albo 2FA. Po zapisie ekran pokazuje stan domu (reloadNotice, także pole czeka).

Dlaczego

Do tej pory zaproszony właściciel domu nie mógł sam dopisać dziecka ani telefonu. Administrator robił to plikiem i dom-importuj N --plik przez kubectl cp (runbook nowy-dom.md, pkt 4).

Rozstrzygnięcia

  • UDID i adresy: wartości widzi tylko aktywny administrator instalacji (ctx.admin). W odpowiedzi dla roli domu są tylko flagi, a audyt zapisuje liczby i nazwy pól. Komunikaty błędów dla roli domu przechodzą przez filtr, który wycina UDID-y i adresy domu.
  • Ostatnie urządzenie: zasada jak w integracjach. Zmiana, po której dom zdolny do startu przestałby startować, jest wycofywana. Działający dom, także Dom 1, nie zostanie bez urządzeń: nadzorca uznałby to za awarię i wróciłby do ostatniej dobrej kopii, czyli dalej pilnowałby usuniętych urządzeń. Dom, który i tak nie startuje (świeży, bez NextDNS, „czeka na konfigurację” z Domy: start kolejnych domów obok Domu 1 #84), można uzupełniać i czyścić w dowolnej kolejności.
  • Walidacja: home_z_danych z bieżącymi integracjami i sekretami domu, czyli tymi samymi walidatorami co config.yaml. Dom bez źródła DNS dostaje atrapę źródła tylko na czas walidacji, jak w importuj_strukture. Kolejność kroków: zapis, odczyt, porównanie (wiersze, porownaj HomeConfig, integracje, TV, wiersz domy). Wszystko w jednej transakcji; błąd daje 400 i baza zostaje bez zmian.
  • Współbieżność: pole wersja jest obowiązkowe, inna wartość daje 409 „odśwież”. Zapis podbija domy.wersja, a nadzorca (Domy: start kolejnych domów obok Domu 1 #84) przeładowuje dom.
  • Audyt: dom.urzadzenia.zapis (dodane / zmienione / usunięte, nazwy pól) i dom.urzadzenia.odmowa. Administrator bez członkostwa dostaje dodatkowo admin.urzadzenia.zapisz przez _wymaga.
  • Adres iPada (host) wpisany przez administratora przechodzi przez strażnika sieci domu (port lockdown), z tą samą podpowiedzią dom-sieci co w integracjach.
  • Dziecko bez urządzenia jest odrzucane, bo konfiguracja domu wywodzi dzieci z urządzeń.

Testy

  • tests/test_urzadzenia_panel.py (23 testy):
    • dostęp: wlasciciel-domu i zarzadca 200, podglad 403, obcy dom 404, flaga administratora bez grupy 404, administrator bez członkostwa z admin.*;
    • Dom w trybie yaml daje 409, złe potwierdzenie 403, brak wersji 400, nieaktualna wersja 409;
    • zła walidacja (także walidator _profiles_need_nextdns) daje 400 bez zmian w bazie;
    • zamiana nazw dzieci i urządzeń w jednym zapisie (UNIQUE), ostatnie urządzenie, świeży dom;
    • strażnik sieci dla host;
    • pola administratora przetrwają zmianę nazwy, rola domu nie wyśle ich ani nie usunie chronionego urządzenia;
    • integracje i sekrety bez zmian, kanarki sekretów nigdzie (odpowiedź, log, audyt, plik bazy).
  • Dom 1 na kształcie produkcji (dom1 z test_domy_e2: UDID, host, known_apps, UniFi, TV, ntfy, HA, MDM, tryb baza): właściciel zmienia nazwę iPada i jego source_ids. porownaj(HomeConfig przed, po) daje dokładnie devices[0].display_name i devices[0].source_ids. UDID, host, MAC, known_apps, TV, integracje, sekrety i ustawienia domu zostają bez zmian, a w odpowiedzi i w audycie nie ma UDID-u ani adresów.
  • Kanarki (python -B, -p no:cacheprovider): każde z 9 zabezpieczeń odwrócono osobno i za każdym razem odpowiedni test padał. Sprawdzone zabezpieczenia: pola administratora z bazy, wartości techniczne tylko dla administratora, wersja, sprawdzenie startu, ochrona przed usunięciem, strażnik, ukrycie TV, 403 dla pól technicznych, walidacja modelem.
  • web/src/utils/urzadzenia.test.js: host Prywatnego DNS, walidacja formularza, ciało zapisu.
  • uv run pytest -q, uv run ruff check, npm --prefix web test, npm --prefix web run build: wszystko zielone.

Wdrożenie i wycofanie

  • Baza PR to feat/dom-importuj-struktura (dom-importuj: struktura kolejnego domu z pliku #85), trzeba scalić po nim. Bez migracji schematu: korzysta z istniejących tabel dzieci i urzadzenia.
  • Po wdrożeniu właściciele domów (wlasciciel-domu, zarzadca) od razu widzą nowy ekran. Dla Domu 1 działa tylko w trybie baza; w trybie yaml ekran zwraca 409.
  • Wycofanie: revert commita. Dane zapisane z panelu zostają w tabelach i są dalej czytane przez home_z_danych, a dom-importuj --plik dalej działa i nadpisuje strukturę.

🤖 Generated with Claude Code

Wlasciciel domu i zarzadca dodaja, zmieniaja i usuwaja dzieci i urzadzenia
swojego domu w Ustawieniach, zamiast administratora z `dom-importuj --plik`.
Administrator instalacji ma to samo w kazdym domu (wpis admin.* w audycie).

- GET /api/domy/<id>/urzadzenia, POST .../urzadzenia/zapisz (uprawnienie
  dom.urzadzenia; podglad 403, obcy dom 404, dom yaml 409).
- Wiersze dopasowane po id: zmiana nazwy nie gubi UDID-u. UDID, adres, MAC,
  MDM i lista aplikacji ustawia administrator; rola domu widzi tylko flagi,
  a zapis przepisuje te pola z bazy bez zmian. Telewizor poza ekranem.
- Walidacja walidatorami config.yaml (HomeConfig z integracjami i sekretami
  domu), zapis -> odczyt -> porownanie w jednej transakcji, wersja domu
  obowiazkowa (409), dzialajacy dom nie traci ostatniego urzadzenia.
- Front: ekran z hostem Prywatnego DNS dla Androida, potwierdzenie haslem
  albo 2FA, stan przeladowania domu po zapisie.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mbeczynski
mbeczynski changed the base branch from feat/dom-importuj-struktura to main October 23, 2026 08:46
mbeczynski and others added 2 commits October 23, 2026 10:54
- nextdns_profile ustawia tylko administrator instalacji (obcy profil
  czytalby kluczem API domu cudze logi); rola domu widzi go do odczytu,
  zapis przepisuje go z bazy, nowe urzadzenie dziedziczy profil dziecka.
- Zmiana imienia dziecka (po id) przemapowuje w tej samej transakcji
  zakresy powiadomien czlonkow domu (z lustrem Domu 1), oczekujace zadania
  czasu gry i kody komend z WhatsAppa; usuniecie dziecka jedynego w czyims
  zakresie = 400, w pozostalych imie zdjete.
- Blad startu i przeladowania dla roli domu bez UDID-ow i adresow (takze
  TV i integracji); log odmowy bez wartosci; 403 za pola administratora
  z wpisem dom.urzadzenia.odmowa.
- DNS adresu iPada rozwiazywany przed BEGIN IMMEDIATE.
- Front: nazwa do Prywatnego DNS bez "-" na brzegu slowa i bez "--".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mbeczynski
mbeczynski merged commit f22b571 into main Oct 23, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant