Platform REST API SaaS siap produksi dengan landing page SEO, dashboard analitik, dokumentasi API interaktif, autentikasi JWT, tier langganan premium, leaderboard, dan panel admin.
Built by github.com/eliasilyz
- Fitur
- Tech Stack
- Struktur Project
- Database & Schema
- Keamanan (Security)
- Cara Menjalankan Project
- Konfigurasi Environment
- Tier & Langganan
- API Endpoint Catalog
- Manajemen Admin
- Demo Akun
- Perintah Berguna
- Landing Page SEO — Hero, kategori API, contoh kode, pricing, JSON-LD structured data untuk Googlebot
- Dokumentasi API Interaktif — Daftar endpoint yang bisa di-collapse/expand, search real-time, try-it-out, contoh cURL & JavaScript
- Leaderboard Global — Peringkat pengguna berdasarkan total request dan durasi premium
- SSR SEO Page — Route
/api/landingmenghasilkan HTML statik untuk crawler mesin pencari
- Dashboard Overview — Statistik total request, kuota harian/bulanan, success rate, grafik aktivitas, status kesehatan endpoint
- Manajemen API Key — Buat, lihat, hapus, dan regenerate API key dengan prefix aman
- Request Logs — Riwayat request dengan filter endpoint, status, dan rentang tanggal + paginasi
- Analitik Mendalam — Grafik harian & bulanan, breakdown per endpoint, average response time
- Manajemen Langganan — Lihat plan aktif, upgrade/downgrade tier, cek tanggal kedaluwarsa
- Statistik Platform — Total user, request hari ini, pendapatan, API key aktif, error rate
- Manajemen User — Ubah role (user/admin), tier, nonaktifkan akun, hapus user
- Toggle Endpoint — Aktifkan/nonaktifkan endpoint katalog secara langsung
- Global Logs — Lihat log request seluruh pengguna platform
| Lapisan | Teknologi |
|---|---|
| Frontend | React 19, Vite 7, TypeScript |
| Styling | Tailwind CSS v4, shadcn/ui, Recharts |
| Routing (FE) | Wouter |
| State / Data Fetching | TanStack Query (React Query) |
| Backend | Express 5, Node.js 24, TypeScript |
| Database | PostgreSQL (Drizzle ORM) |
| Validasi | Zod (zod/v4), drizzle-zod |
| Auth | JWT (access token 15 menit, refresh token 7 hari), bcrypt |
| API Contract | OpenAPI 3.0 → Orval codegen (React Query hooks + Zod schemas) |
| Build Tool BE | esbuild (bundle tunggal ESM) |
| Monorepo | pnpm workspaces |
| Logging | pino + pino-http |
workspace/
├── artifacts/
│ ├── api-platform/ # Frontend React + Vite (preview path: /)
│ │ └── src/
│ │ ├── pages/ # Landing, Login, Register, Docs, Leaderboard, Dashboard, Admin
│ │ ├── components/ # UI components (shadcn/ui + custom)
│ │ └── lib/auth.tsx # AuthContext + JWT token management
│ └── api-server/ # Backend Express (preview path: /api)
│ └── src/
│ ├── routes/ # auth, users, apikeys, logs, analytics, subscriptions,
│ │ # leaderboard, endpoints, admin, ssr
│ ├── middlewares/ # authenticate, requireAdmin
│ └── lib/ # auth utils (JWT sign/verify, API key generator)
├── lib/
│ ├── api-spec/ # openapi.yaml — sumber kebenaran contract API
│ │ └── orval.config.ts # Konfigurasi codegen Orval
│ ├── api-client-react/ # Generated React Query hooks (hasil codegen)
│ ├── api-zod/ # Generated Zod schemas (hasil codegen)
│ └── db/ # Drizzle ORM: schema, migrations, client
│ └── src/schema/ # users, api_keys, request_logs, subscriptions, endpoint_catalog
├── scripts/ # Script utilitas workspace
├── pnpm-workspace.yaml # Workspace packages + catalog dependencies
├── tsconfig.base.json # Shared TypeScript config
└── replit.md # Dokumentasi internal project
Database: PostgreSQL (tersedia via environment variable DATABASE_URL)
ORM: Drizzle ORM dengan drizzle-zod untuk validasi otomatis
| Kolom | Tipe | Keterangan |
|---|---|---|
id |
serial PK | ID unik pengguna |
name |
text | Nama lengkap |
email |
text UNIQUE | Email login |
password_hash |
text | Hash bcrypt (cost 10) |
role |
enum | user | admin |
tier |
enum | free | basic | pro | enterprise |
total_requests |
integer | Akumulasi total request |
avatar_url |
text | URL foto profil (opsional) |
created_at |
timestamptz | Waktu registrasi |
| Kolom | Tipe | Keterangan |
|---|---|---|
id |
serial PK | |
user_id |
integer FK | Referensi ke users.id |
token |
text UNIQUE | Nilai refresh token |
expires_at |
timestamptz | Kedaluwarsa (7 hari) |
created_at |
timestamptz |
| Kolom | Tipe | Keterangan |
|---|---|---|
id |
serial PK | |
user_id |
integer FK | Pemilik key |
name |
text | Label key (misal: "Production Key") |
key_hash |
text UNIQUE | SHA-256 hash dari key asli |
prefix |
text | 8 karakter pertama key (ditampilkan di UI) |
is_active |
boolean | Status aktif |
total_requests |
integer | Jumlah request menggunakan key ini |
last_used |
timestamptz | Terakhir digunakan |
created_at |
timestamptz |
| Kolom | Tipe | Keterangan |
|---|---|---|
id |
serial PK | |
user_id |
integer FK | Pengguna yang melakukan request |
endpoint |
text | Path endpoint yang dipanggil |
method |
text | HTTP method (GET/POST/dll) |
status_code |
integer | HTTP status response |
response_time |
integer | Latensi dalam milidetik |
ip_address |
text | IP pengirim request |
created_at |
timestamptz | Waktu request |
| Kolom | Tipe | Keterangan |
|---|---|---|
id |
serial PK | |
user_id |
integer FK | Pelanggan |
plan_id |
text | free | basic | pro | enterprise |
plan_name |
text | Nama tampilan plan |
status |
text | active | cancelled | expired |
start_date |
timestamptz | Mulai berlangganan |
end_date |
timestamptz | Kedaluwarsa langganan |
duration_days |
integer | Durasi dalam hari |
| Kolom | Tipe | Keterangan |
|---|---|---|
id |
serial PK | |
name |
text | Nama endpoint (misal: "Text Generation") |
path |
text | Path API (misal: /v1/ai/text/generate) |
method |
text | HTTP method |
category |
text | ai | image | data |
description |
text | Deskripsi fungsi |
is_available |
boolean | Apakah endpoint aktif |
min_tier |
text | Tier minimum yang dibutuhkan |
parameters |
jsonb | Daftar parameter (nama, tipe, required, deskripsi) |
example_request |
text | Contoh request body (JSON string) |
example_response |
text | Contoh response body (JSON string) |
# Push perubahan schema ke database (dev)
pnpm --filter @workspace/db run push
# Generate migration files
pnpm --filter @workspace/db run generate
# Jalankan migrations
pnpm --filter @workspace/db run migrate- Password di-hash menggunakan bcrypt (cost factor 10) — tidak pernah disimpan plaintext
- Access Token — JWT HS256, kedaluwarsa 15 menit, payload:
{ userId, role, tier } - Refresh Token — JWT HS256, kedaluwarsa 7 hari, disimpan di database untuk revokasi
- Token disimpan di
localStoragedi sisi client dan dikirim via headerAuthorization: Bearer <token>
- Key asli hanya ditampilkan sekali saat pembuatan (tidak disimpan di DB)
- Database hanya menyimpan SHA-256 hash dari key + 8 karakter prefix untuk identifikasi di UI
- Format key:
dapi_<random_hex>
- Semua route dashboard membutuhkan Bearer token valid
- Route admin membutuhkan
role === "admin"(middlewarerequireAdmin) - Input divalidasi dengan Zod schema di setiap route handler
| Variable | Keterangan |
|---|---|
DATABASE_URL |
Connection string PostgreSQL |
SESSION_SECRET |
Secret untuk signing JWT (wajib diganti di produksi) |
PORT |
Port server (otomatis di-set oleh runtime) |
NODE_ENV |
development atau production |
Penting: Ganti
SESSION_SECRETdengan string random yang kuat (minimal 32 karakter) sebelum deploy ke produksi.
- Node.js v20+ (disarankan v24)
- pnpm v9+
- PostgreSQL database (bisa menggunakan Replit built-in DB)
git clone <repo-url>
cd workspace
pnpm installBuat file .env atau set environment variables:
DATABASE_URL=postgresql://user:password@host:5432/dbname
SESSION_SECRET=ganti-dengan-secret-yang-sangat-kuat-minimal-32-karakter
NODE_ENV=developmentpnpm --filter @workspace/db run pushBackend (Terminal 1):
pnpm --filter @workspace/api-server run devServer berjalan di port yang ditentukan env PORT (default: 8080). Semua route tersedia di /api/...
Frontend (Terminal 2):
pnpm --filter @workspace/api-platform run devFrontend berjalan di port 23225 (atau sesuai konfigurasi Vite).
Untuk mengisi data awal (endpoint catalog + akun demo), jalankan query berikut atau gunakan API register:
# Registrasi akun demo via API
curl -X POST http://localhost:8080/api/auth/register \
-H "Content-Type: application/json" \
-d '{"name":"Demo User","email":"demo@example.com","password":"demo123!"}'Project ini sudah dikonfigurasi untuk Replit. Cukup klik Run dan kedua workflow (frontend + backend) akan berjalan otomatis:
artifacts/api-platform: web— Frontend React/Viteartifacts/api-server: API Server— Express backend
| Variable | Wajib | Default | Keterangan |
|---|---|---|---|
DATABASE_URL |
Ya | — | PostgreSQL connection string |
SESSION_SECRET |
Ya | — | Secret JWT signing key |
PORT |
Tidak | 8080 | Port backend server |
NODE_ENV |
Tidak | development |
Mode aplikasi |
| Tier | Harga | Request/Hari | Request/Bulan | Rate Limit |
|---|---|---|---|---|
| Free | Gratis | 100 | 3.000 | 10 req/s |
| Basic | $9/bulan | 1.000 | 30.000 | 50 req/s |
| Pro | $29/bulan | 10.000 | 300.000 | 200 req/s |
| Enterprise | $99/bulan | Unlimited | Unlimited | 1.000 req/s |
curl -X POST http://localhost:8080/api/subscriptions/upgrade \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"planId":"pro"}'| Method | Path | Keterangan |
|---|---|---|
| POST | /api/auth/register |
Daftar akun baru |
| POST | /api/auth/login |
Login, dapat access + refresh token |
| POST | /api/auth/logout |
Revoke refresh token |
| POST | /api/auth/refresh |
Perbarui access token |
| GET | /api/auth/me |
Info pengguna saat ini |
| Method | Path | Keterangan |
|---|---|---|
| GET | /api/apikeys |
List semua API key milik user |
| POST | /api/apikeys |
Buat API key baru |
| DELETE | /api/apikeys/:id |
Hapus API key |
| POST | /api/apikeys/:id/regenerate |
Regenerate API key |
| Method | Path | Keterangan |
|---|---|---|
| GET | /api/analytics/summary |
Ringkasan: total request, success rate, kuota |
| GET | /api/analytics/daily |
Data harian 30 hari terakhir |
| GET | /api/analytics/monthly |
Data bulanan 12 bulan terakhir |
| GET | /api/analytics/endpoints |
Statistik per endpoint |
| GET | /api/logs |
Request logs (filter: endpoint, status, tanggal) |
| Method | Path | Keterangan |
|---|---|---|
| GET | /api/subscriptions/plans |
Daftar semua plan tersedia |
| GET | /api/subscriptions/current |
Langganan aktif user saat ini |
| POST | /api/subscriptions/upgrade |
Upgrade/downgrade plan |
| Method | Path | Keterangan |
|---|---|---|
| GET | /api/endpoints |
Semua endpoint katalog |
| GET | /api/endpoints/health |
Status kesehatan setiap endpoint |
| GET | /api/leaderboard |
Leaderboard (query: type=usage|premium) |
| Method | Path | Keterangan |
|---|---|---|
| GET | /api/admin/stats |
Statistik platform global |
| GET | /api/admin/users |
Daftar semua user (+ search, paginasi) |
| PATCH | /api/admin/users/:id |
Ubah role/tier/status user |
| DELETE | /api/admin/users/:id |
Hapus user |
| GET | /api/admin/logs |
Log request semua user |
| GET | /api/admin/endpoints |
Katalog endpoint (admin view) |
| PATCH | /api/admin/endpoints/:id/toggle |
Toggle aktif/nonaktif endpoint |
- Login dengan akun yang memiliki
role: admin - Buka
/admin— menu akan muncul otomatis untuk admin - Atau gunakan akun demo:
admin@devapihub.app/admin123!
Via UI: Panel Admin → tab Users → klik akun → ubah role/tier
Via API:
curl -X PATCH http://localhost:8080/api/admin/users/5 \
-H "Authorization: Bearer <admin_token>" \
-H "Content-Type: application/json" \
-d '{"role":"admin","tier":"pro"}'Via UI: Panel Admin → tab Endpoints → klik toggle
Via API:
curl -X PATCH http://localhost:8080/api/admin/endpoints/3/toggle \
-H "Authorization: Bearer <admin_token>"Fitur ini tersedia dari Dashboard → API Keys → tombol Regenerate.
| Password | Role | Tier | |
|---|---|---|---|
demo@devapihub.app |
demo123! |
user | Pro |
admin@devapihub.app |
admin123! |
admin | Enterprise |
# Typecheck semua package
pnpm run typecheck
# Regenerate API hooks dari OpenAPI spec
pnpm --filter @workspace/api-spec run codegen
# Build backend
pnpm --filter @workspace/api-server run build
# Push perubahan schema DB (dev only)
pnpm --filter @workspace/db run push
# Jalankan backend saja
pnpm --filter @workspace/api-server run dev
# Jalankan frontend saja
pnpm --filter @workspace/api-platform run dev- Tambahkan entry di tabel
endpoint_catalogvia SQL atau API admin - Update
lib/api-spec/openapi.yamljika endpoint benar-benar diimplementasi di backend - Jalankan
pnpm --filter @workspace/api-spec run codegenuntuk regenerate hooks - Implementasi route handler di
artifacts/api-server/src/routes/ - Daftarkan router baru di
artifacts/api-server/src/routes/index.ts
MIT — bebas digunakan dan dimodifikasi.
Built by github.com/eliasilyz