S
supero.docs
Documentation/Managing Your App/Admin vs Customer Views

Admin vs Customer Views

Every generated Supero app ships one bundle that renders two different experiences — an operator admin shell and a task-oriented customer view. Here's exactly what each one shows, and how the split is decided.

Overview

You don't build an admin panel and a customer-facing app as two separate projects. Every Supero app is one deployment, and the shell it renders for a given signed-in user — the operator sidebar with a dashboard, or a simplified task-oriented view of just their own stuff — is chosen automatically from that user's role. This page is for anyone deciding which of their app's own users should land where, and for anyone wondering why an app looks different depending on who's logged in.
It covers what's actually on screen in each view: the admin shell's dashboard, per-schema tabs, and System Settings modal; the multi-tenant Tenant Switcher; what a customer's reshaped tab list looks like; and how owner-scoping keeps a customer's "My X" lists limited to their own records. For the underlying role catalog and permission mechanics, see the Roles & Permissions Reference page — this page is about what renders, not how access is checked.

How the View Is Chosen

At login, Supero resolves the signed-in user's role and stamps a ui_view of either admin or customer onto the session (mirrored as context.surface in the response). The generated app's runtime reads this once at boot — via client.userInfo.ui_view, or the convenience helpers client.isAdmin() / client.isCustomer() — and picks a shell accordingly. Nothing in your own app code has to match role strings by hand.
http
POST https://api.supero.dev/api/v1/auth/login
Content-Type: application/json

{
  "domain": "acme-corp",
  "email": "[email protected]",
  "password": "secret123"
}

# Response (relevant fields only)
{
  "user": { "role": "tenant_user", "ui_view": "customer" },
  "context": { "surface": "customer" }
}
ui_view = adminui_view = customer
domain_admin, project_admin, tenant_admin, developerdomain_user, project_user, tenant_user, viewer

ℹ️ Full role mechanics live elsewhere

This table is the same admin/customer split covered in depth on the Roles & Permissions Reference page, including the domain_user/project_user pitfall (broad cross-tenant CRUD access, but still the customer surface). This page picks up from there and focuses on what each surface actually contains.

Touring the Admin Shell

