Tampilan
🛠️ Mini Proyek: Produk, Monetisasi & Rilis
⭐⭐⭐⭐ · 1–2 hari
Apa yang akan kamu bangun
Asisten Dapur — aplikasi percakapan yang membantu memutuskan mau masak apa. Pengguna menyebutkan bahan yang tersisa di kulkas, dan asisten mengusulkan resep, menjawab pertanyaan susulan, dan bisa merapikan usulannya menjadi daftar belanja. Model dibatasi supaya hanya membicarakan urusan masak — kalau ditanya hal lain, ia menolak dengan sopan.
Batasan itu bukan hiasan. Ia adalah alasan utama proyek ini memakai domain yang sempit alih-alih "chatbot serba bisa": mengendalikan kepribadian dan ruang lingkup asisten lewat systemInstruction adalah keterampilan paling berguna dari Bab 34, dan kamu hanya bisa membuktikan ia bekerja kalau ada batas yang jelas untuk diuji. Daftar belanja menambahkan tantangan kedua dari bab itu: meminta keluaran terstruktur dari model yang tidak menjamin keluarannya valid.
Sisi kedua proyek ini adalah uang. Aplikasi menampilkan iklan (Bab 35), dan menawarkan langganan untuk menghilangkannya (Bab 36). Keduanya dikerjakan sepenuhnya dengan ID pengujian dan mode sandbox — proyek ini tidak untuk dirilis.
Ini latihan, bukan produk yang siap dijual
Langganan yang membuka fitur di dalam aplikasi harus melalui sistem pembayaran toko aplikasi (Google Play Billing atau StoreKit), bukan Stripe atau PayPal. Aturan ini dan pengecualiannya dibahas di Bab 36 — baca ulang bagian itu sebelum mulai. Kamu mengerjakan alur Stripe di sini untuk mempelajari mekanismenya (webhook, sumber kebenaran, aturan keamanan), bukan untuk mengunggahnya ke toko.
Dan sekali lagi: selalu pakai ID iklan pengujian. Mengklik iklan sungguhan di aplikasimu sendiri bisa memblokir akun AdMob-mu permanen.
Bagian terakhir tidak berupa kode sama sekali, dan itu disengaja. Bagian V mengajarkan bahwa aplikasi yang bagus tetap gagal kalau tidak ada yang menemukannya, dan bahwa cara sebuah proyek disajikan ke orang lain adalah keterampilan tersendiri. Jadi proyek ini menuntut beberapa dokumen: rencana kata kunci, draf listing toko, dan README yang layak ditunjukkan.
Prasyarat
Selesaikan dulu:
- Bab 34 — AI Chatbot dengan Gemini
- Bab 35 — Google AdMob
- Bab 36 — Langganan: Stripe & PayPal
- Bab 37 — Git & GitHub
- Bab 39 — ASO dan Bab 41 — Model Bisnis & Perlindungan IP untuk bagian non-koding
Requirement fungsional
- Antarmuka percakapan: gelembung pesan pengguna dan asisten yang bisa dibedakan, dan daftar yang menggulir ke pesan terbaru secara otomatis.
- Jawaban asisten mengalir kata demi kata, bukan muncul sekaligus setelah menunggu.
- Pesan pengguna tampil seketika, tanpa menunggu jawaban model.
systemInstructionmembatasi asisten pada urusan masak. Menanyakan hal di luar itu menghasilkan penolakan yang sopan dan konsisten.- Saat percakapan masih kosong, aplikasi menampilkan beberapa saran pertanyaan yang bisa langsung diketuk.
- Tombol "Buat daftar belanja" mengubah percakapan yang sedang berjalan menjadi daftar bahan terstruktur yang bisa dicentang — dan tetap menampilkan sesuatu yang masuk akal kalau model mengembalikan format yang tidak valid.
- Jawaban yang gagal menampilkan tombol "Coba lagi" pada pesan itu sendiri, bukan sekadar snackbar yang lewat.
- Riwayat percakapan bertahan setelah aplikasi ditutup.
- Iklan banner di bagian bawah layar utama, dan iklan interstitial yang muncul sesekali di antara percakapan — dengan jeda minimal dan ambang jumlah aksi, tidak pernah saat aplikasi baru dibuka atau di tengah jawaban yang sedang mengalir.
- Layar paket menawarkan langganan "tanpa iklan", dengan alur pembayaran Stripe dalam mode uji.
- Setelah langganan aktif, seluruh iklan hilang tanpa perlu memulai ulang aplikasi.
Requirement teknis
- Kunci API Gemini tidak ditulis di dalam kode. Pakai
--dart-define, dan jelaskan di README kenapa pendekatan ini pun masih belum cukup untuk produksi. - Jumlah pesan riwayat yang dikirim ke model dibatasi, karena setiap pesan lama ikut dihitung sebagai token input pada setiap permintaan.
- Pemilihan ID iklan otomatis lewat pemeriksaan
kDebugMode, sehingga mustahil ID produksi terpakai saat pengembangan. - Setiap objek iklan di-
dispose(), dan banner memakai ukuran adaptif tanpa memesan ruang sebelum iklannya siap. - Seluruh penempatan iklan dibungkus satu pemeriksaan status langganan, sehingga mematikannya cukup dari satu tempat.
- Aplikasi tidak pernah menulis status langganan. Hanya server (webhook) yang boleh, dan itu ditegakkan lewat aturan Firestore.
- Secret key tidak pernah ada di aplikasi. Hanya publishable key.
- Aplikasi menangani jeda antara pembayaran dan webhook: tampilkan keadaan "mengaktifkan" dengan batas waktu, dan biarkan langganan aktif sendiri ketika webhook tiba.
- Proyek berada di repositori Git dengan
.gitignoreyang mencakup berkas rahasia, riwayat commit yang bermakna, dan setidaknya satu pull request yang kamu buat lalu gabungkan sendiri.
Deliverable non-koding
Ini bagian dari proyek, bukan tambahan opsional. Simpan sebagai berkas Markdown di dalam repositori.
- Rencana ASO: lima kata kunci target untuk aplikasi ini, masing-masing disertai satu kalimat alasan — kenapa kata itu, dan siapa yang mengetiknya.
- Draf listing toko: judul (dengan batas karakter yang benar), subjudul, dan deskripsi singkat yang menjelaskan manfaat, bukan daftar fitur.
- Satu paragraf model bisnis: siapa yang akan membayar untuk versi tanpa iklan, kenapa, dan berapa yang masuk akal. Jujur saja kalau jawabannya "hampir tidak ada" — mengenali itu juga hasil belajar.
- README profesional: apa aplikasinya, tangkapan layar, cara menjalankannya secara lokal termasuk variabel yang dibutuhkan, dan ringkasan arsitekturnya.
Checklist penerimaan
- Menanyakan sesuatu yang jelas di luar topik masak menghasilkan penolakan, bukan jawaban.
- Iklan yang muncul selama pengujian seluruhnya iklan uji coba — periksa labelnya.
- Menyelesaikan pembayaran uji Stripe menghilangkan iklan tanpa memulai ulang aplikasi.
- Mencari
sk_di seluruh repositori tidak menemukan hasil. git logmenampilkan riwayat yang bisa dibaca orang lain, dan tidak ada satu pun berkas rahasia yang pernah ter-commit.- Keempat deliverable non-koding ada di repositori dan benar-benar ditulis, bukan diisi seadanya.
Tantangan ekstra (opsional)
- Pindahkan pemanggilan Gemini ke Cloud Function, sehingga kunci API benar-benar tidak pernah ada di perangkat.
- Tambahkan rewarded ad: menonton satu iklan memberi beberapa percakapan tambahan hari itu. Ini format iklan yang justru menaikkan kepuasan pengguna, karena mereka yang memilih.
- Tambahkan batas pemakaian harian untuk pengguna gratis, lengkap dengan tampilan sisa kuota yang jujur.
- Siapkan GitHub Actions yang menjalankan
flutter analyzedanflutter testpada setiap pull request.
Terjebak?
Kerjakan tiga sisinya secara terpisah dan jangan menggabungkannya sebelum masing-masing bekerja sendiri: percakapan dulu sampai lancar, lalu iklan, lalu langganan. Menggabungkan ketiganya sejak awal membuat setiap kegagalan punya tiga kemungkinan penyebab. Baca ulang Bab 34 untuk urusan streaming, dan Bab 36 untuk urusan siapa yang berhak menulis status langganan. Kalau masih macet di satu bagian spesifik, itu wajar: proyek ini memang dirancang untuk memaksamu mengingat kembali konsep yang sudah dibahas, bukan menghafalnya.