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.
Use Cases
Web eTax, World Bank & Internal Apps
Multi-IndustryBuilt 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 ProjectBuilt 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
FMCGBuilt 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
HealthcareBuilt 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 ProjectEnd-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 ProjectMobile 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
- Backend: CodeIgniter 4 with MVC architecture, RESTful API layer, and authentication middleware
- Frontend: Hybrid approach — server-rendered PHP/CI4 views with React components for interactive parts
- Database: MySQL with relational schema for tax records, approval workflow, and audit trail
- Auth & RBAC: session-based authentication with CI4 Shield library + custom role permission layer
- 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
- App Router: Next.js 16 App Router with server components for layout and page rendering
- Content Layer: per-domain JSON files imported directly into page components (zero API calls)
- Styling: Tailwind CSS utility-first with custom config for consistent design system
- Animation: Framer Motion for page transitions, hover effects, and scroll-triggered animations
- 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
- Input Layer: Web interface — user configures parameters (store list, number of sales reps, working hours, visit target)
- Clustering Engine: geographic proximity-based algorithm to form working areas per salesman
- Routing Engine: Google Maps API (Directions + Polyline) — generates realistic routes per cluster
- Optimization Logic: time-based constraint with dynamic starting point and iterative algorithm tuning
- Output Layer: interactive per-salesman map visualization on the web
- 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
- Auth Layer: Supabase Auth with role-based claims (admin, super_admin, user) + secure session management
- Database Layer: Supabase Postgres with structured SQL migrations, per-table RLS policies, trigger-based audit logs
- API Layer: Server Actions and API routes via Next.js App Router — zero custom backend server
- Frontend Layer: Next.js App Router, TypeScript, Tailwind CSS — server components for data-heavy pages
- Admin Layer: Separate Operational Dashboard + Traction Dashboard with role-gated access
- 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 ProjectLedgerin 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
- Local DB Layer: Drift (SQLite) — type-safe ORM for Flutter, single source of truth, zero network dependency
- Auth Layer: Firebase Authentication — Google Sign-In, only required on first login
- Sync Layer: Go REST API — syncs local data to server when connection is available
- Backup Layer: Google Drive API — export/import SQLite data dump to user's Google Drive
- API Contract: Swagger/OpenAPI — contract-first, spec written before Go implementation
- 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 ProjectHome 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
- Local DB Layer: Drift (SQLite) — type-safe ORM, primary data store, zero network dependency for daily operations
- Auth Layer: Firebase Authentication — user identity for routing sync to the correct household
- Sync Layer: Firestore (pull & sync) — not a real-time listener; data pulled on app open or manual refresh
- Conflict Strategy: last-write-wins with timestamp — simple and effective for household use case
- Backend Layer: Go REST API — server-side logic and orchestration with Swagger-documented endpoints
- 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
Explore other domains