All documents

MERIDIAN · DOC 09 / 25

Platform Admin

Control-plane permissions, tenant list, detail tabs, password reset, and server-authorized tenant dashboard access.

IMPLEMENTED Phase 4 (tenants) · Phase 8 (console + website management).

The platform owner's control plane at /admin (production host: admin.{platformDomain}; locally localhost:3000/admin). Every page is SSR-guarded for PLATFORM_ADMIN, and every endpoint behind it re-checks the role server-side — hidden UI is never the control.


1 · Permissions

Platform Admin canPlatform Admin cannot
Create/edit tenants, run the lifecycle, reset the tenant admin's passwordRetrieve any existing password (hashes only)
Edit website content, branding, navigation, sections, order, SEODelete a tenant or its data (no hard delete exists)
View a tenant's packages read-only ("open tenant dashboard")Mutate packages, statuses, or locations (tenant-admin surface)
See platform-wide metricsBypass authorization ("privileged, not invisible")

Tenant Admins are confined to packages + their own account (docs/tenant-management.md, docs/website-configuration.md §9).

2 · Navigation

Overview · Tenants · Settings · Sign out — nothing else. No billing, customers, marketing, support, staff, subscriptions or invoices (out of V1 by decision).

3 · Overview

GET /api/v1/platform/stats → tenant lifecycle counts (total / active / suspended / archived) and package totals (total / active shipments / delivered, where "active" = the four non-DELIVERED locked statuses, archived packages excluded).

4 · Tenants list

Server-side search (company, slug, admin name, admin email), status filters (All / Active / Suspended / Archived — All shows active + suspended), whitelisted sorts (Newest / Oldest / Most packages / Company name), server-side pagination (≤50/page) with {page, limit, total, totalPages}. Row actions: Manage (detail), Quick view (drawer), and lifecycle buttons appropriate to the current status.

5 · Tenant detail tabs

TabContents
Overviewcompany info form (name, phone, email, address), facts (subdomain, status, admin, package count, website state, timestamps)
Websitesection visibility + ordering, hero, services, about, features, tracking CTA, contact/hours, footer + social, SEO
Brandinglogo/favicon URLs, tagline, five-color palette, typeface, button style, radius, theme, live swatch preview
Admintenant admin name/email/status + password reset (one-time reveal)
Packagesserver-authorized read-only list of that tenant's shipments
Settingslifecycle state and everything derived from it, plus lifecycle actions

Header actions: Preview website and the lifecycle buttons. Dangerous actions (suspend, archive, reset) use two-step confirmation with an explicit consequence label.

6 · Password reset

Generates a one-time temporary password → Argon2id hash → replaces the stored hash → destroys every session of that admin. The plaintext is shown exactly once, never emailed, never retrievable (docs/authentication.md).

7 · Open tenant dashboard

GET /api/v1/platform/tenants/:tenantId/packages — the Platform Admin reads one tenant's packages while remaining a Platform Admin: no credential borrowing, no session swap, no impersonation token. The query is explicitly scoped to the requested tenantId, and the capability is read-only; mutations remain on the tenant's own authenticated surface. No client-visible audit log is built (explicitly out of scope); ordinary structured logs record platform mutations.

8 · Lifecycle from the console

ACTIVE ⇄ SUSPENDED, ACTIVE → ARCHIVED, ARCHIVED → ACTIVE; invalid transitions are refused with 400 INVALID_TENANT_STATUS. Suspension and archival immediately destroy that tenant's admin sessions and disable the public website, tracking, and realtime subscriptions. Data is always retained — restoration is status-only.