← Back

Web & Mobile Development

A collection of real-world Web & Mobile Development experience — from eTax web apps and World Bank projects, to internal platforms, FMCG route optimization, and Flutter mobile apps released to the Play Store.

📌 Note: All images on this page are illustrations only — not screenshots of real dashboards or actual architecture. Hopefully they still represent what I've built.

Use Cases

Web eTax, World Bank & Internal Apps

Multi-Industry

Built multiple web applications across different contexts: an eTax system for private company tax reporting, web-based reporting modules for World Bank projects, and several internal apps using CodeIgniter 4 and React for company operational needs.

Modern Full-Stack Portfolio Platform

Personal Project

Built this digital portfolio platform from scratch using Next.js 16, TypeScript, and Tailwind CSS — with multi-language support (ID/EN), motion-based animations, dynamic content from JSON, and production-grade Vercel deployment.

Sales Route Optimization System

FMCG

Built a web-based sales visit route optimization system for the FMCG industry — integrating clustering & routing algorithms with Google Maps API to produce realistic routes within an 8-hour working day constraint.

BabyTrack – Full-Stack Child Health Platform

Healthcare

Built a full-stack child health tracking platform using Next.js App Router, TypeScript, and Supabase — from database schema design with Row-Level Security to 10+ integrated frontend modules, role-based admin system, and production deployment on Vercel.

Ledgerin – Personal Finance Mobile App (Flutter + Firebase)

Personal Project

End-to-end personal finance mobile app — built with Flutter & Firebase, Go backend with Swagger contracts, and Google Drive integration for backup. Released to Play Store & Firebase App Distribution.

Home Tracker – Digital Household Management App

Personal Project

Mobile app for tracking household needs and tasks — built with Flutter & Firebase with a Go backend documented via Swagger. Released to Play Store.

Web eTax, World Bank & Internal Apps

Experienced in building web applications across diverse real-world project contexts: a web-based eTax system for private company tax reporting, web module implementation in a World Bank-funded project, and several internal applications using CodeIgniter 4 and React used for daily company operations.

📊 Impact

  • eTax system enabled private companies to independently and systematically file tax reports via web
  • World Bank module delivered on time with all project milestones and international documentation standards
  • CI4-based internal apps replaced error-prone manual workflows and spreadsheets
  • React components built for reuse across multiple modules, accelerating development cycles
  • Code quality maintained through code reviews, PSR standards, and manual test coverage

🧩 Tech Stack

CodeIgniter 4, React, PHP, MySQL, REST API, HTML/CSS/JavaScript, Bootstrap, jQuery, MVC Architecture

⚡ Problem Statement

  • Private companies needed a web system to record and report tax obligations in a structured way
  • World Bank project required web modules integrated into an existing running system ecosystem
  • Operations team still using spreadsheets for processes that could be automated via web apps
  • Several internal tools built with different technologies, making maintenance difficult
  • Complex multi-level form validation and cross-department approval workflow requirements

🧠 Solution Overview

  • Built eTax application with multi-step form wizard, automated tax validation, and periodic reports
  • Integrated new web modules into existing World Bank system with agreed API contracts
  • Migrated operational workflows to CodeIgniter 4: CRUD modules, approval workflows, email notifications
  • Standardized frontend components with React: reusable form components, dynamic tables, and modals
  • Implemented role-based access: admin, approver, input user with secure session management

🏗️ Architecture

  1. Backend: CodeIgniter 4 with MVC architecture, RESTful API layer, and authentication middleware
  2. Frontend: Hybrid approach — server-rendered PHP/CI4 views with React components for interactive parts
  3. Database: MySQL with relational schema for tax records, approval workflow, and audit trail
  4. Auth & RBAC: session-based authentication with CI4 Shield library + custom role permission layer
  5. Deployment: shared hosting / VPS with Nginx + PHP-FPM, .env configuration per environment

🔥 Challenges & Solutions

  • Integrating new modules into the legacy World Bank system — required deep understanding of the existing architecture
  • Multi-level tax validation (PKWTT, PKWT, PPh 21) with complex logic that changes per regulation updates
  • Ensuring UI consistency between React components and CI4 templates in a single hybrid application

Modern Full-Stack Portfolio Platform

