Home›ZX Parenting›App Ortu (Android)›App Ortu (Android)›Tugas (Module)
AKTIFtugascrud

Tugas (Module)

CRUD tugas anak + validasi ortu + foto bukti

JSON

💡 Ide & Konsep

1. Executive Summary & Core Concept

Tujuan Modul: Sistem manajemen tugas harian + kuis edukatif berbasis AI + Otomatisasi Terjadwal (Scheduled AI Tasks). Ortu atur jadwal rutin, AI generate tugas/kuis otomatis tiap hari berdasarkan profil anak + skala kesulitan. Tanpa intervensi manual tiap hari.

Visual Mockup (Android Material 3):

  • Scheduler Panel — bottom sheet form, M3 switch, day picker, slider kesulitan
  • Task List — card list, soal preview, approve/reject inline, FAB

2. Spesifikasi Teknis & Integrasi Sistem

  • App Ortu: Android Native (Kotlin + Jetpack Compose). Repo: ZX-Parenting-ortu (PUBLIC).
  • App Anak: Android Native (Kotlin + Compose). Repo: zx-agent.
  • Backend: Next.js 16 + Prisma 6 + PostgreSQL. Deploy Coolify (app_id=9, zxparenting.zomet.my.id).
  • Web = ADMIN ONLY. Ortu + anak = APK ONLY. Web sediakan API untuk APK konsumsi.
  • AI Engine: Gemini 2.5 Flash (sudah dipakai F11 AI Insights).
  • Cron: Coolify scheduled task atau Next.js API route + node-cron di container.
  • Timezone: Wajib per-user (Asia/Jakarta default, configurable untuk global market).
  • Multi-bahasa: Soal support bahasa per-ortu setting. Prompt Gemini pakai bahasa dipilih. Default: Indonesia + English.
  • Data privacy: Profil anak minimal dikirim ke Gemini (hanya umur + kelas). Gender/agama tidak dikirim kalau tidak relevan untuk soal.
  • Offline mode: Kuis yang sudah generated bisa dikerjakan offline di APK anak. Soal + opsi sudah ada di DB lokal saat tugas di-push. Jawaban disimpan lokal, sync ke server saat online. Tidak bisa mulai kuis baru yang belum di-download.

3. Schema DB — Table Baru

3a. JadwalTugasAI

model JadwalTugasAI {

id String @id @default(cuid())

anakIds String // JSON array ["anak1","anak2"] — 1 jadwal bisa untuk multiple anak

ortuId String

tema String

kesulitan Int @default(3) // skala 1-5

jamKirim String // format HH:mm

hariAktif String @default('[1,2,3,4,5]') // ISO weekday: Senin-Jumat

rewardToken Int @default(10)

autoApprove Boolean @default(false)

aktif Boolean @default(false)

maxRetry Int @default(3) // max retry per hari per anak, 0 = unlimited

notifPref String @default('["ai_generate","anak_selesai","anak_buka"]') // ortu pilih notifikasi

lastRun DateTime?

createdAt DateTime @default(now())

updatedAt DateTime @updatedAt

@@index([ortuId])

}

Catatan: 1 jadwal untuk multiple anak (anakIds = JSON array). Cron generate soal terpisah per anak (profil beda = soal beda), tapi 1 entry jadwal.

3b. Tugas

model Tugas {

id String @id @default(cuid())

anakId String

anak Anak @relation(fields: [anakId], references: [id], onDelete: Cascade)

ortuId String

judul String

deskripsi String @default("")

type String @default("manual") // manual | ai_quiz | ai_scheduled

soal String @default("[]") // JSON array soal untuk type ai_*

status String @default("pending") // pending | doing | done | approved | expired

rewardToken Int @default(0)

tokenDiklaim Int @default(0) // token yang sudah diklaim (berdasarkan skor terbaik)

jadwalId String?

waktuMulai DateTime? // saat anak buka tugas

waktuExpire DateTime? // waktuMulai + 24jam, auto-expire kalau tidak selesai

createdAt DateTime @default(now())

selesaiAt DateTime?

approvedAt DateTime?

@@index([anakId])

@@index([ortuId])

@@index([status])

}

3c. KuisSession

