Back to Blog
Membina Expense Tracker dengan Cloudflare Stack
cloudflare javascript pwa tutorial

Membina Expense Tracker dengan Cloudflare Stack

Panduan teknikal bagaimana saya membina aplikasi pengurusan kewangan menggunakan Cloudflare Workers, D1, dan Pages

Saya baru sahaja menyiapkan projek sampingan - sebuah aplikasi pengurusan kewangan peribadi yang dibina sepenuhnya menggunakan teknologi Cloudflare. Dalam artikel ini, saya akan berkongsi seni bina teknikal dan keputusan reka bentuk yang dibuat.


Tech Stack

KomponenTeknologi
FrontendHTML, CSS, JavaScript (Vanilla)
Backend APICloudflare Workers + Hono.js
DatabaseCloudflare D1 (SQLite)
AuthenticationJWT + bcrypt
HostingCloudflare Pages
PWAService Worker untuk offline support

Mengapa Cloudflare?

Saya memilih Cloudflare stack kerana beberapa sebab:

  1. Serverless sepenuhnya - Tiada pelayan untuk diurus
  2. Global edge network - Respons pantas dari mana-mana lokasi
  3. Kos rendah - Free tier sangat generous untuk projek peribadi
  4. D1 Database - SQLite yang di-host, mudah untuk schema migrations
  5. Integrasi Pages + Workers - Deploy frontend dan API dari satu repository

Seni Bina Sistem

┌─────────────────┐     ┌─────────────────────────────┐
│  Cloudflare     │     │  Cloudflare Workers         │
│  Pages          │────▶│  (Hono.js REST API)         │
│  (Frontend)     │     │                             │
└─────────────────┘     └─────────────┬───────────────┘


                        ┌─────────────────────────────┐
                        │  Cloudflare D1              │
                        │  (SQLite Database)          │
                        └─────────────────────────────┘

Ciri-ciri Utama

1. Multi-User Authentication

  • Pendaftaran dan log masuk dengan email/password
  • Password hashing menggunakan bcrypt
  • JWT tokens dengan 7 hari expiry
  • Session management via localStorage

2. Pengurusan Perbelanjaan & Pendapatan

Dashboard dengan ringkasan kewangan

  • Rekod transaksi dengan kategori
  • Periode kewangan bulanan (24hb - 23hb)
  • Sokongan untuk description/catatan
  • Import/export data JSON

3. Senarai Transaksi

Senarai perbelanjaan mengikut kategori

4. Laporan & Analitik

Laporan tahunan dengan trend bulanan

  • Dashboard dengan ringkasan
  • Carta pecahan mengikut kategori (Doughnut chart)
  • Trend bulanan (Bar chart)
  • Laporan tahunan dengan kadar simpanan

5. Progressive Web App (PWA)

  • Boleh di-install pada telefon
  • Responsive design untuk mobile dan desktop
  • Dark theme dengan glassmorphism UI

6. Admin Panel

  • Pengurusan pengguna
  • Statistik penggunaan
  • Padam akaun pengguna

Deployment ke Cloudflare Pages + D1

Berikut adalah langkah-langkah lengkap untuk deploy aplikasi ke Cloudflare Pages dengan D1 database.

1. Struktur Projek

Pastikan struktur projek anda seperti berikut:

expense-tracker/
├── frontend/           # Static files (HTML, CSS, JS)
├── functions/          # Cloudflare Pages Functions (API)
│   └── api/
│       └── [[route]].js
├── src/
│   └── db/
│       └── schema.sql  # Database schema
├── wrangler.toml       # Konfigurasi Wrangler
└── package.json

2. Konfigurasi wrangler.toml

Fail wrangler.toml adalah kunci untuk menghubungkan Pages dengan D1:

name = "expense-tracker"
compatibility_date = "2024-01-01"

# D1 Database binding
[[d1_databases]]
binding = "DB"
database_name = "expense-tracker-db"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Nota: database_id akan diperolehi selepas anda create database di langkah seterusnya.

3. Mencipta D1 Database

Jalankan arahan berikut dalam terminal:

# Login ke Cloudflare (jika belum)
npx wrangler login

# Create database baru
npx wrangler d1 create expense-tracker-db

Selepas run, anda akan mendapat output seperti:

✅ Successfully created DB 'expense-tracker-db'