This digital portfolio platform was built from scratch using a modern stack: Next.js 16, TypeScript, and Tailwind CSS. Designed as a fully data-driven full-stack application, supporting multi-language (ID/EN), and ready for production deployment on Vercel with high performance.

📊 Impact

  • Low time-to-first-byte (TTFB) thanks to Next.js server-side rendering and static generation
  • Fully data-driven content from JSON — easy to update without touching component code
  • Multi-language (ID/EN) natively integrated with URL param sync and no external i18n library
  • Mobile-first, fully responsive across all screen sizes from mobile to widescreen desktop
  • Auto-deploy to Vercel: zero-downtime, preview URL per branch, instant rollback

🧩 Tech Stack

Next.js 16, TypeScript, Tailwind CSS, Framer Motion, React Icons, Vercel, JSON-based content architecture

⚡ Problem Statement

  • Needed a portfolio platform that can update content quickly without rebuilding the entire app
  • Multi-language must work without heavy i18n libraries and still be indexed by search engines
  • Loading performance must be high on mobile devices with slow connections
  • Deployment must be zero-friction — code updates go live without complex CI/CD setup
  • Architecture must scale as new use cases are added across domains

🧠 Solution Overview

  • JSON-based content architecture: each domain (data engineering, analytics, etc.) has its own use-cases.json
  • Multi-language via URL query param (?lang=id/en) with state sync and server-side rendering
  • Animations with Framer Motion for smooth UI experience without sacrificing performance
  • Next.js server components for fast server-side rendering and SEO-friendly output
  • Deployed to Vercel: auto-deploy from GitHub, preview deployments, built-in analytics

🏗️ Architecture

  1. App Router: Next.js 16 App Router with server components for layout and page rendering
  2. Content Layer: per-domain JSON files imported directly into page components (zero API calls)
  3. Styling: Tailwind CSS utility-first with custom config for consistent design system
  4. Animation: Framer Motion for page transitions, hover effects, and scroll-triggered animations
  5. Deployment: Vercel with Git integration — push to main = automatic production deploy

🔥 Challenges & Solutions

  • Multi-language without i18n library: solved with URL param + useSearchParams + server-side lang detection
  • Scalable content without CMS: solved with modular per-domain JSON architecture that's easy to extend
  • SVG architecture diagrams in Next.js Image: solved with dangerouslyAllowSVG config in next.config

Sales Route Optimization System

I built a web-based sales visit route optimization system for the FMCG and agritech distribution industry. The system helps sales teams meet a target of ±20 store visits per day within an 8-hour working day constraint, through a combination of geographic clustering algorithms and Google Maps API-based routing. Output is delivered as per-salesman map visualization and Excel export for field operations.

📊 Impact

  • Sales teams can meet the ±20 store visit target within an 8-hour workday using optimized routes
  • Routes are more realistic than naive approaches — accounting for actual road conditions via Google Maps API
  • Significantly improved field visit efficiency compared to manual route planning
  • Bridged the gap between data (store lat/long) and field operations through easy-to-use output
  • Excel output allowed non-technical field teams to use optimization results directly without special training

🧩 Tech Stack

Web Application (Custom), Backend Algorithm (Clustering + Routing), Google Maps API (Directions + Polyline), Excel Export, GIS Collaboration

⚡ Problem Statement

  • Optimize sales visit routes within an 8-hour daily working time constraint
  • Determine efficient store groupings based on geographic proximity
  • Generate realistic routes (not straight-line distances) aligned with actual road conditions
  • Provide tools that can be used operationally by field teams
  • Generate output that can be validated and understood by non-technical teams

🧠 Solution Overview

  • Web interface with configurable parameters: store list (lat/long), number of sales reps, working hours, visit target
  • Clustering first: stores grouped by geographic proximity to form working areas per salesman
  • Per-cluster routing: each cluster's route optimized using Google Maps API (polyline actual route)
  • Dynamic starting point: flexible visit starting point, can start from nearest store, not always from a fixed depot
  • Time-based constraint: focus on fitting within 8-hour workday, not just count of visit points
  • Dual-format output: per-salesman map visualization on web + Excel export with visit order & time estimates

