پلتفرم

Apps & platform

The same app on six platforms, and it keeps working when the network does not

A business app is judged on its worst moment, not its best one. The interesting engineering is not the screen that loads in two hundred milliseconds — it is the shift that carries on when the connection drops, the ticket that still reaches the right printer, and the notification that arrives in the language the person reading it actually speaks.

Akkad's admin app is one codebase compiled to six targets. Not a mobile app with a cut-down web viewer bolted on, and not a desktop build that is really a wrapped website — the same screens, the same logic and the same offline behaviour everywhere, which is why a feature does not arrive on one platform three months before another.

The practical consequence is that a business does not have to choose. The owner works on a laptop, the counter runs on a desktop machine with a scanner plugged into it, the delivery coordinator uses a phone, and someone checking a figure on a borrowed computer opens a browser. All of them are looking at the same application.

Where the app runs

TargetNotes
iOSNative build, with an in-app store version check and a per-version dismiss so an update prompt cannot become a permanent nag
AndroidNative build, same version check, and verified deep links so a shared install link opens the app rather than a browser page
WebFull application in the browser, installable as a progressive web app with a standalone display mode and maskable icons
macOSNative build with automatic updates delivered through a signed update feed
WindowsNative build with the same automatic update mechanism, on its own per-app feed
LinuxNative build from the same codebase

Desktop updates are signed. The macOS build carries a public key and verifies the signature on every update it downloads, so an update feed cannot be substituted for a hostile one. Each vertical points at its own feed, set at runtime, so the pharmacy app can never be handed the restaurant app's release.

What works offline, and what does not

The line is drawn at conflict. If an action can be replayed later without ambiguity, it works offline. If replaying it would require guessing what happened in between, it is blocked.

Works offlineBlocked offline
Browse and search the full cached catalogue by name, barcode or SKUCreating, updating or deleting items
Browse cached customersCreating, updating or deleting customers
Create orders — queued, and visible in the orders list straight awayUpdating or deleting an order that already exists on the server
Open a cashier session, including when the shift starts offlineBulk import
Close a cashier session, including one that was opened on the serverBulk status updates
Add dine-in rounds to an order the server already knows aboutExporting items or orders
Delete an order that is still only queued locally

A blocked action explains itself in the moment rather than failing silently, so nobody spends a minute wondering whether the tap registered.

The flush, in four phases

When the connection returns, the queue is not sent all at once. It is sent in a strict order, because the pieces depend on each other. The flush runs on app start, on connectivity recovery, and on a fifteen-minute background timer, and it is guarded against running twice at the same time.

  1. 1

    Session opens

    Any shift that was opened while offline is created on the server first, so it has a real server identity before anything is attached to it.

  2. 2

    Orders

    Queued orders are submitted next, and they attach to the session identity that phase one just established. If orders went first they would either attach to a local identity that never becomes real, or attach to nothing at all — and a drawer that cannot account for its own sales is worse than no drawer report.

  3. 3

    Dine-in rounds

    Rounds added to existing orders are appended after the orders exist. Each carries its own idempotency key, so a round that was sent and whose response was lost is not appended twice.

  4. 4

    Session closes

    Only once every order belonging to a shift has landed is the shift closed. The close computes the drawer from orders that are all actually present, so the expected cash figure is right the first time.

Why the queue never loses anything

Four decisions, each of which exists because the obvious alternative destroys data in a way nobody notices until much later.

Lost responses adopt the existing session

If a session open is rejected because the server already created it — a request that arrived, succeeded, and whose response never made it back — the app looks up the user's current open session and adopts it rather than treating the whole thing as failed. Without this, one lost response would strand every queued order behind a session that could never be created.

Deletion propagation has a fail-safe

Every sync returns the complete set of live item and customer identifiers, and the device prunes anything cached that is no longer in that set, in batches. If that list arrives missing, malformed or empty, pruning is skipped entirely. An empty list is far more likely to be a partial response than a business that deleted its entire catalogue, and acting on it would leave a cashier with nothing to sell.

Going offline is debounced, coming back is not

A three-second debounce on going offline stops a moment of poor signal from flipping the whole app into offline mode and back. Recovery is immediate, because there is no reason to wait once the connection is real.

