Baby Monitor Timmy bắt đầu từ một ý tưởng đơn giản: một chiếc camera theo dõi bé tôn trọng quyền riêng tư tại nhà. Không lưu bản ghi trên đám mây, không có những luồng dữ liệu không cần thiết rời khỏi phòng bé. Điều mà nhiều người không thấy là: tôi xây dựng Timmy một mình tại Zurich, và GitHub Copilot là một cộng sự lập trình cặp cực kỳ nhanh nhạy của tôi.
Quy trình làm việc giữa con người và AI
Phân chia rất rõ ràng: tôi xác định tính năng, đặt ưu tiên và đưa ra các quyết định kiến trúc. Copilot hỗ trợ phần triển khai: viết mã, thêm kiểm thử, khoanh vùng lỗi và chuẩn bị các bước phát hành.
Một sprint điển hình của tôi thường diễn ra như sau:
- Mô tả tính năng: Tôi mô tả tính năng cần hoạt động thế nào, bao gồm các trường hợp đặc biệt và ràng buộc.
- Triển khai: Copilot gợi ý mã và tuân theo các quy ước sẵn có của dự án.
- Kiểm thử: Các kiểm thử end-to-end tự động chạy trên hai trình giả lập và kiểm tra kết nối thực giữa thiết bị của bé và thiết bị của bố mẹ.
- Phân phối: Khi kiểm thử đạt, các bản dựng Android và iOS được chuẩn bị cho đúng cửa hàng ứng dụng và kênh thử nghiệm.
Chu trình này lặp lại cho các tính năng và bản sửa lỗi. Tôi không tự viết từng dòng mã, nhưng tôi quyết định cái gì được xây dựng, vì sao nó được xây dựng và liệu một đề xuất có phù hợp với Timmy hay không.
Từ ý tưởng đến WebRTC
Nhiệm vụ kỹ thuật trọng tâm đã rõ ngay từ đầu: truyền âm thanh và video theo thời gian thực giữa hai điện thoại. WebRTC là lựa chọn hiển nhiên, nhưng việc tích hợp với Flutter không hề đơn giản: các ứng viên ICE, quá trình đàm phán SDP, cơ chế dự phòng TURN và DataChannel phải phối hợp theo đúng thứ tự.
Copilot giúp tôi ghép nối từng phần theo từng bước: thiết lập kết nối ngang hàng, giữ đúng thứ tự quan trọng (tạo DataChannel trước khi gửi offer, đăng ký onTrack trước khi gọi setRemoteDescription), và dùng Firebase Firestore cho việc truyền tín hiệu. Mỗi phần đều phải chạy được trên hai trình giả lập trước khi tôi tiếp tục.
Ghép nối an toàn với ECDH
Một trong những tính năng quan trọng nhất là hệ thống ghép nối an toàn. Hai thiết bị cần thiết lập sự tin cậy lẫn nhau mà không phụ thuộc vào một máy chủ trung tâm để xác thực danh tính. Giải pháp là trao đổi khóa ECDH P-256 qua Firebase, kết hợp với một mã xác minh hiển thị (SAS) có khả năng phát hiện các cuộc tấn công xen giữa.
Copilot giúp triển khai chuỗi thao tác mật mã: tạo khóa, trao đổi khóa công khai, dẫn xuất bí mật dùng chung, tính SAS và mã hóa toàn bộ dữ liệu truyền tín hiệu về sau bằng AES-256-GCM. Tôi không gửi khóa ghép nối lên máy chủ; chỉ giá trị băm SHA-256 của khóa được dùng làm mã định danh tài liệu trong Firestore.
Kiểm toán bảo mật: tìm và khắc phục lỗ hổng
Với tôi, phát triển có AI hỗ trợ không chỉ là gõ mã nhanh hơn. Nó còn giúp tìm lỗi một cách có hệ thống. Trong một sprint kiểm toán bảo mật tập trung, Copilot đã phân tích mã nguồn và tìm thấy sáu vấn đề cần khắc phục:
- Thiếu xác thực dữ liệu đầu vào đối với dữ liệu truyền tín hiệu
- Khả năng xảy ra điều kiện tranh chấp khi xử lý ICE candidate
- Dữ liệu phiên cũ không được dọn dẹp đúng cách
- Quy tắc bảo mật Firestore quá lỏng
- Chưa xem xét đầy đủ việc ghim chứng chỉ
- Xử lý lỗi chưa đầy đủ trong quy trình cấp thông tin xác thực TURN
Cả sáu vấn đề đều được khắc phục ngay trong sprint đó. Đây là điểm Copilot làm tốt: đọc nhiều tệp, so sánh các mẫu và đánh dấu những chỗ tôi cần xem xét kỹ hơn.
Các sprint lặp lại: ứng dụng đã phát triển thế nào
Timmy phát triển qua các sprint nhanh nhưng có giới hạn rõ ràng. Một số cột mốc:
- v1.8: Thiết kế lại hoàn toàn quy trình ghép nối — mã 4 ký tự + ECDH P-256 qua Firebase thay thế cách dùng khóa trực tiếp trước đây.
- v1.10: Sprint tăng cường bảo mật — chu trình kiểm toán và khắc phục sáu lỗ hổng.
- v1.11: Chế độ tối trên mọi màn hình, cùng trang chủ và blog bạn đang đọc.
- v1.12: Cải tổ lớn màn hình dành cho bố mẹ, chế độ nhìn đêm và phát hiện chuyển động qua phân tích khung hình camera.
Mỗi sprint đều theo cùng một khuôn mẫu cơ bản: mô tả mục tiêu, xem xét đề xuất, kiểm thử tự động, rồi gửi cho người thử nghiệm.
Kiểm thử E2E trên nhiều thiết bị
Bạn không thể kiểm thử đúng cách một ứng dụng theo dõi em bé chỉ trên một thiết bị. Tôi cần một thiết bị đặt bên bé và một thiết bị dành cho bố mẹ. Ban đầu, dự án sử dụng hai trình giả lập Android chạy đồng thời; hiện nay, quy trình này còn được bổ sung bằng các bước kiểm tra cục bộ trên trình mô phỏng iOS và thiết bị thật. Tập lệnh kiểm thử Android tự động vẫn thực hiện các việc sau:
- Cài ứng dụng trên cả hai trình giả lập
- Đi qua quy trình ghép nối trên cả hai thiết bị
- Xác minh kết nối âm thanh và video đã được thiết lập
- Kiểm tra chức năng nhấn để nói, điều khiển camera và các tính năng khác
Vì cả hai trình giả lập dùng chung một địa chỉ IP (10.0.2.15), nên không thể thiết lập kết nối ngang hàng trực tiếp qua STUN. Mỗi lần kiểm thử đều phải đi qua relay Cloudflare TURN. Điều đó khá phiền, nhưng hữu ích: đường kết nối phức tạp nhất được kiểm thử mỗi lần.
Những điều tôi học được
Việc xây dựng một ứng dụng hoàn chỉnh cùng một người lập trình AI đã dạy tôi vài điều:
- Kiến trúc quan trọng hơn bao giờ hết. Quy ước rõ ràng và mã nguồn được tài liệu hóa tốt giúp AI đề xuất mã nhất quán. Sự mơ hồ nhanh chóng trở nên tốn kém.
- Kiểm thử là điều không thể bỏ qua. Mã do AI tạo ra cần được kiểm thử nghiêm ngặt như mã do con người viết. Kiểm thử E2E tự động đã phát hiện các vấn đề rất dễ bỏ sót khi kiểm tra thủ công.
- Con người vẫn tham gia vào toàn bộ quy trình. Mọi quyết định về kiến trúc, mọi đánh đổi về bảo mật và mọi ranh giới sản phẩm vẫn do tôi chịu trách nhiệm. AI tăng tốc triển khai, nhưng không thay thế được phán đoán.
- Tốc độ tạo điều kiện cho chất lượng. Vì các tính năng được phát hành trong vài giờ thay vì vài ngày, tôi có thêm nhiều vòng lặp để hoàn thiện sản phẩm và sửa lỗi. Nhanh không tự động đồng nghĩa với tốt.
Nhìn về phía trước
Baby Monitor Timmy vẫn tiếp tục phát triển. Bản phát hành iOS đã gần kề; sau đó sẽ có thêm các tính năng cảm biến và tiếp tục tăng cường bảo mật. Quy trình vẫn tương tự: tôi xác định hướng đi và giới hạn, Copilot hỗ trợ triển khai và kiểm tra nhanh.
Các thành phần liên quan đến bảo mật hiện được tổ chức theo các ranh giới rõ ràng trong kho mã công khai baby-monitor-timmy-core. Đây cũng là nơi ghi lại các quyết định kiến trúc liên quan đến ghép nối, truyền tín hiệu và giao diện máy chủ.