App ortu pantau anak β tugas, reward, screen time
Semua modul backend ZX Parenting telah diimplementasi dan deployed.
1. Bank Soal + Rekomendasi + Cross-Language β 6 endpoint
2. Screen Time + Hard Cap β 4 endpoint
3. Adaptive GPS + Geofencing β 2 endpoint
4. Master Toggle 2-layer PIN+OTP β 2 endpoint
5. Anti-cheat Pattern Detection β 2 endpoint
6. Foto Bukti Auto-delete 30 hari β 1 endpoint
7. Multi-device Registration β 2 endpoint
8. Forum AI Moderation β 3 endpoint
9. Curfew Auto-lock β 1 endpoint
10. Cold Start Bot Seed β 1 endpoint
11. Google Play Billing (verify, acknowledge, RTDN) β 3 endpoint
12. Laporan Phase 1 Ringkasan β 1 endpoint
13. Laporan Phase 2 Tren Mingguan β 1 endpoint
14. Laporan Phase 3 Bulanan β 1 endpoint
15. Laporan Phase 4 AI Insights β 1 endpoint
Cleanup: lib/midtrans.ts dihapus, langganan checkout+webhook deprecated (410 Gone).
Schema: PlayPurchase model, Langganan midtransOrderId β purchaseToken + productId.
Aplikasi parenting terpadu β ortu pantau anak (tugas, reward, screen time, lokasi).
3 komponen:
ZX-Parenting-ortu, local /opt/data/zx-ortuzx-agent, local /opt/data/zx-agentzx_parenting, local /opt/data/zx_parentingVersi: v3.3.0 (versiKode 52)
URL: https://zxparenting.zomet.my.id
Deploy: Coolify id9, DB container soqw27wuaccobs7z2prztkct
CI: auto-trigger push; rilis manual rilis.yml workflow_dispatch input versi
Version config: alamat.json (versiNama, versiKode, idPaket, beranda, api, googleWebId)
Ekonomi:
Anti-bypass: Device Admin API (Play Store compliant), Accessibility Service hanya untuk kuis lock.
Data privacy: Foto bukti auto-delete 30 hari (fotoExpireAt). Gender/agama optional (UU PDP).

