Top up game favorit, langsung lewat WhatsApp.
🌐 Live: https://nexastoregame.vercel.app
A production-ready digital game top-up storefront with a multi-item cart, per-game account forms, admin & developer panels, total/route lockdown & maintenance modes, a file-based catalog that persists through GitHub, and a private Telegram bot for full remote control from the developer's pocket.
- Multi-item cart — collect up to 5 products across different games, each line with its own recipient data (Valorant asks for Riot ID, Mobile Legends asks for User ID + Zone ID, and so on — the form is generated from each game's field schema).
- One structured WhatsApp message for the whole cart: numbered items,
explicit account data per item, order reference (
NEXA-YYMMDD-XXXX), and a correct grand total. No JSON soup, no separate chats per product. - Two ways to order — press a product card for the instant single-item flow, or press Tambah to collect items into the cart and checkout once.
- Cart persistence — the cart survives reloads via
localStorage; stale entries (deleted/disabled products) are reconciled away with a clear notice. - Local order history — lightweight, clearly labeled as device-local.
- Trackable orders (v1.6.0) — every checkout (instant or cart) registers a
server-side order with ID
NEXA-YYMMDD-XXXX; the ID rides along in the WhatsApp message to the store and as a Telegram notification to the owner, and visitors follow the status (pending → processing → success/cancel + admin's reason) on the/trackpage. - Reports (v1.6.0) —
/reportslets visitors file bugs, feature requests or general messages, optionally with an image/video attachment (forwarded straight to the owner's Telegram with a timestamped, formatted card). - Web Push notifications (v1.6.0) — visitors who opt in (bell toggle in the chat widget) get a browser notification when the store replies, even after the tab is closed. VAPID keys, service worker, consent-first.
- Nexa Bot — AI chat agent with a two-stage brain (v1.19.0) — the
storefront chat is answered by Nexa Bot in seconds:
- Smart brain (LLM) — understands intent in any phrasing (typos, slang, mixed ID/EN), reasons over the live catalog (cheapest, budget fit, comparisons, recommendations), and replies in clean Markdown. Chat history gives it memory; a precomputed facts sheet keeps every price conclusion exact.
- Local brain (NLP fallback) — a trained @nlpjs/basic model answers instantly whenever the LLM is unavailable (offline / degraded).
- Transaction agent — "pesan 2000 diamonds rp246.000 ff" adds the exact
product to the visitor's cart, guides checkout in ≤ 5 steps, warns
which order fields are required, and auto-fills account data sent in
chat (
id saya 123456789) into the cart item.
- Scroll-aware edge fades — horizontal scrollers only dim the side where more content exists; the last card always renders at full strength.
- Dark / light / system themes, scroll-reveal animations,
prefers-reduced-motionrespected, keyboard-accessible flows, mobile-first checkout. - Footer with auto-year copyright and the developer credit (Dearly Febriano) + visible app version.
Admin panel (hidden route /login)
- Games, categories, products, prices — edited live with conflict detection (revision + per-file SHA) so two admins can't silently overwrite each other.
- Game icon upload (client-side canvas crop → WebP data URI).
- Store settings: name, WhatsApp number, announcement, maintenance mode.
- WhatsApp order template management with placeholder validation.
- Event promo & banner management — schedule store-wide or per-game discounts and announcement banners (same consoles as the Developer panel, permissions enforced server-side).
- Live chat replies — the admin answers visitor messages from the
storefront chat widget in
/admin/chat, with an unread badge on the sidebar. - Chat tools (v1.6.0) — search conversations by name/content, delete a single conversation, or clear all conversations (mirrored as buttons in the Telegram bot); visitors can also clear their own chat from the widget.
- Reports console (v1.6.0) —
/admin/reportslists incoming bug/feature reports with metadata and attachment indicators (media lives in Telegram). - No duplicated nav — sections shared by Admin & Developer (promo, banner, chat, reports) appear once in the sidebar (v1.6.0).
- Collapsible sidebar — the collapse toggle sits in the header next to the logo, with a global Ctrl/Cmd+B shortcut; state persists per browser.
- Admin blocking — a blocked admin cannot log back in (enforced server-side). The block reason set by the Developer is shown to the admin in a full-screen blocking modal (skull + block icon), both on a login attempt and as a live takeover of an already-active dashboard session.
- Kontrol Situs (site control):
- LOCKDOWN — total or route-scoped (
/,/games,/games/…,/help). Affected visitors are redirected to a red/lockdownscreen that shows the Developer's reason. Enforced server-side (no storefront flash) and on soft navigations. Staff routes (/login,/admin,/dev) are never gated so the gate can always be lifted. - Maintenance mode — total or route-scoped, amber
/maintenancescreen with the Developer's message and a retry button. - Bypass rules: Developer passes everything; Admin is exempt from maintenance but subject to lockdown. If both cover a route, lockdown wins.
- LOCKDOWN — total or route-scoped (
- Git sync status & history, data inspector, schema validation, diagnostics, deployment info.
- Catalog lives in canonical JSON files (
data/catalog/*.json,data/store/*.json), validated by Zod schemas + integrity rules (duplicate ids, orphan references, zero prices, …). - Two adapters:
local— read/write the JSON files (development, or read-only hosting).github— commits every mutation to the repo via the GitHub API (single-commit batch writes), so catalog edits on production survive redeploys. Selected automatically whenGITHUB_*env is complete.
- One-tap site control: activate/lift total lockdown, route-scoped lockdown, site-wide maintenance, or route-scoped maintenance — each with a custom reason/message that appears on the gate screen. Every action writes through the same conflict-detected API as the dashboard (so the GitHub-backed persistence and audit trail apply), then the sandbox repo auto-syncs.
- Deploy any past commit — list recent commits or production deployments, pick one, and Vercel rebuilds production from that exact sha (rollback). Build progress is monitored and reported back in chat.
- Admin access control — block/unblock the admin account with a reason, immediately revoking active sessions.
- Catalog management — add games (with a photo icon straight from Telegram), categories, and products; change prices; enable/disable games and products.
- Store settings — update the WhatsApp number and the storefront announcement; view the checkout template.
- Live status — gate states, catalog counts, app version, and the latest
Vercel build, in one
/statuscommand. - Chat notifications, two runtimes — visitor messages reach Telegram in
seconds: instantly via the local bot bridge (sandbox) or sent directly by
the deployed app through the Telegram Bot API (Vercel — needs only
TELEGRAM_BOT_TOKEN+ the owner pairing in thebot-statestore). No double pings: the instant bridge marks messages as notified so the 25-second watcher never repeats them. - Security: single-owner pairing code (first-run claim), silently rejects
every other account, secrets only in
.env(gitignored), and the bot talks to the site through the developer-authenticated API — never raw file writes. - Runs as an independent Bun service (port
3005for a health probe) with long polling; seemini-services/telegram-bot/README.md.
FIND GAME → CHOOSE PRODUCT → ADD TO CART → FILL ACCOUNT DATA → REVIEW → WHATSAPP
Cart review shows per-item completion status (2/5 item siap diproses),
incomplete items auto-expand, and the final review is an immutable snapshot
before the WhatsApp handoff.
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router) + TypeScript 5 |
| UI | Tailwind CSS 4, shadcn/ui (New York), Lucide icons |
| Animation | Framer Motion |
| State | Zustand (cart, persisted) + TanStack Query (server state) |
| Validation | Zod (catalog schemas, forms) + react-hook-form |
| Theme | next-themes (dark / light / system) |
| Tests | Bun test (63 unit tests) |
# 1. Install
bun install # or: npm install
# 2. Configure auth (required for the dashboard)
cp .env.example .env
# → fill AUTH_ADMIN_*, AUTH_DEVELOPER_*, SESSION_SECRET (openssl rand -hex 32)
# 3. Run
bun dev # or: npm run devOpen http://localhost:3000 — the storefront is public; the dashboard lives at
the unlinked route /login.
| Variable | Required | Purpose |
|---|---|---|
AUTH_ADMIN_EMAIL / AUTH_ADMIN_PASSWORD |
✅ | Admin dashboard credentials |
AUTH_DEVELOPER_EMAIL / AUTH_DEVELOPER_PASSWORD |
✅ | Developer credentials |
SESSION_SECRET |
✅ | HMAC key for the signed session cookie |
NEXT_PUBLIC_APP_VERSION |
– | Version label shown in the footer |
GITHUB_OWNER, GITHUB_REPOSITORY, GITHUB_BRANCH, GITHUB_TOKEN |
– | Enables GitHub-backed catalog persistence |
TELEGRAM_BOT_TOKEN + TELEGRAM_WEBHOOK_SECRET |
– | Enables the /api/telegram/webhook runtime — the Telegram bot runs on Vercel itself (24/7). NEXA_API_BASE, NEXA_DEV_EMAIL, NEXA_DEV_PASSWORD must also be set (the site's own URL + developer credentials) |
BOT_SERVICE_LAUNCH |
– | Sandbox only: enables POST /api/bot-service + instrumentation auto-revive for the polling bot |
Secrets live only in env vars — never in the repo, never in the client bundle.
The app is a standard Next.js project — deploy with one click:
- Import the repo into Vercel, framework preset Next.js.
- Add the environment variables above (Production + Preview).
- Deploy. The catalog (
data/**) is bundled into the serverless functions viaoutputFileTracingIncludes.
On serverless hosting the filesystem is read-only: set the
GITHUB_*variables to make admin catalog edits commit back to the repository. Without them the storefront is fully functional and the catalog is read-only.
src/
├─ app/ # App Router — storefront route + API + gate screens
│ ├─ api/ # catalog, auth, management, developer, store-status
│ ├─ lockdown/ # red LOCKDOWN gate screen (server-rendered reason)
│ ├─ maintenance/ # amber maintenance gate screen
│ └─ page.tsx # the storefront SPA shell (gates enforced here)
├─ components/
│ ├─ store/ # storefront views + cart (drawer, item cards) + gate/
│ ├─ admin/ # admin panel views (management shell + Ctrl+B)
│ ├─ developer/ # developer tools (access, site control, git, data…)
│ ├─ shared/ # theme toggle, reveal, price tag, dialogs…
│ └─ ui/ # shadcn/ui primitives
├─ proxy.ts # propagates the original pathname for gate enforcement
└─ lib/
├─ catalog/ # domain: schemas, validation, mutations, repositories, site-control
├─ cart/ # cart store, resolver, validation, WA message builder
├─ auth/ # session (HMAC cookie), credentials, permissions, site gates
└─ whatsapp/ # template engine + deep link builder
data/
├─ catalog/ # games / products / categories (canonical JSON)
└─ store/ # settings, checkout template, access control (blocks + gates)
mini-services/
└─ telegram-bot/ # developer Telegram bot (Bun service, port 3005)
├─ src/ # config, telegram, nexa (store API), vercel, gitops, ui, handlers
└─ .env.example # bot token, pairing code, developer credentials, Vercel/GitHub keys
- Signed, HTTP-only session cookies; timing-safe credential comparison; server-side permission matrix (admin vs developer) on every protected route.
- Login rate limiting; blocked-admin enforcement on session + route level.
- Site gates are Developer-only writes through the same conflict-detected repository as the catalog; the store-status probe is role-aware so gate bypasses can't be forged from the client.
- The public catalog API never exposes disabled records or adapter internals.
- Cart state is client-owned but prices are always resolved from the live catalog — client-side price tampering has no effect.
- All browser input is treated as untrusted: persisted cart state is shape- checked and capped; template rendering is placeholder-allowlisted.
bun test # 63 unit tests: schemas, integrity, template, auth, mutations
bun run lint # eslint
npx tsc --noEmit # type checkThis project follows semantic versioning with unbounded minor/patch
components: bug fixes after 1.9.9 ship as 1.9.10, 1.9.11, …; features
after 1.9.210 ship as 1.10.210, 1.11.210, …; only a genuinely massive
rework (UI/backend/language overhaul) jumps to the next MAJOR (2.0.0).
The current version is visible in the storefront footer and in
package.json / src/lib/version.ts.
- 💸 nexa-budget.js — kalkulator budget — "modal 50rb bisa top up apa?", "budget 15 ribu di ml?" dijawab INSTAN dan presisi dari data live: produk yang benar-benar muat (nominal terbesar per game), fokus otomatis ke game yang disebut, saran termurah bila budget kurang. Pola nexa-math (deteksi pola → hitung → render) — identik di sandbox & produksi, tanpa LLM.
- 🧠 Arsitektur dua-otak final — endpoint API LLM bersifat internal
(IP privat, hanya dari jaringan sandbox), maka: sandbox memakai otak
LLM penuh (pemahaman maksud, penalaran, memori obrolan); produksi
memakai lapisan deterministik + NLP terlatih ulang — semua instan. Env
ZAI_*dicabut dari Vercel (mencegah penalti 10 dtk koneksi gagal). - 🔍 Diagnostik mesin jawaban — respons chat menyertakan
botEngine(llm/local/fast) + kategori kegagalan LLM (timeout/network/http) — tanpa rahasia;GET /api/chatikut melaporkan status otak. - 🐛 Fix: deteksi game pada kalimat bertanda baca ("di ml?", "buat free fire?") dan pemilihan nominal terbesar per game pada daftar budget.
- ⚡ Thinking mode dimatikan — inferensi lebih cepat; ketepatan angka (termurah/termahal/budget) tetap terjamin lembar PRECOMPUTED FACTS yang dihitung presisi di server.
- ⏱️ Timeout LLM 9s → 20s + maxDuration 30 — egress Vercel → API lebih lambat daripada sandbox; budget waktu fungsi dinaikkan agar jawaban LLM sempat tiba (sebelumnya diam-diam timeout → jatuh ke NLP cadangan).
- 🔁 Ulang sekali dengan sisa anggaran — kegagalan singkat (<3 dtk) dicoba ulang memakai sisa waktu, tidak pernah melebihi batas fungsi.
- 📦 SDK ikut ter-bundle di
api/chat.js—includeFilesvercel.json memastikanz-ai-web-dev-sdktersedia di dalam Serverless Function (sebelumnya dynamic import gagal di bundel @vercel/node → endpoint publik diam-diam mundur ke NLP). - 💎 Deteksi produk bonus — format katalog memakai field
bonus(33 produk), bukan tanda "+" di denominasi (0 produk) — jawaban "rekomendasi value" yang sebelumnya selalu KOSONG kini menampilkan daftar produk berbonus; fallback daftar termurah bila tidak ada bonus sama sekali. - 🔍 Diagnostik otak —
GET /api/chatkini melaporkan status otak LLM (tersedia/tidak + sumber koneksi) tanpa membocorkan rahasia.
- 🧠 Dua-otak: LLM + NLP — pipeline chat baru: lapisan deterministik (keamanan → status pesanan → kalkulator → agent keranjang → resolver katalog → overlay dataset kustom) → OTAK LLM (pemahaman maksud + penalaran data live) → NLP lokal sebagai cadangan bila LLM tak tersedia. Pertanyaan terbuka seperti "game yang punya product paling murah, sebutin 1 saja" kini dijawab dengan kesimpulan yang benar dari data sungguhan.
- 🔍 Pemahaman semua bahasa — LLM membalas dengan bahasa yang sama dengan pengguna (default Indonesia gaul); typo, slang, singkatan, dan campuran ID/EN dipahami. Riwayat obrolan (12 pesan terakhir) ikut dikirim — bot punya memori percakapan.
- 📊 Fakta terhitung (selalu akurat) — konteks LLM memuat lembar fakta terverifikasi: produk termurah/termahal, jumlah game/produk, termurah per game, dan analisis budget ("modal 50rb bisa apa?" → daftar produk yang muat dihitung presisi di server, LLM tinggal merangkai).
- 🤖 Aksi agent dari LLM — niat pesan yang lolos dari lapisan
deterministik tetap bisa memicu aksi
add_to_cart/fill_datalewat blok aksiactionyang divalidasi terhadap katalog live (produk tak dikenal dibuang diam-diam). - 🐛 Fix: angka telanjang menimpa data akun — "kalo yang 5000 diamonds
berapa?" tidak lagi dianggap pengiriman data akun (sebelumnya menimpa
Player ID dengan
5000); pertanyaan berbau "berapa/harga/?" kini dijawab sebagai pertanyaan harga. - 📚 Korpus diperkaya + latih ulang — 40+ varian kosakata nyata untuk pertanyaan termurah/budget ("game yang punya product paling murah", "modal 50 ribu bisa apa", …); model.nlp + nexa-brain.js dilatih ulang (76/76 sanity + 9/9 guard lolos).
- 📡 Sinkron lintas kanal — otak LLM aktif di chat web (engine Next),
fungsi publik
api/chat.js, dan bot Telegram (nexa-standalone) — tanpa keranjang di kanal terakhir, jawaban menautkan halaman game. SDK tersambung via.z-ai-config(sandbox) atau envZAI_*(produksi Vercel — terpasang, terenkripsi). - 🖥 Panel AI developer — kartu status "Otak cerdas LLM" (aktif/nonaktif
- sumber koneksi) di panel AI Bot.
- ✅ 0 temuan di pemindai
/debugging(sebelumnya 2 medium): komentar chart tidak lagi memicu aturan XSS (self-match),/api/section-errormasuk allowlist rute publik-by-design (zod + rate-limit ketat, tanpa tulis data store).
- 📎 Media laporan tersimpan permanen — lampiran gambar/video /reports
kini disimpan di
data/media/reports/(dual-mode: sandbox FS / GitHub Contents API di produksi) dan bisa dilihat langsung di konsol Laporan: thumbnail di kartu + klik → modal preview penuh (gambar/video player) + tombol unduh. Laporan lama pra-v1.8.0 tampil keterangan media arsip. - 📨 Perbaikan: media tidak sampai ke Telegram — notifikasi laporan
(foto/video), chat, dan pesanan kini dijadwalkan lewat
after()Next.js: dieksekusi terjamin SETELAH respons terkirim. (Akar masalah:void promisebisa ter-freeze runtime serverless Vercel sebelum upload selesai.) + fallbacksendDocumentbilasendPhotoditolak. - 🧯 Circuit breaker — isolasi kegagalan agar bug tidak merambat:
- API: breaker
github-api&telegram-api(4 kegagalan beruntun → sirkuit terbuka 45–60 dtk → fail-fast tanpa menunggu timeout; half-open probe → pulih otomatis).readFeaturetidak pernah melempar error ke halaman (default aman) — GitHub down tidak menjatuhkan storefront. - UI:
SectionBoundarymengisolasi setiap bagian halaman (header, konten per view, footer, chat widget, tiap konsol panel) — satu bagian error menampilkan fallback + tombol coba lagi, sisanya tetap hidup. - Observabilitas: error UI yang tertangkap boundary dilaporkan otomatis
ke Telegram pemilik (
/api/section-error, rate-limit + throttle 5 dtk). - Jaring terakhir:
error.tsx+global-error.tsxroute-level.
- API: breaker
- 🔒 Temuan /debugging diperbaiki —
ignoreBuildErrorsdinonaktifkan (tipe harus bersih sebelum rilis) dandangerouslySetInnerHTMLdi chart diganti injeksitextContentvia ref (tidak ada jalur injeksi HTML). - 🧹 Higienis data — hapus laporan (satu/semua) kini juga menghapus file
medianya; laporan yang tergeser batas 200 → media orphan ikut dibersihkan;
commit media (
media:*) di-skip vercel.json agar tidak memicu rebuild.
- 🔍
/debuggingdi Telegram — bot memindai kode situs ini sendiri dan melaporkan temuan ke pemilik: 13 aturan regex per-baris (token bot/PAT/ Vercel tertanam,eval/new Function, XSSinnerHTML, injeksi shellexecterinterpolasi,execSync, log kredensial,ignoreBuildErrors, URL http, TODO/FIXME) + pemeriksaan struktural (route API mutasi tanpa guardrequireCapability, dengan allowlist route yang dijaga mekanisme lain). Sumber kode adaptif: disk lokal di panel, GitHub Trees+Contents API di Vercel (anggaran 25 dtk, 10 worker paralel). Laporan jujur — di uji sandbox ia menemukan 2 temuan nyata tanpa false positive. Route webhook kinimaxDuration = 60agar pemindaian serverless selesai.
- 📦 Lacak pesanan end-to-end — checkout instant & keranjang kini
membuat rekaman pesanan ber-ID
NEXA-YYMMDD-XXXX(tersimpan di data store, write-through GitHub). ID tercantum di pesan WhatsApp + notifikasi Telegram dengan tombol status; admin/dev mengubah status (pending/processing/ success/cancel) + keterangan lewat bot/lacak_orderatau API — dan pengunjung membacanya di halaman/track(navbar: Lacak Pesanan). - 🚩 Halaman Laporan
/reports— bug/saran/lainnya + lampiran gambar/video (≤2.5MB/4MB) diteruskan ke Telegram pemilik dengan format waktu WIB, nama, dan tipe; metadata tersimpan dan tampil di panel/admin/reports(hapus satu / hapus semua). - 🔔 Web Push (opt-in) — tombol bel di widget chat: izin browser → langganan VAPID → balasan pemilik jadi notifikasi browser meski tab tertutup. Langganan kedaluwarsa dibersihkan otomatis.
- 🗑 Obrolan bisa dibersihkan dua arah — pengunjung hapus obrolan sendiri (ikon tempat sampah + konfirmasi); admin/dev hapus satu percakapan atau semua (tombol juga ada di bot Telegram). Pencarian percakapan di panel (nama/isi pesan) + tombol 🔍 Cari di bot.
- 🎨 Logo baru — “N” emas dengan sparkle (upload pemilik) dipasang di header, footer, login, widget chat, layar admin-blocked + favicon.
- 🧭 Navbar & footer — link baru: Lacak Pesanan, Laporan.
- 🧹 Panel anti-dobel — section bersama admin/dev tampil sekali.
- 🔑 Login sandbox = produksi — kredensial sandbox disinkronkan dari env produksi agar pemilik bisa menguji di preview panel dengan akun yang sama.
- 🤖 Bot:
/lacak_orderterdaftar di menu "/" (17 perintah); notifikasi pesanan baru dengan tombol status; pesan laporan pengguna masuk ke chat pemilik. Pair code tetapNEXA-STORE-2026.
- 💬 Obrolan di panel Admin — Admin kini bisa membalas pengunjung lewat
/admin/chat(bukan cuma Developer): item nav “Obrolan” dengan badge merah jumlah pesan belum dibaca, aksi cepat “Balas obrolan” di dashboard, izin dikontrol server-side lewat capabilitychat.manage. - 📩 Notifikasi chat ke Telegram — dua jalur:
- Sandbox: bridge instan dipulihkan (env
BOT_SERVICE_INTERNAL_URL+ rahasia bersamaBOT_INTERNAL_SECRET) — pesan pengunjung ping Telegram dalam hitungan detik lengkap dengan tombol balas interaktif. - Produksi (Vercel): aplikasi kirim sendiri lewat Telegram Bot API saat
bridge tidak ada — cukup env
TELEGRAM_BOT_TOKEN+ pairing pemilik di data storebot-state; tombol “Balas di dashboard” menuju/admin/chat.
- Sandbox: bridge instan dipulihkan (env
- 🐛 Fix notifikasi ganda — pesan yang sudah di-ping bridge ditandai
(
markNotified) sehingga chat-watcher 25 detik tidak mengirim ulang. - 🐛 Fix listener bot saat hot reload — listener HTTP lama ditutup penuh
sebelum bind baru (race EADDRINUSE senyap) + socket.io di-attach ulang;
tambah log
[bridge]untuk observabilitas. - 🐛 Fix tombol URL Telegram — tombol hanya dikirim untuk URL
https://(Telegram menolakhttp://); pesan tetap terkirim tanpa tombol di uji lokal. - Pairing pemilik bot disinkronkan ke data store
bot-state(chat id untuk jalur notifikasi produksi).
Bot Telegram kini bisa berjalan langsung di Vercel — tidak lagi mati saat panel sandbox berganti sesi:
- ⚡ Runtime Ganda — perintah
/runtime(atau tombol di menu utama) memindahkan bot antara panel (polling, fitur lengkap) dan Vercel (webhook serverless, aktif 24/7). Poller panel otomatis standby saat webhook aktif dan mengambil alih kembali begitu webhook dilepas — tanpa konflik 409. - ** Endpoint webhook**
POST /api/telegram/webhook— menjalankan kode bot yang sama di dalam fungsi serverless; pairing pemilik tersimpan permanen di data store (ops:*, tanpa rebuild) sehingga aman dari cold-start. - ☰ Menu perintah
/— 16 perintah terdaftar viasetMyCommands: mengetik/di chat langsung memunculkan daftar lengkap dengan deskripsi; setiap perintah membuka menu yang sama dengan tombolnya. - 🛡️ Self-healing —
src/instrumentation.tsmemantau layanan bot; mati/ter-restart dinyalakan ulang otomatis (cek 60 dtk saat gagal, 10 mnt saat sehat). Guard dobel-proses: health + PID file. - 🏷️ Promo & Banner di panel Admin — sidebar Admin kini punya Event Promo dan Banner (konsol yang sama dengan Developer); izin dikontrol capability
promos.manage/banners.managedi server. - 🐛 Fix — kolom nama di widget chat tidak lagi menutup diri saat huruf pertama diketik (commit-on-blur + chip identitas “Sebagai …” dengan tombol Ubah).
- Infra: alias
@bot/*di tsconfig; gitops tetap jalan tanpa GITHUB_TOKEN (akses publik); state bot aman untuk Vercel (BOT_STATE_FILE,/tmp).
Lima fitur baru di panel Developer + bot Telegram, semuanya berjalan tanpa deploy (data dibaca saat runtime):
- 💬 Obrolan Langsung — widget chat di storefront; pesan pengunjung masuk ke Telegram & panel
/dev/chat; balas dari Telegram atau panel, tersampa instan via WebSocket (fallback polling). Tanpa akun: identitas perangkat acak yang di-hash. - 🏷️ Event Promo — diskon terjadwal global/per-game; harga promo otomatis di kartu produk, keranjang, dan pesan WhatsApp (harga asli dicoret + label hemat); strip countdown di seluruh situs.
- 📣 Banner Pengumuman — pita pengumuman 4 level (info/sukses/peringatan/penting) dengan tombol CTA + jadwal tayang; terbit ke semua halaman publik ≤30 detik.
- 📊 Analitik Pengunjung — pelacakan pihak pertama (views, unik, referrer, perangkat, interaksi), pengunjung live (jendela 5 menit), grafik tren 30 hari, digest harian otomatis 21:00 WIB ke Telegram.
- ⏰ Tugas Terjadwal — otomasi berwaktu: maintenance/lockdown/banner/promo/announcement/pengingat; dieksekusi layanan bot 24/7, hasil dilaporkan ke Telegram.
Infra: vercel.json ignoreCommand — commit data (store:/chat:/analytics:/ops:) tidak memicu build. Sidebar developer +5 entri. SemVer minor.
- Live chat — a floating chat widget on the storefront; visitor messages
reach the owner on Telegram and in
/dev/chatwithin seconds, and replies land instantly over WebSocket (HTTP polling fallback in production). - Promo engine — scheduled global or per-game discount events; effective prices propagate to product cards, cart, checkout, and the WhatsApp message (strikethrough originals + savings note) with a countdown strip site-wide.
- Announcement banners — four severity levels with optional CTA buttons and publish windows, delivered to every open storefront within 30 seconds.
- Visitor analytics — first-party page views, uniques, referrers, devices, interaction funnels, a live visitor counter, a 30-day trend chart, and an automatic 21:00 WIB Telegram digest.
- Scheduled tasks — time-based automation (maintenance/lockdown windows, banner and promo scheduling, announcement sets, reminders) executed by the always-on bot service with Telegram result notifications.
- Added:
@nexastoregamebot— a private Telegram bot that gives the developer full remote control of the store, with inline buttons and guided text input for every flow (runs as an independent Bun service insidemini-services/telegram-bot, health probe on port 3005). - Bot — site control: total lockdown, route-scoped lockdown, site-wide maintenance, and route-scoped maintenance, each collecting a reason/message before a confirmation step; lifting gates is one tap away.
- Bot — deployment: redeploy any past commit (list from GitHub or from existing Vercel deployments) — Vercel builds production from the chosen sha and the bot reports back when the build finishes.
- Bot — admin access: block/unblock the admin with a reason (sessions are revoked server-side, exactly like the dashboard flow).
- Bot — catalog: add games with an icon (photo sent straight in chat), add categories, add products (game → name → denomination → price → bonus), change product prices, and enable/disable games & products.
- Bot — settings & status: update the WhatsApp number and announcement;
/statusshows gate states, catalog counts, app version, and the latest production build. - Bot — security: first-run pairing code claims the single owner slot;
all other accounts are rejected; the bot authenticates to the site as the
developer through the same HMAC-cookie API (no bypasses, no raw writes);
secrets stay in a gitignored
.env. - Version semantics: feature release → minor bump (
1.1.1→1.2.0).
- Fixed: game icons missing in the admin dashboard's Game dengan produk terbanyak list and in every row of the Produk table — the uploaded icons now render (letter monogram stays as fallback only).
- Fixed: login page is now pinned to the viewport — the page itself never scrolls at any height (content adapts via clamp; only the form column may scroll internally when a mobile keyboard shrinks the screen).
- Fixed: the security note on the login brand panel now matches the type scale and alignment of the feature list above it (deliberate footer strip).
- Fixed: dashboard sidebar no longer scrolls horizontally when collapsed — group labels become slim dividers in the icon rail.
- Security: staff surfaces no longer reveal the existence of developer
mode to Admins — the sidebar hint is gone,
/dev/*renders the same 404 as any unknown address for Admins, API 403s use one generic message, and gate pages no longer offer a "Masuk sebagai staf" link. - Improved: Kontrol Situs explains why the Developer never sees the gate screens (session bypass) and adds a one-click preview of the lockdown / maintenance page as visitors see it.
- Version semantics: bug-fix + hardening release → patch bump (
1.1.0→1.1.1).
- Added: Developer Kontrol Situs — total or route-scoped lockdown
(
/lockdown, red, reason shown) and maintenance mode (/maintenance, amber, message shown), enforced server-side before the storefront renders plus on client-side navigation; role-aware bypass (Developer all, Admin maintenance only); public/api/store-statusprobe. - Added: blocked-admin takeover modal (skull + block icon + the Developer's reason) on login attempts and mid-session revocations.
- Added: sidebar collapse toggle in the header next to the logo with a global Ctrl+B shortcut.
- Added: footer developer credit (Dearly Febriano → portfolio) and auto-year copyright.
- Improved: login page brand panel — tilted mini-storefront + floating product cards from the live catalog, dark lighting, entrance & drift animations.
- Fixed: featured-games scroller kept darkening the rightmost card at scroll end (static edge mask replaced with a scroll-aware one).
- Version semantics: feature release → minor bump (
1.0.0→1.1.0).
- Storefront with multi-item cart, per-game account forms, one structured WhatsApp checkout; admin & developer panels; conflict-detected catalog mutations; hidden login route; dark/light themes; game icon upload; admin blocking; 61 seeded products across 8 games.
Released under the MIT License — © 2026 neuralforgeio. Developed with 💛 by Dearly Febriano.

