{"id":"cmv07ntfk0001nt2ol8z13ntn","slug":"menu-tugas","judul":"Menu Tugas","deskripsi":"Layar tugas ortu — CRUD tugas anak + validasi foto bukti","parentId":"cmv06akyz001hpj2o93e4r5gu","urut":11,"kategori":"mobile","tag":"[\"kotlin\", \"compose\", \"tugas\", \"crud\"]","status":"aktif","versi":null,"konsep":"1. Executive Summary & Core Concept\nTujuan Modul: Menyediakan sistem manajemen tugas harian yang dilengkapi kuis edukatif berbasis AI serta Otomatisasi Terjadwal (Scheduled AI Tasks). Orang tua dapat mengatur jadwal rutin di mana AI akan secara otomatis menghasilkan dan mengirimkan tugas atau kuis baru setiap hari berdasarkan profil anak dan skala kesulitan yang dipilih, tanpa perlu intervensi manual setiap hari.\n\n2. Spesifikasi Teknis & Integrasi Sistem\nFrontend Mobile: Flutter / Android Native (Antarmuka Orang Tua & Anak).\n\nBackend & Cron Job Automation: Node.js / Supabase dengan Cron Jobs / Background Workers untuk memicu pembuatan tugas otomatis harian.\n\nAI Engine: Integrasi LLM API (DeepSeek/Gemini) untuk pemrosesan pembuatan soal dinamis sesuai jadwal.\n\nDatabase Schema (Automation Settings Table):\n\nschedule_id (UUID)\n\nchild_id (Foreign Key ke profil anak)\n\ntopic_theme (Tema berkala, misal: Matematika Dasar / Kosakata)\n\ndifficulty_level (Skala 1-5)\n\nexecution_time (Waktu pengiriman harian, misal: Pukul 15:00)\n\nreward_tokens (Jumlah token otomatis)\n\nis_active (Boolean)\n\n3. Fitur Utama & Actionable Checklist\nA. Manajemen Tugas Manual oleh Orang Tua\n[ ] Antarmuka pembuatan tugas harian standar (judul, deskripsi, target anak, jumlah token).\n\n[ ] Daftar tugas aktif per anak (Active Tasks List).\n\n[ ] Tombol verifikasi/persetujuan tugas selesai oleh orang tua (Approval System).\n\nB. Fitur Pembuatan Kuis Otomatis Berbasis AI (AI Quiz Generator)\n[ ] Form input tema/topik tugas soal oleh orang tua secara instan.\n\n[ ] Filter otomatis berbasis profil anak (mengambil data umur, kelas, jenis kelamin, dan agama).\n\n[ ] Pengatur tingkat kesulitan interaktif bergeser/skala 1 sampai 5 (Level 1 Pemula hingga Level 5 Expert).\n\n[ ] Pratinjau (Preview) soal sebelum dikirimkan ke perangkat anak.\n\nC. Fitur Tugas AI Terjadwal (Scheduled AI Tasks) [BARU]\n[ ] Panel Pengaturan Jadwal (Scheduler Setup): Menu bagi orang tua untuk menentukan frekuensi (misal: Setiap Hari Senin-Jumat), jam pengiriman, dan tema berulang.\n\n[ ] Background Cron Worker: Sistem otomatis di server yang memicu AI setiap hari pada jam tertentu untuk meracik soal baru berdasarkan profil anak dan tingkat kesulitannya (1-5).\n\n[ ] Auto-Publish to Child Device: Tugas yang digenerate oleh sistem otomatis masuk ke daftar tugas anak tanpa perlu klik manual dari orang tua setiap hari.\n\nD. Sisi Klien Anak (Child View)\n[ ] Notifikasi dan daftar kuis/tugas baru (baik tugas manual, kuis instan, maupun tugas terjadwal dari AI).\n\n[ ] Antarmuka pengerjaan soal atau penandaan selesai tugas.\n\n[ ] Animasi perolehan Token/ZX Coin otomatis saat tugas divalidasi oleh orang tua.\n\n4. Model Token & Reward Integration\nSetiap tugas yang diselesaikan dan disetujui orang tua akan langsung menambahkan saldo Token/ZX Coin ke dompet anak.\n\nSaldo token terhubung langsung dengan modul Market untuk ditukar dengan hadiah pilihan.","createdAt":"2026-10-09T00:12:11.072Z","updatedAt":"2026-10-10T00:46:59.702Z","bagian":[{"id":"cmv07ntix0003nt2oez77xo6a","blueprintId":"cmv07ntfk0001nt2ol8z13ntn","judul":"Ringkasan","konten":"Tab ke-3 (index 2) di bottom navigation. Ortu assign tugas ke anak, anak kirim foto bukti, ortu validasi.\n\n**File:** `ui/layar/LayarTugas.kt` (234 lines)\n**Wiring:** `MainActivity.kt` tab==2 → `LayarTugas(tugasList, anakList, loading, onBuat, onValidasi)`\n\n**Status flow:**\n```\nPENDING → DIKUMPULKAN → SELESAI (token masuk)\n                      → DITOLAK (foto dihapus, anak kirim ulang)\n```\n\n**Validasi ortu:** tombol ✓ (selesai) atau ✗ (tolak) di kartu tugas status MENUNGGU/PENDING.","media":"[]","urut":0,"createdAt":"2026-10-09T00:12:11.193Z","updatedAt":"2026-10-09T00:12:11.193Z"},{"id":"cmv07ntmm0005nt2oarx5bgyr","blueprintId":"cmv07ntfk0001nt2ol8z13ntn","judul":"UI Komponen","konten":"**3 composable:**\n\n**1. `LayarTugas`** — main screen\n- Header: judul \"Tugas\" + tombol \"Buat\" (toggle form)\n- Empty state: \"Tambah anak dulu\" / \"Belum ada tugas\"\n- Section \"Perlu Validasi\" (MENUNGGU/PENDING) — kuning Amber\n- Section \"Riwayat\" (SELESAI/DITOLAK) — muted\n- `verticalScroll`, `Arrangement.spacedBy(12.dp)`\n\n**2. `KartuTugas`** — tugas card (private)\n- Icon `Inventory2` di box biru rounded 12dp\n- Judul + nama anak + badge status (warna: SELESAI=hijau, DITOLAK=merah, MENUNGGU=amber)\n- Deskripsi (jika ada)\n- Token reward \"+N token\" (hijau)\n- Tombol validasi: ✓ (Hijau) + ✗ (Merah) — hanya status MENUNGGU/PENDING\n- Pakai `KartuClay(kecil=true)` wrapper\n\n**3. `FormTugas`** — form buat tugas (private)\n- Dropdown anak (`OutlinedButton` + `DropdownMenu`)\n- Field judul (text)\n- Field deskripsi (text, opsional)\n- Field token reward (number, 1-100, default \"1\")\n- Tombol \"Simpan\" — loading spinner saat loading\n- Validasi: judul tidak kosong + anakList tidak empty\n- Reward `coerceIn(1, 100)`\n\n**Helper:** `FieldBiasa` — label + OutlinedTextField, rounded 12dp","media":"[]","urut":1,"createdAt":"2026-10-09T00:12:11.326Z","updatedAt":"2026-10-09T00:12:11.326Z"},{"id":"cmv07ntqc0007nt2oxcn08vms","blueprintId":"cmv07ntfk0001nt2ol8z13ntn","judul":"Data Flow","konten":"**State:** `UiState.tugasList: List<Tugas>`, `UiState.anakList: List<Anak>`\n\n**Tugas data class:**\n```kotlin\ndata class Tugas(\n    id, judul, deskripsi: String?,\n    tokenReward: Int,\n    status: String,  // PENDING|DIKUMPULKAN|SELESAI|DITOLAK\n    fotoBuktiUrl: String?,\n    validasiOrtu: Boolean?,\n    deadline: String?,\n    createdAt: String,\n    anak: AnakRef,  // {nama: String}\n)\n```\n\n**TugasCreateReq:** `anakId, judul, deskripsi?, tokenReward=1, deadline?`\n**TugasValidasiReq:** `aksi: String` // \"selesai\" | \"tolak\"\n\n**ZxVm functions:**\n- `muatTugas(token)` — `GET /api/tugas`, update `state.tugasList`\n- `buatTugas(anakId, judul, deskripsi, tokenReward, deadline, onSelesai)` — `POST /api/tugas`, reload tugas\n- `validasiTugas(tugasId, aksi)` — `PATCH /api/tugas/{id}`, reload tugas + anak (token balance berubah)\n\n**Called from `muatSemua()`:** tugas load saat login","media":"[]","urut":2,"createdAt":"2026-10-09T00:12:11.460Z","updatedAt":"2026-10-09T00:12:11.460Z"},{"id":"cmv07ntt20009nt2od1gs8ftg","blueprintId":"cmv07ntfk0001nt2ol8z13ntn","judul":"Backend","konten":"**GET /api/tugas** — list semua tugas anak ortu\n- `prisma.tugas.findMany({ where: { anak: { ortuId: ortu.id } } })`\n- include anak.nama\n- orderBy createdAt desc\n\n**POST /api/tugas** — buat tugas\n- Validasi: anakId wajib, judul wajib, tokenReward 1-100\n- Cek anak milik ortu (`findFirst { id, ortuId }`)\n- `deadline ? new Date(deadline) : null`\n- Return `{ ok, tugasId }`\n\n**PATCH /api/tugas/[id]** — validasi\n- `aksi=\"selesai\"`: status→SELESAI, validasiOrtu=true\n  - Token reward masuk: `tokenBalance.upsert` + `tokenLedger.create` (tipe=TUGAS)\n  - `streakNaik(tx, anakId)` — streak +1\n  - `$transaction` — atomic\n- `aksi=\"tolak\"`: status→DITOLAK, fotoBuktiUrl=null, validasiOrtu=false\n  - Anak bisa kumpul ulang (kirim foto baru)\n- Cek tugas milik anak ortu\n- SELESAI tidak bisa di-validasi lagi (400)","media":"[]","urut":3,"createdAt":"2026-10-09T00:12:11.559Z","updatedAt":"2026-10-09T00:12:11.559Z"},{"id":"cmv07ntvj000bnt2o9hhyiwn9","blueprintId":"cmv07ntfk0001nt2ol8z13ntn","judul":"Pitfall","konten":"⚠ `deadline` field ada di model + API + TugasCreateReq, TAPI **tidak dipakai di FormTugas UI**. `MainActivity` wiring: `vm.buatTugas(aId, j, d, r, null) {}` — selalu kirim `deadline=null`.\n\n⚠ Status di backend: `PENDING` → `DIKUMPULKAN` → `SELESAI`/`DITOLAK`. Tapi `LayarTugas` cek `MENUNGGU || PENDING` — `DIKUMPULKAN` tidak masuk \"Perlu Validasi\". Kemungkinan bug: tugas DIKUMPULKAN tidak tampil di section validasi.\n\n⚠ `validasiTugas` reload `muatAnak(token)` setelah \"selesai\" — karena token balance anak berubah. Tapi tidak reload di \"tolak\".\n\n⚠ Foto bukti: `fotoBuktiUrl` field ada, anak kirim via app anak (zx-agent). Upload mechanism belum fully implemented di backend.\n\n⚠ Token reward `coerceIn(1, 100)` di app. Backend juga validasi 1-100. Double validation OK.\n\n⚠ Tugas auto-expire: `deadline` lewat → status DIKUMULKAN? Tidak. Backend tidak auto-expire. Tugas PENDING tetap PENDING walau deadline lewat.","media":"[]","urut":4,"createdAt":"2026-10-09T00:12:11.647Z","updatedAt":"2026-10-09T00:12:11.647Z"}],"children":[],"parent":{"slug":"app-ortu","judul":"App Ortu (Android)"}}