Baby Monitor Timmy gimė iš paprastos idėjos: sukurti kūdikio stebėjimo programėlę, kuri namuose gerbtų privatumą. Jokių įrašų debesijoje, jokio nereikalingo duomenų perdavimo iš vaikų kambario. Ko daugelis nežino: Timmy kuriu vienas Ciuriche, o GitHub Copilot yra mano itin greitas programavimo porininkas.
Žmogaus ir DI darbo eiga
Atsakomybės aiškiai atskirtos: apibrėžiu funkcijas, nustatau prioritetus ir priimu architektūros sprendimus. Copilot padeda įgyvendinti: rašyti kodą, pridėti testų, susiaurinti klaidų paiešką ir paruošti leidimo veiksmus.
Mano įprastas sprintas maždaug atrodo taip:
- Funkcijos aprašymas: Aprašau, ką funkcija turi daryti, įskaitant kraštinius atvejus ir apribojimus.
- Įgyvendinimas: Copilot siūlo kodą ir laikosi esamų projekto taisyklių.
- Testavimas: Automatiniai visos sistemos testai vykdomi dviejuose emuliatoriuose ir patikrina tikrą ryšį tarp kūdikio ir tėvų įrenginių.
- Platinimas: Kai testai praeina, paruošiamos „Android“ ir „iOS“ versijos tinkamai parduotuvei ir testavimo kanalams.
Šis ciklas kartojasi kuriant funkcijas ir taisant klaidas. Ne kiekvieną eilutę rašau pats, bet nusprendžiu, kas bus kuriama, kodėl tai kuriama ir ar pasiūlymas tinka Timmy.
Nuo idėjos iki WebRTC
Pagrindinė techninė užduotis nuo pat pradžių buvo aiški: garso ir vaizdo perdavimas realiuoju laiku tarp dviejų telefonų. WebRTC buvo akivaizdus pasirinkimas, tačiau jį integruoti su „Flutter“ nėra paprasta: ICE kandidatai, SDP derybos, TURN atsarginis sprendimas ir „DataChannels“ turi veikti kartu tinkama tvarka.
Copilot padėjo man žingsnis po žingsnio sujungti šias dalis: užmegzti lygiarangį ryšį, išlaikyti teisingą svarbių veiksmų seką („DataChannel“ prieš pasiūlymą, „onTrack“ prieš „setRemoteDescription“) ir įgyvendinti signalizavimą per „Firebase Firestore“. Prieš eidamas toliau, kiekvieną dalį turėjau paleisti dviejuose emuliatoriuose.
Saugus susiejimas naudojant ECDH
Viena svarbiausių funkcijų buvo saugaus susiejimo sistema. Du įrenginiai turi pradėti pasitikėti vienas kitu be centrinio serverio, kuris patvirtintų jų tapatybę. Sprendimas – ECDH P-256 raktų apsikeitimas per „Firebase“ ir vaizdinis patvirtinimo skaičius (SAS), padedantis aptikti tarpininko atakas.
Copilot padėjo įgyvendinti visą kriptografinę grandinę: raktų generavimą, viešųjų raktų apsikeitimą, bendros slaptosios reikšmės gavimą, SAS apskaičiavimą ir visų vėlesnių signalizavimo duomenų šifravimą naudojant AES-256-GCM. Susiejimo rakto į serverį nesiunčiu; kaip „Firestore“ dokumento identifikatorius naudojama tik jo SHA-256 maišos reikšmė.
Saugumo auditas: pažeidžiamumų radimas ir taisymas
Man DI padedamas kūrimas nėra vien greitesnis spausdinimas. Jis taip pat padeda sistemiškai ieškoti klaidų. Per kryptingą saugumo audito sprintą Copilot išanalizavo kodų bazę ir rado šešias problemas kurias reikėjo ištaisyti:
- Trūkstamas signalizavimo duomenų įvesties tikrinimas
- Galimos lenktynių sąlygos tvarkant ICE kandidatus
- Pasenę sesijos duomenys, kurie nebuvo tinkamai išvalomi
- Per daug leidžiančios „Firestore“ saugumo taisyklės
- Neatsižvelgta į sertifikatų susiejimo poreikį
- Nepakankamas klaidų tvarkymas TURN prisijungimo duomenų sraute
Visos šešios problemos buvo ištaisytos per tą patį sprintą. Čia Copilot stiprus: jis perskaito daug failų, palygina šablonus ir pažymi vietas, kurias turiu atidžiau patikrinti.
Iteraciniai sprintai: kaip vystėsi programėlė
Timmy augo per greitus, bet aiškiai apibrėžtus sprintus. Keletas etapų:
- v1.8: Visiškai pertvarkytas susiejimas — 4 simbolių kodas ir ECDH P-256 per „Firebase“ pakeitė ankstesnį tiesioginio rakto sprendimą.
- v1.10: Saugumo stiprinimo sprintas — šešių pažeidžiamumų auditas ir taisymo ciklas.
- v1.11: Tamsusis režimas visuose ekranuose, taip pat pagrindinis puslapis ir tinklaraštis, kurį dabar skaitote.
- v1.12: Esminis tėvų ekrano atnaujinimas, naktinio matymo režimas ir judesio aptikimas analizuojant kameros kadrus.
Kiekvienas sprintas vyksta pagal tą patį pagrindinį modelį: aprašau tikslą, peržiūriu pasiūlymus, automatiškai testuoju, tada pateikiu testuotojams.
E2E testavimas skirtinguose įrenginiuose
Kūdikio stebėjimo programėlės negalima tinkamai ištestuoti viename įrenginyje. Man reikia vieno įrenginio prie kūdikio ir vieno įrenginio tėvams. Iš pradžių projekte vienu metu veikė du „Android“ emuliatoriai, o dabar šį ciklą papildo vietinio „iOS“ simuliatoriaus ir tikrų įrenginių patikros. Automatinis „Android“ testavimo scenarijus vis dar:
- Įdiegia programėlę abiejuose emuliatoriuose
- Atlieka susiejimą abiejuose įrenginiuose
- Patikrina, ar užmegztas garso ir vaizdo ryšys
- Testuoja tiesioginio kalbėjimo funkciją, kameros valdymą ir kitas funkcijas
Kadangi abu emuliatoriai naudoja tą patį IP adresą (10.0.2.15), tiesioginis lygiarangis ryšys per STUN neįmanomas. Kiekvienas testas turi vykti per „Cloudflare TURN“ retransliavimo serverį. Tai erzina, bet yra naudinga: kiekvieną kartą išbandomas sudėtingiausias ryšio kelias.
Ką išmokau
Kurdamas visavertę programėlę su DI programavimo porininku išmokau keletą dalykų:
- Architektūra svarbesnė nei bet kada. Aiškūs susitarimai ir gerai dokumentuota kodų bazė padeda DI siūlyti nuoseklų kodą. Neaiškumas greitai kainuoja brangiai.
- Dėl testavimo kompromisų nėra. DI sugeneruotą kodą reikia testuoti taip pat griežtai kaip žmogaus parašytą kodą. Automatiniai E2E testai aptiko problemų, kurias būtų buvę lengva praleisti testuojant rankiniu būdu.
- Žmogus lieka procese. Kiekvienas architektūros sprendimas, kiekvienas saugumo kompromisas ir kiekviena produkto riba lieka mano atsakomybė. DI pagreitina įgyvendinimą, bet nepakeičia žmogaus nuovokos.
- Greitis leidžia siekti kokybės. Kadangi funkcijos pristatomos per valandas, o ne per dienas, lieka daugiau iteracijų joms tobulinti ir klaidoms taisyti. Greitis savaime negarantuoja kokybės.
Žvelgiant į priekį
Baby Monitor Timmy toliau tobulėja. „iOS“ versija jau beveik paruošta; po jos atsiras papildomos jutiklių funkcijos ir bus toliau stiprinamas saugumas. Darbo eiga lieka panaši: aš nustatau kryptį ir ribas, o Copilot padeda greitai įgyvendinti ir patikrinti.
Saugumui svarbūs komponentai dabar yra aiškiai atskirti viešoje baby-monitor-timmy-core saugykloje. Joje taip pat dokumentuoti architektūros sprendimai, susiję su susiejimu, signalizavimu ir sąsajomis su galine sistema.