Trasaqu
Retail-first Business Management & Point-of-Sale Platform
An end-to-end retail management and point-of-sale platform where I personally directed product scope and technical delivery: identifying retail operational pain points, defining PRDs, prioritizing functionality, and building across an offline-first Flutter mobile app, a Cloudflare Workers backend with D1 and R2, and a React/TypeScript administrative dashboard. AI-assisted development was utilized as an accelerator with human-owned engineering decisions.
Independent Product Owner & Engineer
Retail & Sembako
React 18 · Vite
Flutter (Dart)
Cloudflare Workers · TypeScript
Cloudflare D1 · R2
Drift (Local SQLite)
Pre-production
Preparing Play Store
Offline-aware · RBAC
FROM IDEA TO PRODUCTION
Setiap tahap dari riset masalah bisnis hingga persiapan rilis produksi dieksekusi secara mandiri.

From Retail Problems to a Production Product
Trasaqu was created around the operational problems of small and medium retail businesses that still rely on fragmented or manual workflows for sales, purchasing, stock management, receivables, and reporting.
Instead of treating the product as an isolated cashier application, the system was designed around the wider retail operational cycle:
Why Retail First?
Instead of trying to support every business type from the beginning, I chose Retail and Sembako as the initial production domain. This provided a concrete business environment for validating transactions, purchasing, inventory, multi-store operations, permissions, reporting, offline behavior, and cloud capabilities before introducing other industries with different operational models.
“Build the concrete domain first. Generalize after recurring patterns become clear.”
Generalize from proven patterns, not assumptions.
Domain rules yang jelas mempercepat validasi ke pengguna nyata.
Menghindari abstraksi generic yang rapuh di fase awal.
Struktur data retail menjadi pondasi kuat untuk shared capabilities.
Feedback langsung dari operasional toko nyata sebelum ekspansi vertikal.
Built Across the Entire Product Lifecycle
Kepemilikan penuh dari perumusan visi bisnis hingga implementasi kode di semua lapisan sistem:
- •Business research & competitor analysis
- •Requirement gathering & PRD
- •MVP definition & feature prioritization
- •Business rules & user journey flows
- •Information architecture & app flows
- •Mobile & Web responsive interfaces
- •Role-specific navigation structures
- •Loading, empty, error, and offline states
- •Administrative browser dashboard
- •Store, product, & inventory management
- •Role & membership management
- •REST API integration & auth state
- •Simplified Clean-inspired Layering
- •Cubit → Repository → Drift & API
- •Drift SQLite pending mutation queues
- •Offline holder & transaction resilience
- •Stateless serverless REST handlers
- •JWT & refresh token authentication
- •Store-scoped RBAC & permission guards
- •Request validation & error handling
- •Relational schema & store isolation
- •Normalized movement ledger tables
- •Constraints, foreign keys, & indices
- •R2 image and file storage
- •Cloudflare routes, secrets & configuration
- •GitHub Actions build & deployment automation
- •Android keystore release signing
- •Google Play Store release preparation
Retail Operations Covered End to End
Fast cashier workflow, barcode scanning, discounts, multiple payment methods, receipt printing, and void handling.
Traceable ledger movements (in, out, adjustment, opname) instead of static overwrite numbers.
SKU management, packaging unit conversion (e.g., box to pcs), base pricing, and store-level configs.
Purchase orders, incoming stock verification, supplier debt tracking, and historical cost recording.
Manage multiple branches with dedicated active store context, isolated data, and role assignments.
Granular permissions for Owner, Cashier, Warehouse, and Finance evaluated at the API layer.
Revenue trends, gross profit margins, inventory valuation, top products, and exportable audit logs.
Customer credit records, repayment history, due date tracking, and balance settlements.
Local persistence via Drift SQLite in Flutter for resilient operation during internet instability.
Multi-Client Product Architecture
Pemisahan tanggung jawab klien web dan mobile yang mengonsumsi backend kontrak REST API yang sama:
Administrative Dashboard, Store Configurations, Master Data, Reporting
BLoC / Cubit · Repository · Dio · Drift Local DB (Offline Cache)
Serverless handlers · Validation · RBAC
Relational SQLite · Store Isolation · D1 Migrations
Images, files, and cloud backup objects
Mobile Relational SQLite Persistence for Offline Resilience
Simplified Layered Clean-Inspired Flutter Architecture
The Flutter application uses a Simplified / Layered Clean-inspired Architecture rather than full Clean Architecture, as there is no explicit domain use-case layer. The architecture is pragmatic rather than dogmatic: Cubit manages presentation state and application workflow orchestration, while repositories coordinate access to remote and local data sources. For the current product complexity, Cubit coordinates feature workflows and state transitions. If domain rules grow significantly, they can be extracted into dedicated domain services or use cases when the complexity justifies the additional abstraction.
Reactive widgets, barcode camera scanners & thermal print dialogs
Presentation state, loading/success/error transitions & workflow orchestration
Coordinates access between remote API and local Drift SQLite data sources
RemoteDataSource & LocalDataSource abstraction boundaries
Dio REST HTTP client & Drift SQLite relational persistence
The current offline-first strategy focuses on preserving local operations and queuing pending mutations for synchronization after connectivity returns. Distributed conflict resolution across multiple offline terminals is outside the current implementation and remains a future design consideration:
Stores products, categories, customers, and active store configurations locally in a type-safe relational SQLite schema.
Captures sales transactions offline into a dedicated pending_sales_transaction table with status flags for automatic sync when connectivity returns.
Preserves in-flight cart operations and temporary cashier hold tickets across network drops and device sleep without state loss.
Automatic JWT token attachment and transparent refresh token rotation on mobile.
ESC/POS byte stream formatting for 58mm & 80mm wireless receipt printers.
Dependency injection decoupling repositories, data sources, and cubit lifecycles.
React 18 Admin Architecture & TanStack Query
The Trasaqu Admin Web platform is engineered with React 18 + TypeScript (Vite) as a dedicated administrative dashboard. Rather than copying Flutter architecture directly into React, I adapted the same engineering principles to the conventions of the web ecosystem(separation of concerns, centralized networking, clear data flow, feature modularity, reusable components, and predictable responsibility boundaries). For the current admin application's complexity, feature API modules combined with TanStack Query already provide clear separation between UI, server-state management, and network access. Adding an additional repository abstraction would currently duplicate responsibilities without providing enough additional value:
Tailwind CSS views, modal forms & responsive tables
Custom TanStack Query hooks managing server state, caching & mutations
Modular endpoint API modules (customers, stores, products)
Centralized Axios client with base URL & active store interceptors
Client-side single-flight refresh mutex with queued request replay
The centralized Axios client uses a single-flight refresh mechanism so concurrent 401 responses do not trigger multiple refresh-token requests. Failed requests are queued and replayed after the access token is successfully rotated:
The first 401 sets an active mutex lock flag, ensuring only one refresh API call is in-flight to the backend at a time.
All subsequent concurrent requests that fail with 401 while refreshing are pushed into an in-memory queue of pending promises.
When token rotation succeeds, processQueue() updates the authorization header and transparently replays all queued requests.
Tiered plans (FREE, PRO_SOLO, PRO_STARTER, PRO_BUSINESS, ENTERPRISE) with store limits and duration validation.
Administrative UI preview initialized in AuditLogsPage.jsx; backend endpoint integration in progress.
Dynamic custom tier and feature flag builder planned for future enterprise partner deployments.
Cloudflare Workers Backend
The current TypeScript backend runs on Cloudflare Workers as a stateless, request-driven API, with Cloudflare D1 for relational data and Cloudflare R2 for images and files. I migrated the original NestJS service from a self-managed Cloud VPS, adapting routing, authentication, store-scoped authorization, validation, business logic, data access, and error handling to the Workers runtime. Cloudflare now manages runtime configuration, routes, secrets, and deployment settings.
NestJS → Cloudflare Workers: routes, authentication, validation, business services, and store-scoped access control.
Self-managed Cloud VPS → Cloudflare-managed serverless runtime, routes, secrets, and deployment configuration.
GitHub Actions runs Flutter dependencies, code generation, tests, environment builds, Android signing, and Firebase App Distribution for development and staging. Google Play release is in preparation.
Store-Scoped Authorization Architecture
Permission Resolution Chain
Izin pengguna tidak statis pada user, melainkan ditentukan berdasarkan membership pada toko yang sedang aktif:
Why Store Membership Model?
Model sederhana seperti user.store_id menjadi pembatas ketika satu pemilik mengelola multi-cabang atau karyawan memiliki peran berbeda di cabang berbeda:
Arsitektur data ini memungkinkan isolasi multi-tenant yang aman dan skalabilitas multi-cabang sejak awal.
Stock Is a History of Movements, Not Just a Number
Menyimpan stok hanya sebagai angka tunggal yang di-overwrite rawan kehilangan jejak audit. Trasaqu mencatat stok sebagai buku besar mutasi (stock movements) yang dapat direkonstruksi secara historis.
A Sale Touches Multiple Domains
Satu transaksi kasir melibatkan rangkaian orkestrasi lintas domain bisnis, bukan sekadar perintah tunggal INSERT INTO sales:
Problems Beyond Basic CRUD
Multiple transactions affecting the same stock concurrently.
Transactional database operations and atomic deductions.
Stock state must remain reliable without race conditions.
Access tokens expiring during active cashier workflows.
Centralized Dio refresh token interceptor with request queueing.
Auth handling shouldn't be duplicated across individual screens.
Retail shops often experience erratic internet connectivity.
Persist product catalog in Drift SQLite local database.
Temporary network loss shouldn't paralyze cashier operations.
User having different roles across different store locations.
Membership-based role and permission hierarchy.
Authorization must be strictly contextual to active store.
Subscription expiration shouldn't destroy store historical data.
Separate cloud entitlement from ownership of local business records.
Data ownership and service access are different concerns.
App state surviving navigation, restart, and device sleep.
Explicit separation between memory state, cache, and relational DB.
Predictable lifecycle across complex multi-step workflows.
Technology Choices With Product Context
Mobile-first operational UI, reactive state, strong local persistence ecosystem.
Platform-specific channels required for hardware integration.
Desktop-oriented admin frontend evolving independently from mobile flows.
Dual-client codebase to maintain across shared API contracts.
Stateless TypeScript API execution with Cloudflare-managed deployment and configuration.
The former NestJS modules required adaptation to a request-driven runtime.
D1 stores relational retail data; R2 stores images and files within the Cloudflare ecosystem.
Database migrations and object lifecycle require careful coordination.
Designed Beyond the Happy Path
Dio interceptor triggers refresh token queueing automatically.
Drift local database maintains cached product catalog.
State reset and store context header propagated across requests.
Transactional database verification before sale commit.
Local business data preserved with graceful cloud feature limits.
Distributed conflict resolution across multiple offline terminals is outside the current implementation and remains a future design consideration.
Production Was Part of the Engineering Scope
Tanggung jawab rekayasa tidak berhenti di localhost. Pengelolaan rahasia lingkungan, deployment backend, migrasi database, signing kunci rilis Android, hingga persiapan rilis Google Play Store dieksekusi secara terstruktur.
Keystore signing & AAB build
Store listing & release preparation
Cloudflare D1 schema migrations
Workers, D1, R2 & configuration
Retail First. Platform Next.
Trasaqu intentionally starts with a concrete retail domain rather than attempting to model every business category from day one. Once recurring platform concerns are validated through the Retail and Sembako product, shared capabilities can gradually be extracted while new business verticals retain their own domain-specific workflows.
- • Products & SKU
- • Packaging Units
- • Barcode Scan
- • Stock Movements
- • Raw Ingredients
- • Recipe / HPP
- • Menu Engineering
- • Table / Kitchen
- • Weight / Kiloan
- • Service Stages
- • Ready & Pickup
- • Order Tracking
- • Vehicle Records
- • Service Jobs
- • Mechanic Assign
- • Spare Parts
Different Businesses Share Transactions — Not Workflows
Forcing all verticals into a single generic POS introduces conditional spaghetti code and weak domain abstractions. Trasaqu aims to reuse shared platform infrastructure while allowing each business vertical to maintain its native operational workflow.
From Solo Product Engineering to Collaborative Development
The initial Trasaqu Retail platform was independently designed and engineered by me from product definition through pre-production release preparation. As Trasaqu moves beyond its initial Retail and Sembako scope, future development is planned together with Kōhī Labs as a technology partner.
- • Research, PRD, UX/UI
- • React.js Web + Flutter Mobile
- • Cloudflare Workers + D1 + R2
- • Retail & Sembako Pre-production
- • Technology & IT Partner
- • Shared Platform Scaling
- • Deeper Domain Research
- • Vertical Expansion (F&B, Laundry, Bengkel)
Expand by Domain, Not by Feature Accumulation
Technology Stack
What Building the Entire Product Changed
Kebutuhan bisnis multi-cabang langsung membentuk relasi StoreMember di database.
UI checks hanya untuk visual affordance; API guards yang menjamin keamanan data.
Buku besar pergerakan stok mutlak diperlukan untuk audit dan mencegah selisih misterius.
Kebutuhan offline menuntut pemisahan tegas antara remote persistence dan local cache.
End-to-End Product Engineering Summary
Trasaqu represents my end-to-end product engineering work: taking a retail business problem from research and PRD through UX, React.js web development, Flutter mobile engineering, Cloudflare Workers backend migration, D1 relational data, R2 object storage, Cloudflare infrastructure, GitHub Actions automation, and Google Play release preparation. The initial pre-production version focuses on Retail and Sembako. Future development is planned to expand the platform into additional business verticals together with Kōhī Labs as a technology partner.