model KuisSession {

id String @id @default(cuid())

tugasId String

tugas Tugas @relation(fields: [tugasId], references: [id], onDelete: Cascade)

anakId String

urutanSoal String // JSON [3,1,5,2,4] shuffle index soal

urutanOpsi String // JSON [[2,0,3,1],...] shuffle opsi per soal

jawaban String @default("[]") // JSON [{soalIdx, opsiIdx}] locked saat dipilih

skor Int? // 0-100

benarCount Int?

totalSoal Int?

durasiDetik Int? // total waktu pengerjaan

status String @default("aktif") // aktif | selesai | reviewed

mulaiAt DateTime @default(now())

selesaiAt DateTime?

@@index([tugasId])

@@index([anakId])

}

4. Prompt Template (Gemini 2.5 Flash)

System: You are an educational quiz generator for children. Generate multiple-choice questions that are child-safe, age-appropriate, and contain NO violence, adult themes, or inappropriate content. Explanations must be simple enough for the target age to understand.

User: Generate [jumlah] multiple choice questions about [tema] for a [umur] year old student in [kelas], in [bahasa]. Difficulty level [1-5].

Difficulty guide:

Level 1: Simple recall, single-step, obvious answers.

Level 2: Basic application, single operation.

Level 3: Multi-step or word problems with context.

Level 4: Requires reasoning or combining concepts.

Level 5: Complex multi-step, advanced reasoning, near grade-level ceiling.

Return JSON array only, no markdown:

[

{

"question": "Sari punya 12 permen. Dia memberi 4 permen kepada Andi. Berapa permen Sari sekarang?",

"options": ["6", "8", "7", "9"],

"answer_index": 1,

"explanation": "12 - 4 = 8. Sari memberi 4 permen, jadi sisanya 8."

}

]

Safety: All content must be child-safe. No violence, adult themes, scary content, or inappropriate language.

Explanation: Must be simple enough for [umur] year old to understand. Use short sentences and concrete examples.

5. Fitur Utama & Actionable Checklist

A. Manajemen Tugas Manual (APK Ortu)

  • [x] Form buat tugas: judul, deskripsi, target anak, jumlah token
  • [x] Daftar tugas aktif per anak
  • [x] Approval system: ortu approve tugas selesai -> token masuk

B. AI Quiz Generator (APK Ortu)

  • [x] Form input tema/topik instan
  • [x] Filter profil anak (umur dari tanggalLahir, kelas)
  • [x] Slider kesulitan 1-5 (Pemula -> Expert)
  • [ ] Preview soal sebelum kirim ke anak
  • [ ] API: POST /api/tugas/ai-generate -> Gemini generate soal -> return preview
  • [ ] Soal validation: cek jawaban benar ada, format parse-able, tidak ambig. Retry 1x kalau gagal, skip kalau gagal lagi.
  • [ ] Content moderation: validasi output tidak mengandung konten tidak pantas. Keyword filter + Gemini safety settings.
  • [ ] Soal dedup: hash soal, skip duplikat dalam 30 hari.

C. Scheduled AI Tasks [BARU]

  • [ ] UI Scheduler di APK ortu: pilih anak (multiple), tema, kesulitan, jam, hari aktif
  • [ ] API CRUD: /api/jadwal-tugas-ai (GET, POST, PATCH, DELETE)
  • [ ] Cron worker: tiap menit cek jadwal aktif yang jamKirim = now -> generate via Gemini -> auto-publish ke daftar tugas anak
  • [ ] 1 jadwal multiple anak: cron generate soal terpisah per anak (profil beda = soal beda)
  • [ ] Auto-publish: tugas masuk ke antrian anak tanpa ortu klik manual
  • [ ] Token: tugas AI auto-publish TIDAK auto-claim. Anak kerjakan -> ortu approve -> token masuk. Kecuali ortu set auto-approve per jadwal.
  • [ ] Ortu notifikasi preference: pilih notif saat AI generate / anak selesai / anak buka tugas.

D. Sisi Klien Anak (APK Anak)

  • [ ] Notifikasi tugas baru (manual, instan, terjadwal)
  • [ ] UI pengerjaan soal + submit jawaban
  • [ ] Animasi token/ZX Coin saat approval
  • [ ] Offline mode: kuis yang sudah di-download bisa dikerjakan offline

