Dashboard generate & publish artikel promosi otomatis untuk ekosistem Z (ZPos, ZXGym, ZXRoom, Zomet, ZXParenting). Cron harian generate artikel via Gemini, publish ke markdown zomet-main + API publik untuk landing page tiap app.
Dashboard otomasi konten promosi untuk ekosistem aplikasi Z. Generate artikel SEO harian via Gemini AI, publish ke zomet-main (markdown) + API publik untuk landing page tiap app.
1. POST /api/artikel/trigger (GitHub Actions 07:00 WIB)
2. publishScheduled() - publish artikel scheduledFor=today
3. generateSatuArtikel() per app - generate artikel baru today+3 hari
4. Setiap app punya ZADV_API_URL env -> fetch /api/artikel/publik?appId=X
| App | appId | Domain |
|-----|-------|--------|
| Z1Pos | 4 | z1pos.zomet.my.id |
| ZXGym | 5 | zxgym.zomet.my.id |
| ZXRoom | 8 | zxroom.zomet.my.id |
| Zomet | 9 | www.zomet.my.id |
| ZXParenting | 10 | zxparenting.zomet.my.id |
- /api/artikel/publik — publik, no auth
- /api/artikel/trigger — cron, X-Cross-App-Secret header
- /api/artikel/foto — CRUD foto pool
- /api/artikel/settings — autopost config
- /api/artikel/riwayat — admin, cookie auth
ArtikelDraft — artikel (status: draft|scheduled|published) ArtikelFoto — foto pool (url, useCount) ArtikelIde — bank ide artikel per app Pengaturan — key-value settings PromoApp — daftar app (appId, nama, url, artikelAktif)
ArtikelDraft — artikel (status: draft|scheduled|published)
ArtikelFoto — foto pool (url, useCount)
ArtikelIde — bank ide artikel per app
Pengaturan — key-value settings
PromoApp — daftar app (appId, nama, url, artikelAktif)
### External Integration - **GitHub API**: push markdown ke repo djvpri/zomet-main/content/artikel/ - **Google Gemini**: generate judul, deskripsi, konten, tags - **Coolify auto-deploy**: GitHub App webhook trigger rebuild
1. GitHub Actions trigger POST /api/artikel/trigger
2. publishScheduled() — cek artikel status=scheduled, scheduledFor=today
- Push markdown ke zomet-main GitHub (jika tujuanZomet=true)
- Set status=published, publishedAt=now()
3. generateSatuArtikel() per app (yang punya web URL)
- Ambil ide dari ArtikelIde (atau generate via Gemini)
- ambilFoto() — foto random dari pool, set gambarPath + fotoId
- Gemini generate konten lengkap (judul, deskripsi, tags, body markdown)
- Save ke ArtikelDraft dengan status=scheduled, scheduledFor=today+3
4. Pre-generate (manual via dashboard)
- Generate N hari ke depan sekaligus
ZADV_API_URL=https://zpromo.zomet.my.id/api/artikel/publik?appId=X&limit=N (ISR revalidate 300s)imgUrl() helper convert relative /api/uploads/... → absolute https://zpromo.zomet.my.id/api/uploads/.../api/artikel/foto (POST multipart)/app/public/uploads/artikel/ (container volume mount)ArtikelFoto table: {id, url, filename, useCount}/api/uploads/artikel/artikel-<timestamp>-<random>.jpegambilFoto() di src/lib/artikel.ts — foto random, prefer useCount=0generateDraft() set gambarPath: foto.url + fotoId: foto.iduseCount saat foto dipakai/api/uploads/[...path] route handler serve file statis| appId | Nama | Domain | Artikel Aktif |
|-------|------|--------|---------------|
| 1 | ZGold | — | ❌ |
| 2 | ZBengkel | — | ❌ |
| 3 | ZBilliar | — | ❌ |
| 4 | Z1Pos | z1pos.zomet.my.id | ✅ |
| 5 | ZXGym | zxgym.zomet.my.id | ✅ |
| 6 | Z-Resto | — | ❌ |
| 7 | Z-Absen | — | ❌ |
| 8 | ZXRoom | zxroom.zomet.my.id | ✅ |
| 9 | Zomet | www.zomet.my.id | ✅ |
| 10 | ZXParenting | zxparenting.zomet.my.id | ✅ |
Hanya app dengan url tidak null + artikelAktif=true yang di-generate artikelnya.
| Var | Value | Purpose |
|-----|-------|---------|
| ADMIN_PASSWORD | (secret) | Login dashboard |
| DATABASE_URL | postgresql://... | PostgreSQL connection |
| GITHUB_TOKEN | github_pat_... | Push markdown ke zomet-main repo |
| GEMINI_API_KEY | AIza.../AQ... | AI generate artikel |
| ZADV_PUBLIC_URL | https://zpromo.zomet.my.id | Base URL untuk image absolute |
| X_CROSS_APP_SECRET | z-ecosystem-admin-2026 | Auth trigger endpoint |
| Var | Value |
|-----|-------|
| ZADV_API_URL | https://zpromo.zomet.my.id |
Set di Coolify DB environment_variables table. Note: Coolify v4.4.6 bug — env tidak auto-generate di .env, perlu append manual + docker compose up -d --force-recreate.