Projekt Baby Monitor Timmy powstał z prostego pomysłu: elektronicznej niani, która szanuje prywatność w domu. Bez nagrań w chmurze i bez niepotrzebnego przesyłania danych poza pokój dziecka. Wiele osób nie wie, że tworzę Timmy samodzielnie w Zurychu, a GitHub Copilot jest moim bardzo szybkim partnerem w programowaniu.
Współpraca człowieka z AI
Podział jest jasny: to ja definiuję funkcje, ustalam priorytety i podejmuję decyzje architektoniczne. Copilot pomaga w implementacji: pisze kod, dodaje testy, pomaga lokalizować przyczyny błędów i przygotowywać kolejne wydania.
Mój typowy sprint wygląda mniej więcej tak:
- Opis funkcji: Opisuję, co dana funkcja ma robić, uwzględniając przypadki brzegowe i ograniczenia.
- Implementacja: Copilot proponuje kod i trzyma się istniejących w projekcie zasad.
- Testowanie: Automatyczne testy end-to-end działają na dwóch emulatorach i sprawdzają rzeczywiste połączenie między urządzeniem dziecka a urządzeniem rodzica.
- Dystrybucja: Gdy testy przejdą pomyślnie, wersje na Androida i iOS są przygotowywane do odpowiednich sklepów i kanałów testowych.
Ten cykl powtarza się przy nowych funkcjach i poprawkach błędów. Nie piszę każdej linijki sam, ale to ja decyduję, co powstaje, dlaczego to powstaje i czy dana propozycja pasuje do Timmy.
Od pomysłu do WebRTC
Od początku kluczowe zadanie techniczne było jasne: dźwięk i obraz w czasie rzeczywistym między dwoma telefonami. WebRTC było oczywistym wyborem, ale integracja z Flutterem nie jest prosta: kandydaci ICE, negocjacja SDP, awaryjne połączenie przez TURN i DataChannels muszą działać razem we właściwej kolejności.
Copilot pomógł mi krok po kroku połączyć te elementy: skonfigurować połączenie peer-to-peer, zachować właściwą kolejność krytycznych kroków (DataChannel przed ofertą, onTrack przed setRemoteDescription) oraz oprzeć sygnalizację na Firebase Firestore. Każdy element musiał działać na dwóch emulatorach, zanim przeszedłem dalej.
Bezpieczne parowanie z ECDH
Jedną z najbardziej krytycznych funkcji był system bezpiecznego parowania. Dwa urządzenia muszą wzajemnie sobie zaufać, bez polegania na centralnym serwerze, który potwierdza ich tożsamość. Rozwiązanie: wymiana kluczy ECDH P-256 przez Firebase, połączona z wizualnym numerem weryfikacyjnym (SAS), który wykrywa ataki typu man-in-the-middle.
Copilot pomógł wdrożyć cały łańcuch kryptograficzny: generowanie kluczy, wymianę kluczy publicznych, wyprowadzenie wspólnego sekretu, obliczanie SAS i szyfrowanie AES-256-GCM wszystkich późniejszych danych sygnalizacyjnych. Nie wysyłam klucza parowania do backendu; jako identyfikator dokumentu Firestore wykorzystywany jest wyłącznie jego hash SHA-256.
Audyt bezpieczeństwa: znajdowanie i naprawianie luk
Tworzenie z pomocą AI to dla mnie nie tylko szybsze pisanie. Pomaga też systematycznie szukać błędów. Podczas skoncentrowanego sprintu audytu bezpieczeństwa Copilot przeanalizował bazę kodu i znalazł sześć problemów do naprawienia:
- Brak walidacji danych wejściowych w danych sygnalizacyjnych
- Możliwe warunki wyścigu podczas obsługi kandydatów ICE
- Nieaktualne dane sesji, które nie były prawidłowo usuwane
- Zbyt liberalne reguły bezpieczeństwa Firestore
- Brak uwzględnienia przypinania certyfikatów
- Niewystarczająca obsługa błędów w procesie poświadczeń TURN
Wszystkie sześć problemów naprawiono w tym samym sprincie. W tym Copilot jest mocny: czyta wiele plików, porównuje wzorce i wskazuje miejsca, którym muszę przyjrzeć się dokładniej.
Kolejne sprinty: jak rozwijała się aplikacja
Timmy rozwijał się w ramach szybkich sprintów o jasno określonym zakresie. Kilka kamieni milowych:
- v1.8: Całkowite przeprojektowanie parowania — 4-znakowy kod + ECDH P-256 przez Firebase zastąpiły wcześniejsze rozwiązanie z bezpośrednim kluczem.
- v1.10: Sprint wzmacniający bezpieczeństwo — audyt sześciu luk i cykl ich naprawy.
- v1.11: Tryb ciemny na wszystkich ekranach oraz strona główna i blog, który właśnie czytasz.
- v1.12: Duża przebudowa ekranu rodzica, tryb nocnego widzenia i wykrywanie ruchu przez analizę klatek z kamery.
Każdy sprint przebiega według tego samego podstawowego schematu: opisuję cel, przeglądam propozycje, automatycznie testuję, a potem przekazuję wersję testerom.
Testy E2E na różnych urządzeniach
Nie da się porządnie przetestować elektronicznej niani na jednym urządzeniu. Potrzebuję urządzenia dziecka i urządzenia rodzica. Projekt zaczął się od dwóch jednocześnie uruchomionych emulatorów Androida, a teraz uzupełnia ten proces o lokalne testy na symulatorze iOS i prawdziwych urządzeniach. Automatyczny skrypt testowy Androida nadal:
- Instaluje aplikację na obu emulatorach
- Przechodzi przez proces parowania na obu urządzeniach
- Sprawdza, czy nawiązano połączenia audio i wideo
- Testuje funkcję mówienia po naciśnięciu przycisku, sterowanie kamerą i inne funkcje
Ponieważ oba emulatory korzystają z tego samego adresu IP (10.0.2.15), bezpośrednie połączenie peer-to-peer przez STUN jest niemożliwe. Każde uruchomienie testów musi przejść przez przekaźnik Cloudflare TURN. To uciążliwe, ale przydatne: za każdym razem testowana jest najbardziej złożona ścieżka połączenia.
Czego się nauczyłem
Tworząc kompletną aplikację z AI w roli partnera w programowaniu, nauczyłem się kilku rzeczy:
- Architektura ma większe znaczenie niż kiedykolwiek. Jasne zasady i dobrze udokumentowana baza kodu pomagają AI proponować spójny kod. Niejednoznaczność szybko staje się kosztowna.
- Testowanie nie podlega negocjacjom. Kod wygenerowany przez AI wymaga tak samo rygorystycznego testowania jak kod napisany przez człowieka. Automatyczne testy E2E wykryły problemy, które łatwo byłoby przeoczyć podczas ręcznego testowania.
- Człowiek zachowuje kontrolę. Każda decyzja architektoniczna, każdy kompromis dotyczący bezpieczeństwa i każda decyzja o zakresie produktu należą do mnie. AI przyspiesza implementację, ale nie zastępuje ludzkiego osądu.
- Szybkość pozwala zadbać o jakość. Ponieważ funkcje trafiają do aplikacji w ciągu godzin, a nie dni, zostaje więcej iteracji na dopracowanie i naprawianie błędów. Szybko nie zawsze znaczy dobrze.
Co dalej
Baby Monitor Timmy stale się rozwija. Wydanie na iOS jest blisko, a potem pojawią się dodatkowe funkcje wykorzystujące czujniki i dalsze wzmocnienia zabezpieczeń. Sposób pracy pozostaje podobny: to ja wyznaczam kierunek i granice, a Copilot pomaga w szybkiej implementacji i weryfikacji.
Elementy istotne dla bezpieczeństwa są teraz wyraźnie wydzielone w publicznym repozytorium baby-monitor-timmy-core. To tam udokumentowano również decyzje architektoniczne dotyczące parowania, sygnalizacji i interfejsów backendu.