6. Quiz Flow (Kuis Session)

6a. Mulai Kuis

  • Anak tap tugas kuis -> buat KuisSession (status=aktif)
  • Generate urutanSoal: shuffle index soal (Fisher-Yates)
  • Generate urutanOpsi: shuffle opsi per soal
  • Simpan ke session. Anak lihat urutan acak.
  • Timer mulai: record waktuMulai di Tugas.

6b. Lock Per-Soal

  • Anak tap opsi -> jawaban langsung LOCK, tidak bisa ubah.
  • UI: opsi terpilih highlight, opsi lain disabled.
  • Simpan jawaban ke session.jawaban.
  • Progress bar: "3/5 terjawab"

6c. Submit

  • Submit button disabled sampai semua soal dijawab.
  • Submit = final. Tidak ada undo.
  • Hitung skor: (benar / total) x 100.
  • Status session -> selesai. Tugas status -> done.
  • Simpan skor + benarCount + totalSoal + durasiDetik.

6d. Review Mode

  • Setelah submit: tampilkan tiap soal dengan:

- Jawaban anak (benar = hijau, salah = merah)

- Jawaban benar (highlight)

- Pembahasan/explanation text dari Gemini (simple, age-appropriate)

  • Anak tidak bisa mengulang jawab. Review = read-only.

6e. Retry & Token Balance

  • Anak bisa ulang kuis: buat KuisSession baru (urutan + opsi diacak ulang).
  • Token berdasarkan skor: rewardToken x (skor / 100). Misal: 10 token x 80% = 8 token.
  • Max retry per hari: default 3x (configurable per jadwal, 0 = unlimited).
  • Token diklaim berdasarkan skor SESI TERBAIK, bukan sesi terakhir. Misal: coba 1 = 60%, coba 2 = 80%, coba 3 = 70% -> token = rewardToken x 80%.
  • Cap: token tidak bisa melebihi rewardToken. Skor 100% = full rewardToken.
  • Token diklaim sekali per tugas. Setelah diklaim, retry tidak tambah token.

6f. Token & Approval

  • Setelah kuis selesai + skor dihitung -> token = rewardToken x (skorTerbaik/100).
  • Kalau auto-approve aktif: token langsung masuk dompet anak.
  • Kalau tidak: ortu approve dulu -> token masuk.
  • Ortu lihat detail: skor, jawaban salah, pembahasan, jumlah retry.

6g. Time Limit (Opsional)

  • Timer per kuis: default tidak ada timer (santai mode).
  • Ortu bisa enable timer per jadwal: misal 2 menit per soal, total 10 menit untuk 5 soal.
  • Waktu habis -> auto-submit jawaban yang sudah terjawab, soal kosong = salah.
  • Timer hanya berjalan saat app aktif (tidak countdown saat background).

7. Token & Reward Integration

  • Tugas selesai + ortu approve -> token masuk dompet anak.
  • Kuis: token = rewardToken x (skorTerbaik/100). Skor 0 = 0 token.
  • Token cap: maksimal rewardToken per tugas. Retry tidak tambah token.
  • Saldo token terhubung Marketplace (tukar hadiah).
  • Scheduled AI: reward token tetap dari setting jadwal, klaim setelah approval.

8. Adaptive Difficulty (Opsional, Post-MVP)

  • Sistem auto-suggest level: anak 5/5 benar -> suggest naik level.
  • Anak 2/5 -> suggest turun level.
  • Ortu tetap kontrol, sistem hanya suggest.

9. Progress Tracking (Opsional, Post-MVP)

  • Dashboard ortu: rata-rata skor per tema, per minggu.
  • Sari: Matematika 80%, Sains 60%.
  • Grafik sederhana: skor per sesi, trend naik/turun.

10. Streak & Gamification (Opsional, Post-MVP)

  • Streak: 7 hari berturut ngerjain tugas -> bonus token.
  • Badge: Quiz Master (50 kuis selesai), Perfect Score (5/5 10x).
  • Leaderboard optional (opt-in, privacy-aware).

