Altahdi System
An Arabic-first ERP on a Laravel + MySQL backend that replaced paper and spreadsheets with one system for POS invoicing, daily journals, payroll, permissions, and live financial reporting.

- Role
- Technical lead · System architecture · DevSparks team delivery
- Services
- ERP/POS system architecture · Arabic-first RTL UI/UX · Laravel + MySQL API · React 19 + Redux development · Financial reports, charts & Excel/CSV export · Payroll & attendance module · Roles, auth & FCM notifications
- Stack
- React 19 · Laravel · MySQL · TypeScript · Redux Toolkit · MUI · Recharts · Firebase FCM
- Client
- Altahdi Co.
- Industry
- Business Services
- Timeline
- 20 weeks · 2025
01 / Business context
The Problem to Solve
Altahdi was managing core business workflows across paper and spreadsheets: handwritten invoices, expenses in notebooks, manual payroll, and delayed financial visibility. The team needed one Arabic-first system connecting those workflows with separate access levels for admin, reception, and staff.
Altahdi System is an ERP built for Altahdi Co., a businessmen-services company that previously managed important operational and financial work across paper and spreadsheets. It connects front-desk invoicing, daily journals, payroll, and reporting in an Arabic-first interface with separate permissions for admin, reception, and staff, over a Laravel API and a MySQL database that hold the company's financial record.
02 / From Scope to Launch
How the Work Moved
The work became clearer through decisions, working increments, and feedback—not a long wait for a final reveal.
05 Steps
Step 01
We started by sitting with Altahdi's operations and accounting teams to map the real money flow, from invoice to collection to daily journal to report, and turned that into modules, data models and three permission roles.
Step 02
We modelled clients, the service catalog, invoices, journal entries, attendance, and payroll as a relational schema in MySQL, and exposed it through a Laravel API that owns the financial rules: totals, government fees, discounts, tax, and salary calculation.
Step 03
We designed the financial UI RTL from the first screen, with Arabic accounting terminology, mirrored data tables, and an MUI-based design system reused across the operational modules.
Step 04
We built module by module, shipping incrementally: billing and the service catalog first, then journals, payroll, reports, and the analysis room, with reusable data tables and PDF generation.
Step 05
We handled rollout and training ourselves: role accounts, password flows and FCM alerts configured, the team onboarded screen by screen, and workflows tuned from real daily usage.
03 / Decisions that shaped the product
Key Product Decisions
Arabic-first RTL, not a translation pass
- Business context
- A financial UI can be built LTR and later mirrored and translated, or designed right-to-left from the start. For a team moving off paper day-books, the accounting language on screen had to match how they already worked.
- Decision
- We designed RTL from the first screen, with Arabic accounting terminology and mirrored data tables, then reused that MUI-based design system across the platform.
- Why
- The staff issuing invoices and keeping journals work in Arabic; an interface that reads like their existing paper workflow made adoption and training far smoother than a retrofitted translation would.
One ERP instead of separate point tools
- Business context
- Invoicing, accounting journals, payroll and reporting could each have been a separate tool, but Altahdi's core problem was fragmentation: money data scattered across handwritten invoices, notebooks and spreadsheets.
- Decision
- We built a single platform where POS invoicing, daily journals, payroll, and financial reports share one MySQL schema and one Laravel API behind one set of roles.
- Why
- Management was flying blind on cash precisely because the pieces did not connect; one relational model means the invoice at the front desk feeds the journals, reports and live charts without re-entry.
Financial rules on the server, not in the client
- Business context
- Totals, per-item government fees, discounts, tax, and salary calculation could have been computed in the React client, which is faster to build but puts the company's accounting logic in the browser.
- Decision
- We kept every financial calculation and state transition inside the Laravel API, with invoices and their journal entries written in database transactions, and let the client render results rather than derive them.
- Why
- Accounting has to be reproducible and consistent: one authoritative implementation means a report, a PDF invoice, and an on-screen figure cannot disagree, and a half-written invoice cannot leave the books unbalanced.
Three permission roles with protected routes
- Business context
- Admin, reception and staff all touch the same financial data but must not see or do the same things; a single shared login would expose payroll and financials to everyone.
- Decision
- We implemented three permission levels, admin, receptionist and employee, enforced in the Laravel API and mirrored as protected routes in the client, with real-time Firebase Cloud Messaging notifications.
- Why
- It lets reception issue invoices quickly while payroll and financial intelligence stay restricted, matching how responsibility is actually divided in the company — and enforcing it at the API means hiding a screen is not the only thing standing between a role and the payroll data.
04 / The product in use
What Was Built
Real interfaces across the customer and operational experience.



05 / How it was built
Engineering Decisions
Laravel API over a MySQL schema covering clients, the service catalog, invoices and line items, daily journal entries, attendance, and payroll runs, as the single financial record behind every module.
Financial logic held server-side: invoice totals, per-item government fees and margins, discounts, tax, and salary calculation, with invoices and their journal entries written inside database transactions so the books cannot end up half-updated.
React 19 and TypeScript architecture organized into modular Redux Toolkit slices across billing, journals, payroll, reporting, and access control.
POS billing flow with client lookup by phone, per-item government fees and margins, global discounts, one-click PDF invoices and bilingual invoice emails in Arabic or English.
Filterable reports across revenues, expenses, services, tax, salaries, and debts, rendered through reusable paginated data tables, with any filtered view exported to Excel or CSV straight from the screen.
Financial-analysis room with live Recharts views for liquidity, expenses, profit margin, receivables aging, tax, and KPI trends.
Admin, receptionist and employee roles enforced in the Laravel API and mirrored as protected routes in the client, with real-time Firebase Cloud Messaging notifications.
06 / What changed
Delivered Outcome
The delivered system covers 61 screens across billing, daily journals, payroll, reporting, and access control.
Reception and management now use one system for invoicing, daily journals, payroll, and financial reporting.
Every invoice, expense, journal entry, and salary run is stored in one relational database instead of being spread across paper and separate spreadsheets.
Payroll calculations draw from attendance, bonuses, and deductions instead of being assembled through a separate manual process.
Management can review live financial views without rebuilding the picture from disconnected records.
Moving off spreadsheets did not mean losing them: any report exports to Excel or CSV for the external accountant, an audit request, or a tax filing, without re-keying figures.
Paper and spreadsheet workflows were consolidated into one role-based system, with migration and reconciliation included in rollout.
“Every invoice, expense and salary in the company now lives in one system — we finally see our numbers in real time.”
Facing a similar product challenge?
Bring the problem, the current state, and the outcome you need. We can turn that context into a clear product direction and a workable path to launch.