A user in the admin view gets the operator shell: a sidebar (or top nav, depending on your app's layout) grouped into the sections you define on your tabs, plus a few things that are always there.
  • •Dashboard — the first item in the first section, showing KPI tiles and charts computed from your schemas' data. It's an admin-only pseudo-tab; it never renders for a customer.
  • •One tab per schema you've exposed, grouped by the section label you set on each tab (tabs without a section fall into a default "Navigation" bucket).
  • •An account-menu footer with an AI Assistant shortcut (when your app doesn't already surface AI as its own tab), a System Settings entry, and Sign out.
  • •For admin roles specifically, a quick link out to your app's own admin console in a new tab — covered on The Admin Panel page.
In a multi-tenant app, admin-shell users with the right scope also get an "Acting as" Tenant Switcher near the top of the sidebar — see the dedicated section below.

System Settings: Password, Services, Workflows

For the complete set, see Roles & Permissions Reference.
Every signed-in user — admin or customer — has a System Settings modal, opened from the gear icon in the account-menu footer. It's tabbed, and which tabs show up depends on role.
TabWho sees itWhat it does
Change passwordEveryoneCurrent password, new password, confirmation. On success the user is signed out and has to log back in with the new password.
ServicesEveryoneLists the services your project has imported, each with a status badge — Active, or Needs config. It's a lightweight in-app view over the same object the services catalog API manages; it's not a replacement for the console.
WorkflowsEveryonePoints to the Workflows console for this app's automations.
LoginAdmin roles onlyA per-browser toggle for the demo-account autofill chips shown on the sign-in screen — useful while previewing, irrelevant once an app is actually published (published apps hide demo chips automatically).
LandingAdmin roles onlyPreview the customer-facing landing page inside the same session, with an option to swap hero and section images, then return to the admin view.
On the Services tab, the two config paths split by permission. Anyone holding service:configure (platform_admin/platform_user, domain_admin, project_admin, and developer) additionally sees a one-click action to provision starter test credentials for services that offer them — clearly labeled for testing only, never for production. Every role, including tenant_admin, instead sees a direct link out to the console's Services page to enter real, per-service production credentials.

💡 Configuring integrations for real

System Settings > Services is a status view, not the primary place to configure an integration. Import and configure services through the managed services catalog — GET /api/v1/services/catalog to see what's available, POST /api/v1/services/import to add one to your project, and PUT /api/v1/services/{id}/config to set its credentials.

The Tenant Switcher

In a multi-tenant app (isMultiTenant on the project), the admin shell shows an "Acting as" dropdown near the top of the sidebar for roles that legitimately operate across tenants. It lists every tenant in the project except default-tenant, plus a 🔒 Default scope option and a Manage tenants… entry that jumps to the full tenant-management page.
RoleSees the switcher
platform_admin / platform_userYes
domain_adminYes
project_adminYes
tenant_adminYes
developerNo — a project-scoped technical role, not a tenant operator
Any customer-view role (domain_user, project_user, tenant_user, viewer)Never — the switcher is admin-shell only
Picking a tenant from the dropdown scopes the current browser session's reads and writes to that tenant without a fresh login — useful for support and QA across many customers without juggling separate accounts. Picking Default scope returns to the signed-in user's own tenant.

The Customer View

A user whose role resolves to ui_view=customer doesn't get a stripped-down copy of the admin shell — the same tab set is reshaped into a task-oriented journey before it ever renders.
  • •The Dashboard is dropped entirely — customers don't see operator KPI tiles.
  • •Any tab whose section is named System, Admin, Administration, or Settings is dropped, so schema authors can keep genuinely operator-only tabs out of the customer view just by naming their section one of those.
  • •Every remaining tab is sorted into Browse (a read-only catalog — things to look at) or Mine (records the customer actually owns, relabeled "My <X>", where creating a new one happens too). Browse renders first, Mine after.
  • •Purely internal linking entities (line items, cart items, and similar) never get their own tab on either surface.
Which group a schema lands in is automatic by default — based on whether the signed-in role can create that entity and whether it's wired to a transactional service — but a schema author can force it per record type with the customer_surface field on its UI schema (values: browse, mine, shop, hidden). The full field reference, including how it interacts with the surface value on each UI schema, is on the Dynamic UI page.

Owner Scope: What "Mine" Actually Means

A "My <X>" tab needs two things working together, not one. The real boundary is server-side: a per-schema access_policy / access_rule with a filter_field and filter_match (for example filter_field: "customer_email", filter_match: "$user.email") that scopes reads, writes, and record creation to the caller's own identity. That mechanism — including exactly how it resolves and what happens on a mismatched record — is documented on the Access Control (RBAC) page.
On top of that, the shell itself applies a best-effort client-side match on the signed-in user's own identity and drops rows that don't belong to them before rendering. This is a non-authoritative backstop only — it can be bypassed and is not a substitute for the server-side access_rule.

⚠️ The tab label alone scopes nothing

Setting customer_surface: "mine" on a UI schema controls navigation, labeling, and ordering only. Without a matching access_rule that actually scopes that entity to the caller, a permissive policy can still hand back every tenant's records to whoever opens a "Mine" tab — the client-side filter is a defensive backstop, not a substitute for configuring the real one.

Choosing the Right Role When You Provision Users

For the complete set, see Roles & Permissions Reference.
This is the one decision that determines which of the two experiences above someone gets — get it wrong and a customer either can't do anything, or ends up looking at your operator dashboard.
Who they areAssign
A real end customer of your app — a shopper, patient, guest, membertenant_user
A read-only external party (auditor, reporting partner)viewer
Your own staff running one tenant day to daytenant_admin
Staff who need the operator shell across every tenant in the project (support, ops)project_admin
A cross-tenant analyst or integration account that only needs API-level read/CRUD, not the operator UIproject_user or domain_user
Engineers who need schema, SDK, and cross-tenant testing accessdeveloper

⚠️ Cross-tenant read access is not the same as the admin shell

domain_user and project_user get full CRUD across every project/tenant they can see, but they still land on the customer view, not the admin shell — that split is by design (those roles are meant for cross-tenant data access, not operating the app). If you're building an internal cross-account tool on top of one of those roles, don't assume the admin shell renders for it automatically; you may want project_admin or tenant_admin instead, or a purpose-built API integration.

💡 Decide this once, at invite time

Whether someone sees your operator tools or your product's customer journey comes down entirely to the role you hand them when you create or invite the account — there's no separate flag for it. Changing someone's mind later means changing their role (see Users & Roles), not changing app code.

Next steps

Related pages:
  • •Roles & Permissions Reference — the full role catalog, hierarchy, and sign-in flows behind the admin/customer split on this page
  • •Access Control (RBAC) — how to configure the access_policy/access_rule owner-scoping that backs every "Mine" tab
  • •Dynamic UI — the full customer_surface and surface field reference for controlling how a schema shows up per view
  • •Building Multi-Tenant Apps — the Domain -> Project -> Tenant hierarchy the Tenant Switcher operates over