Home›Zpromo (Zadv)
AKTIF1.0zadvartikelcrongeminiseolanding

Zpromo (Zadv)

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.

JSON

💡 Ide & Konsep

Zpromo (Zadv)

Tujuan

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.

Arsitektur

  • Frontend: Next.js 15 + Tailwind, dashboard zpromo.zomet.my.id
  • DB: PostgreSQL (Coolify), Prisma ORM
  • AI: Google Gemini 2.5 Flash untuk generate judul/deskripsi/konten/tags
  • Storage: Foto pool ArtikelFoto, upload via /api/uploads/
  • Publish: GitHub API (zomet-main markdown) + API publik (app landing)

Cron Harian

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

Foto Pool

  • Upload foto di dashboard -> ArtikelFoto table
  • generateDraft() ambil foto random, set gambarPath + fotoId
  • Foto accessible via /api/uploads/artikel/xxx.jpeg (HTTP+HTTPS)

API Endpoints

  • GET /api/artikel/publik?appId=X&limit=N
  • GET /api/artikel/publik/[slug]
  • POST /api/artikel/trigger (X-Cross-App-Secret header)
  • POST /api/artikel/pre-generate
  • GET/POST /api/artikel/foto
  • GET/POST /api/artikel/settings
  • GET /api/artikel/riwayat

App Mapping (appId)

| 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 |

Environment

  • ADMIN_PASSWORD - login dashboard
  • DATABASE_URL - PostgreSQL
  • GITHUB_TOKEN - push markdown ke zomet-main
  • ZADV_PUBLIC_URL - base URL image (https://zpromo.zomet.my.id)
  • GEMINI_API_KEY - AI generate
  • X_CROSS_APP_SECRET - auth trigger

Arsitektur Sistem

Komponen Utama

Frontend (Dashboard)

  • Next.js 15 + Tailwind CSS
  • Domain: zpromo.zomet.my.id
  • Halaman: Dashboard, Foto Pool, Artikel Riwayat, Settings

Backend API

  • Next.js Route Handlers (App Router)
  • Prisma ORM + PostgreSQL (Coolify managed)
  • Endpoints:

- /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

Database Schema

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

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

Flow Generate Artikel

Cron Harian (07:00 WIB)

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

App Landing Fetch

  • Setiap app (ZPos, ZXGym, ZXRoom) punya env ZADV_API_URL=https://zpromo.zomet.my.id
  • Landing page fetch /api/artikel/publik?appId=X&limit=N (ISR revalidate 300s)
  • imgUrl() helper convert relative /api/uploads/... → absolute https://zpromo.zomet.my.id/api/uploads/...

Foto Pool

Upload & Storage

  • Upload foto via dashboard → /api/artikel/foto (POST multipart)
  • File disimpan di /app/public/uploads/artikel/ (container volume mount)
  • Record di ArtikelFoto table: {id, url, filename, useCount}
  • URL format: /api/uploads/artikel/artikel-<timestamp>-<random>.jpeg

Usage di Artikel

  • ambilFoto() di src/lib/artikel.ts — foto random, prefer useCount=0
  • generateDraft() set gambarPath: foto.url + fotoId: foto.id
  • Increment useCount saat foto dipakai

Akses Publik

  • /api/uploads/[...path] route handler serve file statis
  • No auth required
  • Accessible via HTTP + HTTPS (Traefik TLS certresolver)

App Mapping

Daftar App (PromoApp table)

| 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.

Environment Variables

Container Env (Coolify)

| 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 |

App Env (ZPos, ZXGym, ZXRoom)

| 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.