🏗️ Architecture

  1. Input Layer: Web interface — user configures parameters (store list, number of sales reps, working hours, visit target)
  2. Clustering Engine: geographic proximity-based algorithm to form working areas per salesman
  3. Routing Engine: Google Maps API (Directions + Polyline) — generates realistic routes per cluster
  4. Optimization Logic: time-based constraint with dynamic starting point and iterative algorithm tuning
  5. Output Layer: interactive per-salesman map visualization on the web
  6. Export Layer: Excel export — visit order, time estimates, store names per salesman

🔥 Challenges & Solutions

  • Uneven data distribution: solution — geographic clustering before routing, not direct routing to all points
  • Route accuracy (map distance ≠ real distance): solution — Google Maps API polyline integration for actual road routes
  • Real-world constraints (road conditions, access): solution — time-based optimization replacing point-count approach
  • Iterative algorithm tuning: solution — intensive trial & error combined with GIS expert collaboration

BabyTrack – Full-Stack Child Health Platform

As Full-Stack Developer for BabyTrack, I built the entire technical stack from scratch: SQL schema design and migrations in Supabase Postgres, Row-Level Security implementation for sensitive child health data, Supabase Auth-based authentication, and a complete frontend using Next.js App Router with TypeScript and Tailwind CSS. The platform includes 10+ integrated tracking modules, a role-based admin system, and a traction dashboard for business reporting — all deployed to Vercel.

📊 Impact

  • Built 10+ fully integrated child tracking modules in a single production-ready platform
  • Implemented Supabase Row-Level Security (RLS) ensuring per-user data isolation for sensitive health data
  • Designed and maintained SQL migrations for database schema evolution as new modules were added
  • Built trigger-based audit logging system for admin actions and governance controls
  • Deployed to Vercel with zero-downtime, complete SEO metadata (Open Graph, Twitter Card), and domain-ready branding

🧩 Tech Stack

Next.js (App Router), TypeScript, React, Supabase (Auth, Postgres, RLS), Tailwind CSS, Vercel, SQL Migrations, Trigger-based Audit Logging

⚡ Problem Statement

  • Child health data needs per-user isolation with strong security — cross-user data leaks must be prevented
  • Database schema must evolve as new modules are added without breaking changes
  • Admin needs structured role-based access without exposing sensitive data to the wrong permission level
  • Frontend must be responsive, fast, and support multiple modules without fragmented architecture
  • Audit logs for admin actions are required for compliance and governance

🧠 Solution Overview

  • Implemented Supabase RLS policies across all sensitive tables for per-user data isolation
  • Designed structured SQL migrations for database schema evolution — each new module has its own migration file
  • Built trigger-based updated_at consistency and admin audit logging at the database level
  • Used Next.js App Router with server components for optimal rendering performance and SEO-friendly output
  • Built admin panel with role separation (operational admin vs. super admin) based on Supabase Auth claims

🏗️ Architecture

  1. Auth Layer: Supabase Auth with role-based claims (admin, super_admin, user) + secure session management
  2. Database Layer: Supabase Postgres with structured SQL migrations, per-table RLS policies, trigger-based audit logs
  3. API Layer: Server Actions and API routes via Next.js App Router — zero custom backend server
  4. Frontend Layer: Next.js App Router, TypeScript, Tailwind CSS — server components for data-heavy pages
  5. Admin Layer: Separate Operational Dashboard + Traction Dashboard with role-gated access
  6. Deployment: Vercel — auto-deploy from Git, per-stage environment variables, domain-ready with favicon & app icon

🔥 Challenges & Solutions

  • Complex RLS policy design for shared child profiles between parents — solved with ownership join table and granular policies
  • updated_at consistency across many tables — solved with reusable trigger function applied to all relevant tables
  • Admin audit logging without slowing main operations — solved with async triggers at the database level

Ledgerin – Personal Finance App (Offline-First)

Personal Project

Ledgerin is a personal finance mobile app built with an offline-first approach using SQLite via Drift as the primary local database. All transactions are stored locally — the app runs fully without internet. A Go + Swagger backend handles server synchronization, and Google Drive API is used for independent data backup. Released to Google Play Store and Firebase App Distribution.

📊 Impact

  • Offline-first: app runs fully without internet — data always available
  • SQLite via Drift as local single source of truth — high performance with no network latency
  • Google Drive API for independent financial data backup & restore
  • Go + Swagger backend for server sync with contract-first API design
  • Built using vibe coding approach — from idea to Play Store in a short timeframe

🧩 Tech Stack

