X-POSCross-Platform Point-of-Sale App
- Period
- Feb 2026 - Feb 2026
- Project type
- Team Project
- Role
- Client Lead & Backend Contributor (Small Team)
- Team
- Client led solo; backend team
A cross-platform (iOS / Android / web) point-of-sale app for electronics-retail staff to ring up sales, manage stock, and process returns, with role-based access spanning cashier through super-admin.
- Redux slices
- 8Redux slices
- Cashier through super-admin
- 5RBAC rolesCashier through super-admin
Overview
X-POS combines one Expo and React Native codebase with a Laravel and Sanctum API. The client organizes authentication, products, inventory, customers, sales, payments, returns, and UI state through Redux and domain services. Those services can target either the API or an in-process mock adapter without changing screen logic.
Role & context
- Role
- Client Lead & Backend Contributor
- Team
- Client led solo; backend team
- Type
- Team Project
- Period
- Feb 2026 - Feb 2026
I authored the Expo client and contributed a smaller portion to a teammate-led Laravel backend. The combined system covers the mobile and web interaction layer plus an authenticated REST API, while a switchable mock adapter remains available for parallel frontend development.
Problem
Electronics-retail checkout needs cashiers to ring up multi-item sales with line-level discounts, deduct stock atomically, and handle returns, while owners restrict who can discount, refund, or manage staff. The team also needed to build and demo the full app before the backend existed.
Approach & architecture
Screens gate on RBAC and dispatch thunks through a typed service layer; one axios instance attaches the JWT and runs single-flight refresh; a mock adapter stands in for the pending backend.
Practices followed
Layered separation of concerns
atomic-design components, per-domain service modules, and Redux slices — screens never call axios directly
RBAC from a single source of truth
a 5-role × 14-permission matrix with role normalization, reused by a
can()gate across UI and route guardsResilient auth
a response interceptor refreshes the JWT with a single-flight flag and a failed-request queue, replaying parked 401s after one refresh
Circular-dependency-safe wiring
injectStore()plus runtime dynamicimport()of thunks inside the interceptor to break the api → store → slices → services → api cycleDisciplined persistence
redux-persist whitelist limited to auth tokens + theme, so stale server data and PII are not persisted
API/domain decoupling with strict TypeScript and explicit DTO → domain mappers with defensive type coercion
Challenges & resolutions
Circular import deadlock — the axios layer needs the store for the token, but the store imports slices that import the services that import axios.
FixLazy injectStore(store) called once at bootstrap, plus runtime dynamic imports of the refreshToken/logoutUser thunks inside the interceptor instead of at module load.
Parallel requests all 401-ing at once would each trigger a separate token refresh (a refresh stampede).
FixA single-flight refresh guarded by an isRefreshing flag; other failed requests park in a queue, resolve with the new token, and retry automatically.
Outcomes
Cross-platform front-end covering Dashboard, Sales/Checkout, Inventory, Returns, Profile, and Users Management
- 8
Redux slices; full auth flows (login, signup, forgot/reset via deep link, refresh, logout); RBAC for 5 roles
Line-level discounts with savings/change calculation; graceful stock-sync failure handling
Complete mock backend enabling backend-independent development
A real Laravel API with authenticated operations and a migration-backed domain model
Tech stack
Concepts & skills12
- JWT authentication with refresh-token rotation
- Axios request/response interceptors
- Single-flight / request-queue (refresh-stampede prevention)
- Role-Based Access Control (RBAC) & permission matrices
- Redux Toolkit (createSlice / createAsyncThunk)
- State persistence & rehydration (redux-persist)
- File-based routing (expo-router) & route guards
- Atomic design component architecture
- Cross-platform React Native / Expo (New Architecture)
- Material Design 3 theming
- Dependency injection to break circular imports
- DTO-to-domain mapping & defensive type coercion