The admin panel for a mobile app is the control surface
Operators do not live inside the consumer app. They need a web admin panel on the same data — users, content, bookings, roles — or the mobile screens do not matter.

An admin panel for a mobile app is the web surface operators use to run the live product — users, content, bookings, offers, roles, payouts — on the same backend as the app. The store-facing screens are half the product. If a merchant cannot publish an offer, a clinic cannot see tomorrow’s list, or an instructor cannot record a payout, the mobile screens do not matter.
At FLUIDS the consumer app is Flutter or native Swift. The admin is React. Both talk to the same Supabase project. That is not a template. It is the other half of the product.
What an admin panel is — and what it is not
It is a role-gated web app on the same rows the mobile clients read and write. It is not a CMS. WordPress is for pages. This is for live operations. It is not a wall of charts. A dashboard is for observers. An admin panel is for operators — people who have to act. It is not a generated form over every table. It is not an “admin tab” inside the consumer app.
Why a serious mobile product needs a control surface
A calculator does not need an admin panel. Anything with users, content, bookings, offers, or money does. A merchant who cannot hide a closed branch will call you. A clinic that still runs the day on WhatsApp never left WhatsApp. An instructor who emails a spreadsheet for payouts is already doing the admin, badly.
The useful question is not “do we need an admin?” It is the test above. If the answer is a list, that list is the scope.
The admin and the app are one product
One schema. Two clients. The backend for a mobile app is not a second server for the dashboard. It is Postgres, auth, and storage. The phone and the admin share it. When a T-CODE merchant publishes an offer, the shopper sees it on the map. When a Naqrah clinic confirms a slot, the patient sees it in the app. There is no sync job. There is one row.
- T-CODE merchant — branches, offers, redemption codes. The shopper sees nearby coupons on a map.
- Naqrah clinic — appointments organised in one place. The patient books or reschedules in a few taps.
- Oxygen instructor — courses, exams, roster, payouts. The student studies inside the course.
- WOSTA supplier — quotes, invoices, a warehouse or branch of their own. The buyer compares offers.
Those are live products. Read them: T-CODE, Naqrah.app, Oxygen Academy, WOSTA. No invented rates. No invented user counts. Clinic booking and supply procurement are two products — that split has its own note. Local deals as a shopper face and a merchant face has another.
How we build it
The schema is designed once. Flutter or Swift for the consumer app. React for the admin. One Supabase project under both. The admin is designed next to the app screens, not after launch as a patch. Roles live in the data model from week one — in server-owned claims or a membership table, never in a field the user can edit. At handover the project and the credentials belong to you.
If the customer is an organization — a clinic, a merchant, a supplier — the admin is also a multi-tenant surface. Platform owner and organization admin are not the same login.
Roles, not a single admin login
A production admin is not one superuser. Owner, merchant, branch staff, reviewer — each can do some things and must not do others. A clinic must not see another clinic’s appointments. A receptionist must not change prices. A government reviewer may only read a locked year.
Permission lives in the database. Hiding a button in React is not access control. Anyone with the publishable key can call the API. Row-level security is the actual gate. The same policies apply to the mobile JWT and the admin JWT. The service-role key bypasses those policies. It belongs on a trusted server. It never ships in the browser, the app, a log, or a screenshot.
CareerFolio locks a finished performance year as a read-only archive and shares it through a secure link. That is a role, expressed as data, not as a menu item.
The weekly work
Content: publish or hide an offer, a course, a clinic profile, a branch. Operations: redeem a code, move an appointment, accept a quote, issue an invoice, mark a payout. That is the operator dashboard. Charts come later, if they come at all.
Some actions are dangerous. Delete a user. Refund. Change a role. Unlock an archive. Export personal data. Those need a confirmation, a reason, and a line in an audit log. An admin that cannot answer “who changed this, and when” is not finished. Export as a product problem sits in the PDPL note.
What to build first — and what to refuse
First: login, roles, the two or three weekly actions, search and filters on those records, an audit line on money and identity. Later: custom charts, forecasting, a full ticket product. A pixel-perfect mobile admin is almost never the first surface. Operators sit at a desk.
- Refuse a database GUI as the product.
- Refuse one login that can do everything.
- Refuse “we’ll add the admin after the App Store listing.”
Common mistakes
- Shipping the consumer app with no operator surface.
- Treating the admin as a CMS theme.
- Charts before queues.
- Permissions only in the React router.
- A second database “for the dashboard.”
The control surface is not phase two
It is how the business runs the day the app goes live. If you are scoping a mobile product and the admin is still a later slide, the product is not scoped. Write to us with the operators in the room, not only the screens the store will show.
Tell us what you’re building.
Write to us with the product you want built. You will get a considered reply from the people who would do the work.
Start a conversation