Econary: Penjelasan Tech Stack

Aplikasi web pencatat keuangan pribadi: transaksi, dompet, kategori, anggaran bulanan, target tabungan, laporan, dan simulasi “Alternate Universe”. Penjelasan ini ditelusuri langsung dari isi Econary-main.zip (95 file), bukan dari klaim README saja.

Satu aplikasi full-stack JavaScript · Bukan TypeScript · Deploy asal: Vercel

1. Gambaran singkat

Econary itu monolit full-stack: frontend dan backend hidup dalam satu codebase Next.js yang sama. Tidak ada server backend terpisah (misalnya Express/FastAPI) dan tidak ada frontend yang di-build terpisah lalu dipanggil via REST ke server lain.

Browser→Next.js App Router→API Routes→Prisma ORM→PostgreSQL (Neon)

Autentikasi dijaga di tengah-tengah alur itu oleh NextAuth (sesi JWT), dan halaman /dashboard/* diproteksi oleh middleware.js sebelum halaman sempat dirender.

2. Tech stack lengkap

LapisanTeknologiVersi / keterangan dari package.json
BahasaJavaScriptSeluruh kode app/, components/, dan lib/ ditulis .js. Tidak ada TypeScript di codebase ini.
FrameworkNext.js (App Router)^14.2.0 — routing berbasis folder di app/, Server Component + Client Component.
UIReact^18.3.0 + react-dom ^18.3.0.
StylingTailwind CSS^3.4.3, dengan PostCSS ^8.4.38 dan Autoprefixer ^10.4.19. Konfigurasi di tailwind.config.js: warna primer teal, font Inter, dark mode berbasis class, animasi kustom.
BackendNext.js API RoutesRoute handler di app/api/ (lihat bagian 4). Bukan server terpisah.
DatabasePostgreSQLHost yang disarankan di README: Neon. Koneksi lewat dua variabel: DATABASE_URL dan DIRECT_URL (hanya nama variabelnya, nilainya tidak ada di zip ini).
ORMPrisma@prisma/client dan prisma ^5.14.0. Skema di prisma/schema.prisma, migrasi di prisma/migrations/, seed di prisma/seed.js.
AutentikasiNextAuth.js^4.24.0, provider Credentials (email + password) dan Google OAuth. Sesi JWT, masa berlaku 30 hari.
Passwordbcryptjs^2.4.3, hash dengan 10 salt rounds di lib/auth.js.
GrafikRecharts^2.12.0 — dipakai di dashboard, laporan, dan Alternate Universe.
IkonLucide React^0.378.0 — hampir semua halaman dan komponen memakainya.
Tanggaldate-fns^3.6.0, plus utilitas sendiri lib/dateFormat.js dan lib/currency.js (format IDR).
EksporjsPDF + autotable, html2canvas, xlsxEkspor PDF laporan lewat lib/exportPDF.js (jsPDF ^2.5.2 + jspdf-autotable ^3.8.2). Paket xlsx dan html2canvas terdaftar di dependensi.
State clientZustand (terdaftar)^4.5.0 tercantum di package.json, tapi pada penelusuran file app/, components/, dan lib/ tidak ditemukan pemakaian Zustand yang menonjol — state halaman lebih banyak ditangani React state di komponen *Client.js dan Context provider. Jadi jangan mengklaim Zustand sebagai tulang punggung state-nya.
Deploy asalVercelvercel.json: framework nextjs, region sin1 (Singapura), build prisma generate && next build.

Catatan build: next.config.js mengaktifkan eslint.ignoreDuringBuilds dan typescript.ignoreBuildErrors. Artinya error lint tidak akan menggagalkan build — praktis untuk demo, tapi bukan standar yang bagus untuk produksi.

3. Frontend-nya gimana?

Pola utamanya: Server Component mengambil data, Client Component mengurus interaksi. Contohnya app/dashboard/page.js (async, mengambil data lewat Prisma) merender components/dashboard/DashboardClient.js yang berisi grafik, tombol, dan modal. Pola *Client.js ini dipakai konsisten di semua fitur.

Halaman yang ada

Komponen

19 file di components/, dikelompokkan per fitur: dashboard/, transactions/, wallets/, categories/, budget/, saving-goals/, reports/, settings/, alternate-universe/, plus providers/ (AuthProvider untuk sesi NextAuth dan PreferencesProvider untuk preferensi). Modal-modal form (tambah transaksi, dompet, kategori, anggaran, target tabungan) masing-masing file sendiri, jadi mudah dilacak.

Styling & bahasa

4. Backend-nya gimana?

Backend = 21 file route di app/api/, semuanya route handler Next.js. Tidak ada folder server/ terpisah. Setiap route yang menyentuh data user wajib memeriksa sesi dulu, lalu memfilter berdasarkan userId dari sesi — jadi user A tidak bisa sekadar menebak ID untuk melihat data user B lewat API normalnya.

Endpoint utama (CRUD per resource)

ResourceEndpoint
AuthPOST /api/auth/register, NextAuth di /api/auth/[...nextauth] (signin/signout/session)
TransaksiGET/POST /api/transactions, PUT/DELETE /api/transactions/[id]
KategoriGET/POST /api/categories, PUT/DELETE /api/categories/[id]
DompetGET/POST /api/wallets, PUT/DELETE /api/wallets/[id]
AnggaranGET/POST /api/budgets, PUT/DELETE /api/budgets/[id]
Target tabunganGET/POST /api/saving-goals, PUT/DELETE /api/saving-goals/[id], GET/POST /api/saving-goals/[id]/transactions (setoran/penarikan)
UserGET/PUT /api/user/profile, PUT /api/user/password, DELETE /api/user/delete

Alur satu request (contoh: ambil transaksi)

Browser (sudah login, cookie sesi JWT)
  → GET /api/transactions
  → getServerSession(authOptions) — tanpa sesi → 401 Unauthorized
  → prisma.transaction.findMany({ where: { userId: session.user.id } })
  → amount Decimal diubah ke Number, lalu dikirim sebagai JSON

Autentikasi, detailnya

Database: 7 model Prisma

ModelIsi penting
Username, email (unik), password hash, phone, bio, avatarUrl, currency (default IDR), theme (default light).
Walletname, type (cash/bank/e-wallet), balance Decimal(15,2).
Categoryname, type income/expense, icon, color, isDefault; bisa milik user tertentu atau default global (userId nullable).
Transactiontype, amount Decimal(15,2), note, date; terhubung ke User, Wallet, dan Category.
Budgetamount per kategori per bulan/tahun; unik per (user, kategori, bulan, tahun).
SavingGoaltargetAmount, savedAmount, targetDate, imageUrl, wallet opsional.
SavingTransactionSetoran/penarikan ke target tabungan, terhubung ke SavingGoal dan Wallet.

Relasi memakai onDelete: Cascade di sebagian besar tempat (hapus user → dompet, kategori, transaksi, anggaran, dan target ikut terhapus), kecuali wallet pada SavingGoal yang SetNull. Index sudah dipasang di kolom yang sering difilter: userId, date, type, dan month/year untuk budget.

⚠️ Jangan deploy Econary mentah-mentah ke produksi. Di zip ini masih ada route debug/pengembangan yang tidak boleh ikut ke publik: /api/debug/env (membeberkan ada/tidaknya dan potongan kredensial Google & NextAuth), /api/debug/users (menampilkan semua user), /api/test-db (menampilkan jumlah user dan data demo, plus stack error), dan /api/setup/add-columns. Hapus keempat route itu dulu, ganti secret, dan matikan akun seed demo sebelum dipakai beneran.

Menjalankan secara lokal

npm install
npx prisma generate
npx prisma migrate dev --name init
npx prisma db seed
npm run dev   # http://localhost:3000

Script build produksi: prisma generate && next build, lalu next start.

5. Jadi, halaman penjelasan ini aman di Cloudflare?

Ya, halaman ini aman. Halaman ini 100% statis: satu file HTML, CSS inline, tanpa JavaScript yang memanggil server, tanpa form, tanpa cookie, tanpa database, dan tanpa kredensial apa pun. Yang di-deploy ke Cloudflare Pages hanyalah penjelasan tentang Econary — bukan aplikasi Econary-nya sendiri.

Yang TIDAK aman (dan tidak dilakukan di sini): men-deploy aplikasi Econary-nya sendiri ke Cloudflare Pages sebagai situs statis — itu tidak akan jalan, karena Econary butuh server Node.js untuk API Routes + NextAuth dan koneksi PostgreSQL. Jalur aslinya adalah Vercel (lihat vercel.json), atau platform lain yang mendukung Next.js server-side. Dan kalau Econary di-deploy ke mana pun, hapus dulu route debug di atas.

6. Ringkasan satu paragraf

Econary adalah aplikasi keuangan pribadi full-stack JavaScript berbasis Next.js 14 App Router + React 18, dengan UI Tailwind CSS + Lucide + Recharts, backend berupa Next.js API Routes yang diamankan NextAuth (JWT) dan password bcrypt, serta data yang disimpan di PostgreSQL (Neon) lewat Prisma dengan 7 model utama. Frontend memakai pola Server Component + *Client.js per fitur; backend memakai pola cek sesi lalu filter userId di setiap request. Cocok sebagai proyek pembelajaran/portfolio — dengan catatan route debug harus dihapus sebelum produksi.

Sumber: isi Econary-main.zip — package.json, README.md, prisma/schema.prisma, app/, components/, lib/, middleware.js, vercel.json, dan next.config.js. Versi dependensi dicantumkan sesuai package.json di zip tersebut.