11. Tier Gating

  • FREE_TRIAL: 1 jadwal AI aktif, kesulitan max 3.
  • ZX PRO: 3 jadwal AI aktif, kesulitan 1-5.
  • ZX ELITE: unlimited jadwal AI, kesulitan 1-5, adaptive difficulty, progress tracking, timer mode.

12. Pitfall

  • Gemini rate limit: 15 RPM free tier. Cron harus queue + retry, bukan fire-and-forget.
  • Cost: tiap generate ~1k token output. 100 anak x 1 jadwal/hari = ~100k token/hari. Monitor.
  • Fallback: kalau Gemini down, skip generate hari itu, jangan crash cron.
  • Timezone: jika dijual global, jamKirim harus pakai timezone per-ortu, bukan server time.
  • Auto-publish tanpa approval: pastikan ortu tahu tugas AI masuk otomatis. Notifikasi ke ortu saat AI generate.
  • DB migration: table baru, tidak break existing. Prisma db push auto-sync tiap deploy (Coolify start cmd).
  • Soal validation: Gemini bisa halusinasi jawaban salah atau format rusak. Validasi output sebelum insert.
  • Content moderation: Gemini bisa generate soal tidak pantas. Safety settings + keyword filter + system prompt instruction. Kritikal untuk app anak.
  • Soal dedup: tema sama + level sama hari berurutan -> soal mirip. Hash soal, skip duplikat 30 hari.
  • Data privacy: profil anak (umur, kelas) dikirim ke Gemini. Gender/agama tidak dikirim kalau tidak relevan.
  • Child timeout: tugas kuis tidak dijawab dalam 24 jam -> status expired. Ortu lihat tugas expired di dashboard.
  • FCM: perlu Firebase project + FCM token per device. Setup follow-up.
  • Token exploit: retry unlimited = spam sampai 100%. Solusi: max retry per hari + token dari skor terbaik + cap rewardToken.
  • Explanation readability: pembahasan harus sesuai umur anak. Prompt specify: simple enough for [umur] year old.
  • Offline sync conflict: jawaban offline sync saat online. Kalau tugas sudah expired saat sync, tolak jawaban.

13. Alur Cron

Setiap menit:

1. SELECT * FROM JadwalTugasAI WHERE aktif=true AND hariAktif contains today_weekday

2. Filter jamKirim = current HH:mm (timezone ortu)

3. Filter lastRun < today (sudah jalan hari ini? skip)

4. Untuk tiap jadwal:

a. Parse anakIds -> loop per anak

b. Fetch profil anak (tanggalLahir -> umur, kelas)

c. Call Gemini: generate soal berdasarkan tema + kesulitan + profil + bahasa

d. Validate output: parse JSON, cek answer_index valid, cek explanation ada

e. Content moderation: keyword filter + safety check

f. Dedup check: hash soal, skip kalau duplikat 30 hari

g. INSERT ke tabel Tugas (type: ai_scheduled, soal: JSON, rewardToken dari jadwal)

h. Update lastRun = now

i. Notifikasi push ke APK anak (FCM) — cek notifPref ortu

j. Notifikasi push ke APK ortu (info: AI generate tugas baru) — cek notifPref

5. Error handling: log + skip, jangan block jadwal lain

Ringkasan

Tugas = pekerjaan rumah/aktivitas yang ortu assign ke anak.

Flow:

1. Ortu buat tugas (judul, deskripsi, tokenReward, deadline)

2. Anak lihat tugas PENDING

3. Anak kerjakan → kirim foto bukti → status DIKUMPULKAN

4. Ortu validasi: SELESAI (token masuk) atau DITOLAK

Status: PENDING → DIKUMPULKAN → SELESAI/DITOLAK

Model: Tugas — anakId, judul, deskripsi, tokenReward, fotoBuktiUrl, status, validasiOrtu, deadline

API:

  • GET /api/tugas — list semua tugas anak ortu
  • POST /api/tugas — buat tugas
  • PATCH /api/tugas/[id] — validasi (selesai/tolak)

App ortu: LayarTugas.kt — list tugas per anak, form buat, validasi foto

App anak: lihat tugas, kirim foto bukti

Pitfall

⚠ deadline field ada di model+API tapi belum dipakai di UI app ortu

⚠ Foto bukti: upload mechanism belum fully implemented di app anak