The admin panel is half the product
Building Prime Optic taught me that an e-commerce app without a real admin panel isn't a product — it's a demo that needs me in the loop forever.
The first time a client asks "how do I add a new frame to the store?", you find out whether you shipped a product or a demo.
When I built Prime Optic, the obvious deliverable was the storefront — catalog, cart, checkout, order confirmations. The less obvious deliverable, and the one that took roughly as long, was the admin panel. Without it, every product change, every price update, every refund would have meant me opening a terminal. The site would be live, but the business wouldn't be.
What "fully operate the app" actually covers
Once you sit down and list what a small e-commerce owner needs to do without touching code, the surface is bigger than you'd expect:
- Products — add a new frame, edit price and description, swap images, mark something out of stock or discontinued.
- Stock — update quantities as inventory comes in, decrement automatically on order, get a flag when a SKU is low.
- Store metadata — change the shop name, update locations and hours, edit the "about" copy, swap a banner image without redeploying.
- Orders — see every order, filter by status, mark shipped, view the customer's contact details, handle a refund or cancellation.
- Users — at minimum, see who's bought what; ideally, promote another staff member to admin without me running a Firebase CLI command.
If any one of those requires a developer, you've handed the client a car with no steering wheel.
Build vs. buy
There's a tempting shortcut: drop in Retool, Forest Admin, or just hand the client access to the Firebase console. I built a custom panel on top of Firestore instead, for three reasons:
- Vocabulary matches the business. The client thinks in frames, lenses, brands, not documents in a collection. A custom UI uses the right nouns. Off-the-shelf tools force the user to translate.
- You can hide what shouldn't be edited. A generic admin exposes every field on every document, including the ones that exist for internal reasons. A custom panel only shows what's safe to change.
- The UI and the security model evolve together. When I added the "trusted staff" role, the form changes, the route guard, and the Firestore rule all moved as one PR. With an external tool, those live in different places and drift.
The tradeoff is honest: you write more code. I think it's the right call for a product the client will live inside every day, and the wrong call for an internal dashboard nobody loves.
Auth that doesn't lean on the UI
Hiding the admin button doesn't make the route admin-only. The actual gate is a custom claim on the Firebase Auth user — set server-side, read by Firestore security rules on every write:
match /products/{id} {
allow read: if true;
allow write: if request.auth.token.admin == true;
}
The UI mirrors that — admins see edit buttons, non-admins don't — but the database is the source of truth. If someone forges a request, the rule rejects it. If the UI has a bug and shows the wrong control, the rule still rejects it. UI guards are for ergonomics; database rules are for security.
The work you don't budget for
The admin panel was roughly as much work as the buyer-facing app. None of it is glamorous:
- Forms for every editable field, with validation, image upload, and a "discard changes" prompt.
- A real table for orders — sortable, filterable by status, paginated, with a detail view.
- Bulk actions: marking a batch of orders as shipped without clicking each one.
- Empty states, loading states, error states for every screen, because admins notice when those are missing.
If I had quoted Prime Optic assuming "and then a quick admin page" was the last 10% of the project, I would have undershot by weeks. The way I think about it now: the storefront is half the product. The admin panel is the other half. They get scoped together or not at all.
Why it matters more than it looks
A product without a real admin panel is one where the developer is still in the loop forever. Every typo, every new arrival, every shipping update routes back through Slack. That's bad for the client (they're blocked on you), bad for the product (changes are slow, so they don't happen), and bad for you (you're maintenance staff for something you thought you'd handed over).
The most useful thing an admin panel does isn't power. It's handing the keys over. The day the client adds a product without messaging me is the day Prime Optic stopped being my project and started being their store.