Shipping a workforce app to both stores in 10 weeks

By

Original article

How I built Tech 92, Technology 92’s attendance and KPI app, from the first commit to the App Store and Google Play in 68 days, then kept it stable through 13 updates in its first 4 months.

Tech 92 app on three phones: KPI list, home screen with check-in button, and attendance timer, next to App Store and Google Play badges

The brief and the clock

Technology 92 needed one app for its employees: clock in and out, log daily KPIs, keep a profile, and read company updates, in Arabic and English. The first commit landed on 15 February 2026. Version 1.0.0 went live on the App Store and Google Play on 24 April: 68 days, just under 10 weeks.

I built each feature end to end, from the Flutter screen to the Laravel endpoint behind it. That removed the usual wait between “the app is ready” and “the API is ready”.

Structure that lets you move fast

The app is split into 15 feature modules (attendance, KPIs, profile, leave requests, notifications and more), each with its own data, domain and presentation layers. State lives in BLoC and Cubit, dependencies are wired with get_it, navigation uses go_router, and every request goes through one Dio client.

Arabic and English were there from the first screen, not added at the end. CI checks that translations are generated, the code is formatted and analysed, and the tests pass; Codemagic builds and sends each release to TestFlight and the Play internal track.

Clocking in without a signal

Employees check in from wherever they are, and the signal is not always there. When the phone is offline, a check-in or check-out goes into a queue saved on the device, and the screen updates straight away so the timer starts. When the connection returns, the queue is sent in order.

Every queued action carries an idempotency key, so if the same check-in is replayed the backend ignores the duplicate. An item that fails three times is parked for a manual retry instead of blocking the rest, and one corrupted entry is skipped without losing the others. The same queue now also covers KPI entries, leave requests and complaints.

Time is harder than it looks

Most of the tricky bugs were about time. A shift from 22:00 to 06:00 has to be drawn as one continuous block that crosses midnight, not two broken pieces. Converting between the server’s timezone and the phone’s could move a record to the wrong day. The loading skeleton could get stuck at the exact moment a shift crossed midnight, and fast repeated taps could send the same status update twice. Each one got a fix and a test.

Shipping after launch

Launch was the start. Between 24 April and 21 August the app shipped 13 updates: offline-friendly KPI editing, admin-managed banners that still show without a connection, a redesigned onboarding, and seasonal themes switched on from the dashboard. Sentry reports crashes, and the app has about 800 automated tests covering logic, BLoCs and widgets.

Today about 100 employees in 4 countries use it every month. They have logged more than 1,600 check-ins and 700 KPI entries, and the app is 100% crash-free.

What I would do again

Own the feature end to end so nothing waits on a hand-off. Design for bad connectivity from the first week, because retrofitting an offline queue is far harder than starting with one. And treat dates and times as a feature with its own tests, not a detail.

Read the case study: Tech 92 — Workforce Attendance & KPI App →