Overview
A complete operating system for a veterinary pharmacy in the UAE. The touch- and keyboard-friendly POS handles barcode scanning, split payments, held carts and discount approvals, while the back office covers batch and expiry tracking, prescriptions, suppliers and purchasing, cash and VAT accounting, reporting, HR and administration. The system is fully bilingual, with Arabic as the default and a complete right-to-left layout.
The problem
The pharmacy needed to sell quickly at the counter while staying compliant: medicines tracked by batch and expiry, prescription-only and controlled products enforced, UAE VAT invoices issued correctly, and every cashier working within clear limits.
What I built
- A React single-page app on a Laravel REST API, with cookie-based authentication
- A service layer where every sale runs in one database transaction with row locks
- Role-based access with 85+ permissions, six roles and per-user overrides
- Bilingual PDF documents with a custom Arabic text shaper
Key features
- 01POS with hardware barcode scanning, keyboard shortcuts, split payments across six methods, held and recalled carts, and a per-user draft that survives a refresh
- 02Shift management per terminal, with opening balance, cash count and expected-versus-counted reconciliation
- 03FIFO stock deduction by earliest expiry, with batch tracking, low-stock and expiry alerts, and barcode label printing
- 04Prescription enforcement for prescription-only products and an audit trail for controlled substances
- 05Discount escalation: cashiers request a discount and approvers accept or reject it while the sale is open
- 06Purchasing workflow from purchase order to supplier invoice, return and payment
- 07Finance: safes, expenses, customer and supplier balances with ageing, profit and loss, cash flow and VAT reports
- 08UAE tax invoices, tax credit notes and daily sales reports as bilingual PDFs
- 09Role-aware dashboard, notification centre, HR attendance and an audit log
- 10Sign-in by email and password or a 4-digit POS PIN, with optional two-factor authentication
Architecture
- React SPA
- Laravel REST API
- Service layer
- MySQL
Screens
Decisions & challenges
Every sale is one transaction
Checkout locks the shift and the stock batches, deducts stock FIFO, records tax at the rate charged and updates balances in a single transaction, so stock cannot be oversold.
Permissions enforced twice
The interface hides what a user cannot do, and every permission is checked again on the server for each API route.
Arabic on printed documents
The PDF engine cannot join Arabic letters, so a custom shaper processes every document, including Arabic-Indic digits and line wrapping.
Performance & security
Security
- TOTP two-factor authentication with single-use recovery codes, and management of active sessions
- Tax exemptions restricted to the owner and unlocked only by re-entering a PIN, with every change audit-logged
- Prescription files stored privately and served only through permission-checked endpoints
- Rate-limited sign-in and hardened security headers