[[d1_databases]]
binding = "DB"
database_name = "expense-tracker-db"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Copy database_id ini ke dalam wrangler.toml anda.

4. Setup Database Schema

Jalankan migration untuk create tables:

# Local development
npx wrangler d1 execute expense-tracker-db --local --file=./src/db/schema.sql

# Production
npx wrangler d1 execute expense-tracker-db --remote --file=./src/db/schema.sql

5. Deploy ke Cloudflare Pages

Terdapat dua cara untuk deploy:

Cara A: Melalui Cloudflare Dashboard (Disyorkan)

  1. Pergi ke Cloudflare DashboardWorkers & Pages
  2. Klik CreatePagesConnect to Git
  3. Pilih repository GitHub/GitLab anda
  4. Konfigurasi build settings:
    • Build command: (kosongkan untuk static files)
    • Build output directory: frontend
  5. Klik Save and Deploy

Cara B: Menggunakan Wrangler CLI

npx wrangler pages deploy frontend --project-name=expense-tracker

6. Binding D1 ke Pages Project

Ini adalah langkah paling penting yang sering terlepas pandang:

  1. Pergi ke Cloudflare DashboardWorkers & Pages
  2. Pilih Pages project anda
  3. Pergi ke SettingsFunctionsD1 database bindings
  4. Klik Add binding:
    • Variable name: DB
    • D1 database: Pilih expense-tracker-db
  5. Klik Save

⚠️ Penting: Tanpa langkah ini, Pages Functions tidak akan dapat akses database!

7. Environment Variables (Jika Perlu)

Untuk secrets seperti JWT_SECRET:

  1. Pergi ke SettingsEnvironment variables
  2. Tambah variables yang diperlukan:

8. Custom Domain (Optional)

  1. Pergi ke Custom domains dalam Pages project
  2. Klik Set up a custom domain
  3. Masukkan domain anda (contoh: duit.hafism.xyz)
  4. Cloudflare akan auto-configure DNS dan SSL

9. Local Development

Untuk development di local machine:

# Start local server dengan D1
npx wrangler pages dev frontend --d1=DB=expense-tracker-db

Ini akan start local server di http://localhost:8788 dengan akses kepada local D1 database.


Kemaskini: Ciri Pengurusan Hutang

Dikemaskini: 28 Disember 2025

Satu ciri pengurusan hutang yang komprehensif telah ditambah ke aplikasi Expense Tracker, membolehkan pengguna menjejaki hutang peribadi, ansuran kad kredit, dan balance transfer.

Ciri-ciri Baru

1. Penjejakan Hutang Peribadi

  • Hutang Diterima (Wang yang anda berhutang kepada orang lain)
  • Hutang Diberi (Wang yang orang lain berhutang kepada anda)
  • Rekod pembayaran separa dengan sejarah penuh
  • Notifikasi tarikh akhir (amaran 7 hari sebelum)
  • Pilihan auto-tambah pembayaran ke perbelanjaan

2. Pengurusan Kad Kredit

  • Simpan berbilang kad kredit
  • Jejaki hari penyata dan tarikh akhir pembayaran
  • Tetapkan had kredit

3. Penjejakan Ansuran (EPP & Balance Transfer)

  • Hubungkan ansuran ke kad kredit tertentu
  • Jejaki pembayaran bulanan dan kemajuan
  • Penciptaan perbelanjaan automatik semasa pembayaran

Implementasi Teknikal

Database Schema

Empat jadual baru ditambah ke D1:

-- Kad Kredit
CREATE TABLE credit_cards (
    id INTEGER PRIMARY KEY,
    user_id TEXT NOT NULL,
    name TEXT NOT NULL,
    card_type TEXT DEFAULT 'credit',
    last_four TEXT,
    statement_day INTEGER,
    payment_due_day INTEGER,
    credit_limit REAL
);

-- Hutang Peribadi
CREATE TABLE debts (
    id INTEGER PRIMARY KEY,
    user_id TEXT NOT NULL,
    type TEXT NOT NULL, -- 'receivable' or 'payable'
    person_name TEXT NOT NULL,
    original_amount REAL NOT NULL,
    current_balance REAL NOT NULL,
    interest_rate REAL,
    due_date TEXT,
    status TEXT DEFAULT 'active',
    auto_add_expense INTEGER DEFAULT 0
);