There is a recovery probe for lying networks

When a low-level network error forces a hard offline flip, a probe loop runs every ten seconds until it gets a real answer. Operating systems sometimes report a healthy connection through a captive portal or a dead uplink; the app checks for itself rather than believing them.

Three print layouts

Each layout has its own paper sizes, and each is configured separately — an invoice and a thermal receipt are different documents with different jobs.

LayoutPaperTypical use
InvoiceA4 or US LetterThe document that goes to a business customer or into the file
Shipping label100 × 150 mm or 80 × 120 mmWhat the courier scans and reads at the door
Receipt80 mm or 58 mm thermal rollThe slip handed over at the counter

Thermal output is sized to the print head rather than the paper, which is the single most common source of receipts with a cut-off right edge. An 80 mm roll gets 576 dots across 72 mm at 203 DPI; a 58 mm roll gets 384 dots across 48 mm. Printers connect over the network using ESC/POS on the standard port, or over USB.

What triggers a notification

Every notification is localised to the recipient's own language and mirrored into a persistent in-app inbox, so nothing depends on someone having seen a banner at the right moment.

TriggerWho receives itWhen
New orderTeam members allowed to see that order's creator — including a pseudo-creator covering public storefront and landing-page ordersOn creation. A member restricted from seeing an order is not sent a push about it
Low stock and out of stockOrganisation ownersOn the stock change, one alert per item
Batch expiry digestOwners plus anyone holding the expiry report permissionDaily at 06:00 UTC, roughly 09:00 in Iraq. Two tiers: batches hitting the seven-day mark, and batches expiring today
Onboarding nudgesTrial usersDaily at 16:00 UTC, early evening in Iraq — one nudge, chosen by priority
Subscription noticesOwnersDaily at 08:30 UTC

The expiry digest needs no deduplication table. Because it matches on the exact day in the organisation's local time, and because it runs once a day, the daily run is the deduplication — a batch can only hit its seven-day mark on one day. Removing the need for state is usually better than managing the state well.

Questions

If the internet drops mid-shift, what actually happens?

The app switches to the local database after a three-second debounce and keeps taking orders. Everything created while offline queues locally and appears in the orders list immediately, so the shift looks normal. When the connection returns, the queue flushes in four phases — sessions, orders, rounds, then session closes — and nothing is deleted at any point.

Can two people take orders offline on different devices?

Yes. Each device holds its own queue and its own cashier session, and each flushes independently when it reconnects. Order creation carries an idempotency key, so a submission whose response was lost returns the original order rather than creating a second one.

Why can't I create an item while offline?

Because uniqueness on SKUs and barcodes is enforced across the whole organisation, and two disconnected devices cannot both guarantee it. Rather than accept the item and reject it hours later during a flush — after it has already been sold — the action is blocked with a message at the moment you try.

Does my thermal receipt need configuring for paper width?

You choose 80 mm or 58 mm and the printable area is derived from the print head, not the paper. That is why receipts do not come out with the right column clipped, which is the usual symptom of a layout sized to paper width instead.

How do kitchen tickets know which printer to use?

Each station printer is mapped to a set of categories, and a round's lines are routed accordingly. A category mapped to nothing goes to the fallback station rather than being dropped — in a kitchen, a ticket that silently never printed is the failure that costs a table.

Will my team get notifications in their own languages?

Yes. Notifications are localised per recipient rather than per business, so a mixed team each reads the same alert in their own language, and the same is true of API error messages and of stock history.

Counter & cashbox

Drawer sessions, scanning and the shift close that the offline flush is ordered around.

Orders

Idempotent creation, editing with a change log, and the statuses the queue replays into.

Team & permissions

The grants that gate printing and reports, and the visibility rules notifications honour.

آن را روی فهرست کالاهای خودتان ببینید

با بستهٔ مناسب شروع کنید، کالاهایتان را از یک فایل اکسل وارد کنید، و همان روز فروشگاه، صندوق و دفتر سفارشِ فعال داشته باشید.

بستهٔ رایگان موجود است. برای امتحان به کارت نیاز نیست. ورود اطلاعات، فهرست کالاهای فعلی شما را همراهتان می‌آورد.