Flutter, Dart, Drift (SQLite), Go (Golang), Swagger / OpenAPI, Google Drive API, Firebase Auth, REST API, Google Play Store

⚡ Problem Statement

  • Finance apps dependent on internet cannot be used with poor or no connection
  • Financial data must always be instantly available without waiting for server responses
  • Independent backup needed — users don't want to fully depend on a single cloud vendor
  • Backend API must be documented for long-term maintainability
  • Fast development needed since this is a personal project outside work hours

🧠 Solution Overview

  • Drift (SQLite) as primary local database — all CRUD operations run locally without network calls
  • Offline-first architecture: UI always reads from local DB, server sync happens in background when online
  • Firebase Auth for authentication — only the auth layer requires connection on first login
  • Google Drive API for backup & restore: users can export/import data to their own Google Drive
  • Go REST API for data sync — Swagger spec defined before implementation (contract-first)
  • Vibe coding: AI-assisted scaffolding and UI iteration for faster delivery

🏗️ Architecture

  1. Local DB Layer: Drift (SQLite) — type-safe ORM for Flutter, single source of truth, zero network dependency
  2. Auth Layer: Firebase Authentication — Google Sign-In, only required on first login
  3. Sync Layer: Go REST API — syncs local data to server when connection is available
  4. Backup Layer: Google Drive API — export/import SQLite data dump to user's Google Drive
  5. API Contract: Swagger/OpenAPI — contract-first, spec written before Go implementation
  6. Deployment: Google Play Store (production) + Firebase App Distribution (beta)

🔥 Challenges & Solutions

  • Conflict resolution during sync — local data can change while offline, requiring a merge strategy when back online
  • Drift schema migration — SQLite schema changes require careful migrations to avoid losing existing data
  • Google Drive OAuth flow in Flutter — token handling across sessions requires careful management

Home Tracker – Digital Household Management (Offline-First + Firestore Sync)

Personal Project

Home Tracker is a household management mobile app with an offline-first architecture using SQLite via Drift as the primary local database. Data is stored locally so the app runs without internet. Firestore is used as a pull & sync layer to synchronize data across devices within a household — not as the primary database. A Go + Swagger backend handles server-side logic. Released to the Google Play Store.

📊 Impact

  • Offline-first: app runs fully without internet — household data always available
  • Drift (SQLite) as local source of truth — instant performance with no network latency
  • Firestore as sync layer: pull & sync across devices within one household when online
  • Shared household data — household members see the same updates after sync
  • Built using vibe coding approach — fast delivery as a personal project

🧩 Tech Stack

Flutter, Dart, Drift (SQLite), Firebase (Auth, Firestore), Go (Golang), Swagger / OpenAPI, REST API, Google Play Store

⚡ Problem Statement

  • Household management was manual — shopping lists and tasks scattered across chats and paper
  • Household members need the same data but are not always connected to internet simultaneously
  • App must work offline — core functions must not depend on connection
  • Cross-device sync must be smooth without confusing conflicts for users

🧠 Solution Overview

  • Drift (SQLite) as primary local database — all operations run locally, offline by default
  • Firestore as pull & sync layer — not a real-time listener, but periodic pull when connection available
  • Sync strategy: local changes are queued, pushed to Firestore when online, other devices pull on app open
  • Firebase Auth for user identity — ensures data syncs to the correct household
  • Go REST API for server-side business logic with Swagger documentation
  • Vibe coding: AI-assisted development for rapid iteration from concept to product

🏗️ Architecture

  1. Local DB Layer: Drift (SQLite) — type-safe ORM, primary data store, zero network dependency for daily operations
  2. Auth Layer: Firebase Authentication — user identity for routing sync to the correct household
  3. Sync Layer: Firestore (pull & sync) — not a real-time listener; data pulled on app open or manual refresh
  4. Conflict Strategy: last-write-wins with timestamp — simple and effective for household use case
  5. Backend Layer: Go REST API — server-side logic and orchestration with Swagger-documented endpoints
  6. Deployment: Google Play Store

🔥 Challenges & Solutions

  • Designing a sync strategy that isn't confusing — last-write-wins chosen for its simplicity and sufficiency for household use
  • Drift schema migration — local schema updates require safe migrations to avoid corrupting existing data
  • Separating concerns between local DB and Firestore sync layer — both must be loosely coupled for flexibility
To go back to profile, click here.