-- Pembayaran Hutang
CREATE TABLE debt_payments (
    id INTEGER PRIMARY KEY,
    debt_id INTEGER REFERENCES debts(id),
    user_id TEXT NOT NULL,
    amount REAL NOT NULL,
    payment_date TEXT NOT NULL,
    notes TEXT,
    expense_id INTEGER REFERENCES expenses(id)
);

-- Ansuran
CREATE TABLE installments (
    id INTEGER PRIMARY KEY,
    user_id TEXT NOT NULL,
    card_id INTEGER REFERENCES credit_cards(id),
    type TEXT NOT NULL, -- 'epp' or 'balance_transfer'
    name TEXT NOT NULL,
    total_amount REAL NOT NULL,
    monthly_payment REAL NOT NULL,
    interest_rate REAL,
    total_months INTEGER NOT NULL,
    months_paid INTEGER DEFAULT 0,
    payment_day INTEGER NOT NULL,
    start_date TEXT NOT NULL,
    status TEXT DEFAULT 'active',
    auto_add_expense INTEGER DEFAULT 0
);

API Endpoints

16 endpoints baru ditambah:

MethodEndpointKeterangan
GET/api/credit-cardsSenarai semua kad kredit
POST/api/credit-cardsCipta kad kredit
PUT/api/credit-cards/:idKemaskini kad kredit
DELETE/api/credit-cards/:idPadam kad kredit
GET/api/debtsSenarai semua hutang
POST/api/debtsCipta hutang
PUT/api/debts/:idKemaskini hutang
DELETE/api/debts/:idPadam hutang
GET/api/debts/:id/paymentsDapatkan sejarah pembayaran
POST/api/debts/:id/paymentsRekod pembayaran
GET/api/installmentsSenarai ansuran
POST/api/installmentsCipta ansuran
PUT/api/installments/:idKemaskini ansuran
DELETE/api/installments/:idPadam ansuran
POST/api/installments/:id/payRekod pembayaran ansuran
GET/api/summary/debtsDapatkan ringkasan hutang

Frontend Components

  • Seksyen navigasi “Hutang” baru
  • Antara muka tiga-tab (Hutang Diterima, Hutang Diberi, Ansuran)
  • Modal pengurusan kad kredit
  • Borang hutang dan ansuran dengan validasi
  • Progress bars untuk penjejakan hutang/ansuran
  • Rakaman pembayaran dengan paparan sejarah

Langkah Deployment

1. Kemaskini Wrangler

cd workers
npm install --save-dev wrangler@4

2. Apply Database Migration

npx wrangler d1 execute expense-tracker-db --file=./src/db/schema.sql --remote

3. Deploy Worker

npx wrangler deploy

Output Deployment

⛅️ wrangler 4.54.0
Total Upload: 175.85 KiB / gzip: 41.37 KiB
Worker Startup Time: 1 ms

Uploaded expense-tracker-api (10.80 sec)
Deployed expense-tracker-api triggers (4.61 sec)
  https://your-worker-name.your-subdomain.workers.dev

Fail yang Diubah

FailPerubahan
workers/src/db/schema.sql+40 baris (4 jadual baru)
workers/src/index.ts+490 baris (16 endpoints)
frontend/js/debts.jsFail baru (~700 baris)
frontend/js/api.js+190 baris (fungsi API)
frontend/js/app.js+20 baris (integrasi)
frontend/index.html+310 baris (komponen UI)
frontend/css/styles.css+660 baris (styling)

Paparan Hutang baru memaparkan:

  • Kad ringkasan menunjukkan jumlah hutang
  • Antara muka bertab untuk jenis hutang berbeza
  • Progress bars untuk penjejakan pembayaran
  • Butang tindakan untuk pembayaran dan suntingan

Demo

Cuba sendiri aplikasi ini:


Kesimpulan

Cloudflare stack adalah pilihan yang sangat baik untuk aplikasi web moden:

  • Zero cold starts berbanding Lambda/Cloud Functions
  • SQLite compatibility dengan D1 memudahkan development
  • Generous free tier sesuai untuk side projects

Source code boleh didapati di GitHub. Sebarang soalan, boleh hubungi saya di X (@xhafism) atau Threads (@haf.ism).


Artikel ini adalah sebahagian daripada siri “Building with Cloudflare” di mana saya berkongsi pengalaman membina aplikasi menggunakan edge computing.