Feature graphic
App Ortu:
App Anak:
Backend:
Deploy:
pd59y3gb3k6nkqjqvm873uim-* (ID berubah tiap deploy)soqw27wuaccobs7z2prztkctpsql -U postgres -d postgres25+ Prisma models:
Auth & User:
User β PARENT/CHILD/ADMIN, email/passwordHash/googleId, username+pinHash (CHILD), locale, consentAnak β 1:1 dengan User (CHILD), tanggalLahir, kelas, gender (optional), agama (optional), dormantDeviceRegistration β daftar device per anak (multi-device), deviceName, isActive, revokedAtEkonomi Anak (Token ZX):
TokenBalance β saldo per anakTokenLedger β KUIS/TUGAS/CHALLENGE/FAMILY_QUEST/PINJAM/BAYAR_PINJAM/PEMAKAIAN/PENYESUAIAN/OFFICIAL_KUIS/OFFICIAL_TANTANGANPinjamWaktu β amount, createdAt, expireAt (24h), lunasEkonomi Ortu (ZX Coin):
CoinWallet β saldo per ortuCoinLedger β TOPUP_IAP/PEMBELIAN/PENJUALAN/REFERRAL/BONUS/PENYESUAIANLangganan:
Langganan β FREE_TRIAL/PRO/ELITE, Google Play purchaseToken, subscriptionState, autoRenewingPlayPurchase β productId, purchaseToken, orderId, verifiedAt (RTDN webhook verification)Tugas & Kuis:
Tugas β PENDING/DIKUMPULKAN/SELESAI/DITOLAK, fotoBuktiUrl, fotoExpireAt (auto-delete 30 hari), deadlineKuisAttempt β soal JSON (Gemini-generated), jawaban, skor, levelKesulitan, durasiDetik, flagged (anti-cheat)Bank Soal (Persistent Question Bank):
BankSoal β mataPelajaran, kelas, levelKesulitan (1-5), tipeSoal (PILIHAN_GANDA/ESSAY), pertanyaan, pilihanGanda, jawabanBenar, penjelasan, bahasa ("en"/"id"), source (AI/ORTU/MARKETPLACE), createdBy, tags[], ratingSum, ratingCount, translateFlagBankSoalTerjemahan β bankSoalId, bahasa, pertanyaan, pilihanGanda, jawabanBenar, penjelasan, translatedAt (cached translation)BankSoalRate β bankSoalId, userId, rating (up/down), createdAtGamifikasi:
Streak β current/terbaik/terakhirChallengeProgress β challenge harian per anakFamilyQuest + FamilyQuestMember β quest keluargaOfficialCompletion β tracking complete official contentDevice Control:
DeviceSession β sessionLimit, cooldown, dailyLimit (hard cap 3 jam), curfew, appBlokir, GPS, geo-fenceActivityLog β app_open/browser/quiz_lock/geo_exitGpsLog β lastSpeed, lastInZone, pollInterval (adaptive: 5/15/2/1/3 min)Marketplace:
KontenMarketplace β PAKET_SOAL/PRESET/KUIS_HARIAN/ARTIKEL/VIDEO/TANTANGAN_MINGGUANPembelianKonten β 1x beli per kontenOfficialMeta β scheduling, targeting, metricsHadiah + PesananHadiah β marketplace hadiah ortuWithdrawal β MINTA/DISETUJUI/DITOLAK/SELESAI (payout via bank transfer manual)Komunikasi:
Pesan β direct chat ortuβanakForumPost + ForumKomentar β forum keluarga (AI moderation flag)Moderasi:
ModerasiLog β type (keyword_filter/report_block), target, reason, timestamp~60 API routes (Next.js App Router):
Auth:
POST /api/auth/native-login β login ortu (email+password)POST /api/auth/native-daftar β daftar ortuPOST /api/auth/native-google β Google OAuth ortuPOST /api/auth/native-anak β login anak (username+PIN), JWT, rate limit 5/min, lockout 10β15minAnak (CRUD):
GET/POST /api/anak β list/create, GET flatten username+umur calcGET/PATCH/DELETE /api/anak/[id] β detail/edit/hapusPATCH /api/anak/[id]/pin β reset PIN (validasiPin, bcrypt)PATCH /api/anak/[id]/dormant β toggle dormantDevice:
GET /api/device-session β listPATCH/DELETE /api/device-session/[id] β edit/hapusPOST /api/device/register β daftar device anak (multi-device)DELETE /api/device/[id] β revoke deviceGET /api/device/gps β GPS log + adaptive polling intervalTugas & Kuis:
GET/POST /api/tugas β list/createPATCH /api/tugas/[id] β validasi (selesai/tolak)POST /api/tugas/ai-generate β Gemini generate soalPOST /api/tugas/jadwal β CRUD scheduled AI tasksGET /api/tugas/[id]/kuis β kuis session (shuffle, lock, submit, review)Bank Soal:
GET /api/bank-soal β list/filter (mataPelajaran, kelas, level, bahasa)POST /api/bank-soal β simpan soal manualGET /api/bank-soal/rekomendasi?anakId=X β rule-based recommendation (avg skor per mataPelajaran, level adaptif, filter duplikat)POST /api/bank-soal/[id]/rate β ortu rate thumbs up/downPOST /api/bank-soal/tugas β create Tugas dari soal bankPOST /api/bank-soal/[id]/translate β trigger translate on-demand + cache (Gemini translate, cached permanently)Ekonomi:
GET/POST /api/coin β saldo + penyesuaianGET /api/token-ledger β riwayat token anakGET/POST /api/pinjam β pinjam waktu (max 30 min, 24h expiry) + hutangGET/POST /api/hadiah β marketplace hadiahPOST /api/hadiah/pesanan β proses pesanan (beli/tolak)GET/POST /api/marketplace β konten marketplacePOST /api/marketplace/beli β beli kontenPOST /api/marketplace/withdrawal β tarik coin (min 50k, max 500k/bln, fee 10%, delay 3 hari, payout bank transfer)Gamifikasi:
GET /api/leaderboard β ranking (bot label "Official" sampai >50 user)GET/POST /api/challenges β daily challenges + claimGET/POST /api/quests β family questGET /api/anak/streak β streak dataGET/POST /api/referral β kode referral + claimKomunikasi:
GET/POST /api/pesan β direct chatGET/POST/DELETE /api/forum β forum posts (AI moderation filter)POST /api/forum/[id]/komentar β komentarPOST /api/forum/[id]/report β laporkan postLangganan (Google Play Billing):
GET /api/langganan/status β status langganan (FREE_TRIAL/PRO/ELITE)POST /api/langganan/verify β verify purchase token dari app (Google Play Developer API)POST /api/langganan/rtdn β Real-Time Developer Notifications webhook (Google Pub/Sub)POST /api/langganan/acknowledge β acknowledge purchaseAI:
GET /api/insights β insights anak (Gemini/rule-based)POST /api/admin/generate β generate soal/preset (Gemini)GET /api/tugas/[id]/anti-cheat β pattern detection flagLaporan:
GET /api/laporan/ringkasan β agregasi tugas+kuis+streak+token (v3.3.0)GET /api/aktivitas β activity log anakOfficial Content:
GET /api/anak/official β feed anakGET /api/anak/official/[id] β detailPOST /api/anak/official/[id]/complete β selesai + rewardGET/POST/PATCH/DELETE /api/admin/official β admin CRUDAdmin:
GET /api/admin/users β list usersGET /api/admin/metrics β metricsGET/POST /api/admin/konten β konten managementGET/POST /api/admin/withdrawal β withdrawal managementLain:
DELETE /api/akun/hapus β hapus akunβ umur dihapus dari schema, diganti tanggalLahir DateTime?. Umur dihitung server-side dari tanggalLahir. App tampilkan ? jika null.
β Tanggal lahir server kirim ISO 8601 (2019-04-19T00:00:00.000Z). App pakai fmtTgl() substring(0,10) β yyyy-MM-dd.
β PIN blacklist (66 PINs: sequential+repeated 4/5/6 digit). 123456 = sequential naik β ditolak API. Existing PIN (1234) tidak di-retroactive reject.
β Reset PIN bug (3 iterasi):
1. v2.9.5: dialog fire-and-forget β async callback
2. v2.9.6: state.error global tidak reliable β pesan langsung dari callback
3. v2.9.7: dua tombol Simpan di satu dialog β pisah DialogResetPin
β App container ID berubah tiap deploy Coolify. Cari via sudo docker ps.
β DB akses: SSH VPS β sudo docker exec soqw27wuaccobs7z2prztkct psql -U postgres -d postgres.
β Login anak JWT: POST /api/auth/native-anak, header Authorization: Bearer <token>.
β Validasi username: regex /^[a-z0-9_]{3,20}$/, reserved words set, P2002 catch β 409.
β Rate limit in-memory Map (single instance Coolify). 5/min per IP+username, lockout 10 gagalβ15min.
β Play Store risk: Accessibility Service untuk anti-uninstall bisa kena ban. Pakai Device Admin API sebagai utama. Accessibility hanya untuk kuis lock (justified use case). Siapkan policy justification untuk Google Play review.
β Token inflation: hard cap 3 jam/hari. Token = kuota dalam cap, bukan override. Pinjam waktu tidak override cap. Tanpa cap, anak rajin-soal β main 5 jam.
β Data sensitif anak (UU PDP): gender/agama optional, hanya simpan kalau ortu isi. Tidak dikirim ke Gemini. Anak = subjek khusus, perlu consent ortu eksplisit.
β Multi-device bypass: screen time sync per-anak (bukan per-device). Device tidak terdaftar = tidak ada enforcement. Ortu harus daftar semua device anak.
β Foto bukti: fotoExpireAt di Prisma, cron job hapus harian. Auto-delete 30 hari setelah tugas selesai/divalidasi. Tidak pernah dipakai AI training.
β Google Play Billing: wajib verify purchase token server-side via Google Play Developer API. Jangan trust client-side purchase data. Gunakan RTDN (Real-Time Developer Notifications) untuk subscription state changes (cancel/refund/renew). Acknowledge purchases dalam 24 jam atau auto-refund.
β Google Play fee: 15% (first $1M/year) / 30% (above). Harga tier harus factoring fee ini. ZX Coin sebagai buffer β ortu beli coin via IAP, pakai coin di marketplace, fee Google sekali di top-up.
v3.3.0 (kode 52) β tab Laporan compact: 4 kartu stat + AI insight + ringkasan tugas + laporan kuis + statistik token + timeline aktivitas. Backend /api/laporan/ringkasan.
v3.2.5 β app anak v1.8.2: fix kuis + offline mode
v3.2.1-v3.2.4 β generate soal AI v2 rewrite, OkHttp timeout 60s, UI fix
v3.2.0 β generate tugas AI (backend + UI app ortu)
v3.1.0 β menu Tugas di blueprint Engine
v3.0.0 β blueprint Engine launch (wiki simpan blueprint app)
v2.9.7 β pisah dialog reset PIN dari dialog edit anak
v2.9.6 β pesan error langsung dari callback (bukan state.error global)
v2.9.5 β dialog tunggu API respond + loading + error display
v2.9.4 β edit username anak + reset PIN + brute-force + PIN blacklist + reserved username
v2.9.3 β fix tanggalLahir ISO 8601 display (fmtTgl substring)
v2.9.2 β DatePicker native + dropdown gender
v2.9.1 β edit + hapus anak, umurβtanggalLahir
v2.9.0 β referral + leaderboard + challenges
v2.8.0 β pinjam waktu + AI insights
v2.7.1 β i18n (locale field)
Roadmap berikutnya:
{
"type": "service_account",
"project_id": "zxparenting",
"private_key_id": "212e27f4910755e2b2c2f59667291cfdf0d6fe1f",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCwPc4ZDzGnRQPL\nnb9CTUn+dc7IQSXaVgbXa4qrq6TF/ADr+phcV2OOvHTVcowf5FyJKnqptybto2oL\n8eL7phlSyJOJEWcseXLzqynax+ChBDIlds/S7Q+Qb6ct7gn8ihpEbsD3bDy03WhL\nfeZIMnQ6w1Xvd8tSCxxKjCh8V6diygdCmUmfn/A8dhZ5npWWGoUtj7FkTDlI12pN\nPIA4yBI430X2qhYRiqWxFzlKzeoB0+BxkGR9rUzvK2jFz3cj1x14dfpTWgGZGw17\nTyqfDQW+AwHXgyq7utkaDOyX/K8H4CUQZ9QjFPSOncxJNBVwqvpdRi4RhXOBTZMa\n+Ep1CUn3AgMBAAECggEAEom1u4oPGX6XaxwBKaqyjUr8ALFll2U0HAWqVOtdjhu3\nRxsZWqEwjiuBiJAfcB1XpG/s7hwfQqDNP0tmqjyq7ju91Q2ZEiMGNd47rVEX7ifg\nVHN+YbvgxrsP1TN0JnWqVKdnsb7XVdjyJvqrtc1kz2eLiwBJSSx1AdxjR8z6hNf5\nhSbtao6plOm0PTWxhmTR1WERyrDKzQGMwxpFBc/lKz42QSBf9pVJUDBxsH3Gkzc2\nrpjBve9M/zvURPnfyXp01YG0rwB5IPgmDOy5SHk5TbTOdS9p5CgUKNe34wLG0ikL\naJKUSWPd7EXEvcl0UXYP8F4NbXUcxIrDzqM9X95/QQKBgQDkWTCbvc+rCLOV2+1P\nBRNrZgYxeZ/qpCf5b5KV8ZK+K68Zj6xzkFeDOUl8xIAXd2PfQfeui3XpzMztmNx4\nN7Xm+TTPonVLeHs8KbBFPQcNma9gjxr3bpsg3dflzdz5agMZ32WoRVuZuAWj8qQw\nVr42IqB2TBvRtV2crQobZP2BQQKBgQDFlUv9Ib2yaupTWZF1pvsr5Qbr79m5slHn\nHwXN+ic8WnR3qlB22jTdhm0E4yo5hTpKY417ooUdx9r/3wzZ/uSme75iPUgob33k\njYL2MskXp55S6B32OlC/IH1EVa0v2oMiRHMqB2wsd97rp7dsOa5TR/+KORKTa0ng\nIfKQw7xFNwKBgH4jLpC5dz+5XMqJZDtkSGfpQb6OuuG4sEQ/d6/QdAkMxHrQPKjR\nsSXRvWBog4Fy9/5ZyGHos8fk08bjy9W0oIzoWF3iFf0MnraLKM32ejDvFku2gWTw\n+kxbf2l4IHq+LtxZ5SPgvErbtnHsFPqG0CfDVPRD8pITJ5TmmVCspsSBAoGAXgYM\n8jmjPwtX1TAzY0yCDEJhx9cMwiyUgyqlJX7cOwFEmUmIHvb5301ABepgRp0avxme\n023kcOaRVd/8CqUchAkw8Sj+dJeRzjh1UNmcDlCqrANfdrQLhthcJC+tSa9vZdgz\nAZYkqQimIXhfdfYA+gqyFUHRkCunLSyadL9gkYMCgYEAu2C3lvknXK0/fu51rzZR\nYr1D5nMTVeak8aCL7mXbAsAGy4PD+lo5uRICx4yOoUA7Wvp9PYztdZc/deSYUNTy\nw+3VfK44CGNw8qNmVxtbGfoJ/2kvwJ1oKh/ED3BNI9akmtMisn0D9q0pa6egmk7k\n0bDlf/h+dDFv2FT2AhnRDXA=\n-----END PRIVATE KEY-----\n",
"client_email": "zx-parenting-billing@zxparenting.iam.gserviceaccount.com",
"client_id": "107387419850321250664",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/zx-parenting-billing%40zxparenting.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}