npm package: @geenius/admin
Description: Geenius Admin — Super admin panel for Convex apps (React + SolidJS)
Author: Antigravity HQ
Latest version: 0.1.0

# @geenius/admin

> Super-admin panel for Convex-backed Geenius apps — React + SolidJS, role-gated, fully typed.

## Packages

| Sub-package | Import path | Description |
|---|---|---|
| `shared` | `@geenius/admin/shared` | Types, validators (Zod v4), permissions, constants |
| `react` | `@geenius/admin/react` | React components & pages |
| `solidjs` | `@geenius/admin/solidjs` | SolidJS components & pages |
| `convex` | `@geenius/admin/convex` | Convex mutations/queries for admin operations |
| `react-css` | `@geenius/admin/react-css` | OKLCH design system stylesheet (React) |
| `solidjs-css` | `@geenius/admin/solidjs-css` | OKLCH design system stylesheet (SolidJS) |

## Installation

```bash
pnpm add @geenius/admin
```

## Quick Start (React)

```tsx
import '@geenius/admin/react-css'
import {
  AdminSidebar,
  AdminUsersPage,
  AdminDashboardPage,
  AdminRolesPage,
  AdminApiKeysPage,
  AdminHealthPage,
  AdminSettingsPage,
} from '@geenius/admin/react'

const navItems = [
  { label: 'Dashboard', href: '/admin', icon: '📊' },
  { label: 'Users', href: '/admin/users', icon: '👥' },
  { label: 'Roles', href: '/admin/roles', icon: '🛡️' },
  { label: 'API Keys', href: '/admin/api-keys', icon: '🔑' },
  { label: 'Health', href: '/admin/health', icon: '💚' },
  { label: 'Settings', href: '/admin/settings', icon: '⚙️' },
]

function AdminApp({ admin }) {
  return (
    <AdminUsersPage
      admin={admin}
      navItems={navItems}
      appName="My App"
      onNavigate={(href) => router.push(href)}
    />
  )
}
```

## Roles & Permissions

Five built-in roles form a strict hierarchy:

| Role | Label | Key Permissions |
|---|---|---|
| `super_admin` | Super Admin | All permissions |
| `admin` | Admin | Users, roles, API keys, metrics, audit, settings, billing |
| `staff` | Staff | User lookup, moderation — no billing or role changes |
| `moderator` | Moderator | User moderation, audit read |
| `viewer` | Viewer | Read-only |

```ts
import { checkPermission, hasAnyPermission, getRoleDefinition, PERMISSIONS } from '@geenius/admin/shared'

// Check a single permission
const canBan = checkPermission(admin.role, admin.permissions, 'users:ban')

// Check any of several permissions
const canManageUsers = hasAnyPermission(admin.role, admin.permissions, ['users:write', 'users:ban'])

// Get the full definition for a role
const def = getRoleDefinition('staff')
// { name: 'staff', label: 'Staff', permissions: [...], isSystem: true }
```

### Full Permission List

`users:read` · `users:write` · `users:delete` · `users:ban` · `users:impersonate` · `roles:read` · `roles:write` · `api_keys:read` · `api_keys:write` · `api_keys:revoke` · `metrics:read` · `audit:read` · `audit:export` · `settings:read` · `settings:write` · `billing:read` · `billing:write` · `data:export` · `health:read` · `system:manage`

## Pages

### `AdminDashboardPage`

System metrics overview (users, MRR, churn, session duration).

```tsx
<AdminDashboardPage
  admin={adminUser}
  navItems={navItems}
  appName="My App"
  onNavigate={handleNav}
  metrics={systemMetrics}        // SystemMetrics
  isLoading={false}
/>
```

### `AdminUsersPage`

Full user management: search, filter, ban/unban, impersonate, bulk actions.

```tsx
<AdminUsersPage
  admin={adminUser}
  navItems={navItems}
  appName="My App"
  onNavigate={handleNav}
  users={managedUsers}           // ManagedUser[]
  totalCount={500}
  isLoading={false}
  onSearch={(q) => setQuery(q)}
  onBanUser={(id) => banUser(id)}
  onUnbanUser={(id) => unbanUser(id)}
  onImpersonateUser={(id) => impersonate(id)}
  onBulkAction={(action) => runBulkAction(action)}
  enableImpersonation={true}
  enableBulkActions={true}
/>
```

### `AdminAuditPage`

Searchable audit log with action icons and timestamps.

```tsx
<AdminAuditPage
  admin={adminUser}
  navItems={navItems}
  appName="My App"
  onNavigate={handleNav}
  logs={auditLogs}               // AuditLogEntry[]
  isLoading={false}
  onSearch={(q) => setSearch(q)}
  onExport={() => exportLogs()}
/>
```

### `AdminRolesPage`

Role summary cards + full permission matrix grid.

```tsx
<AdminRolesPage
  admin={adminUser}
  navItems={navItems}
  appName="My App"
  onNavigate={handleNav}
  onPermissionToggle={(role, perm, enabled) => updatePermission(role, perm, enabled)}
/>
```

### `AdminApiKeysPage`

API key listing with create/revoke flows, scope selector, security notice.

```tsx
<AdminApiKeysPage
  admin={adminUser}
  navItems={navItems}
  appName="My App"
  onNavigate={handleNav}
  apiKeys={apiKeys}              // ApiKey[]
  isLoading={false}
  onCreateKey={(name, scopes) => createKey(name, scopes)}
  onRevokeKey={(id) => revokeKey(id)}
/>
```

### `AdminHealthPage`

Service health grid with status banners (healthy / degraded / down), latency, refresh button.

```tsx
<AdminHealthPage
  admin={adminUser}
  navItems={navItems}
  appName="My App"
  onNavigate={handleNav}
  services={serviceHealth}       // ServiceHealth[]
  isLoading={false}
  onRefresh={() => refetchHealth()}
  lastRefreshed={Date.now()}
/>
```

### `AdminSettingsPage`

Feature toggles (impersonation, data export, bulk actions, MFA) + numeric settings + system config table.

```tsx
<AdminSettingsPage
  admin={adminUser}
  navItems={navItems}
  appName="My App"
  onNavigate={handleNav}
  config={adminConfig}           // AdminConfig
  systemConfig={systemConfigs}   // SystemConfig[]
  isSaving={false}
  onSave={(updates) => saveConfig(updates)}
/>
```

## Components

### `AdminSidebar`

Navigation sidebar, renders nav items with active state, impersonation banner.

### `RoleMatrix`

Full permission × role grid with tick/cross cells. Accepts optional `onPermissionToggle` for editable mode.

### `SystemHealthCard`

Card displaying a set of `ServiceHealth` entries in a grid with colour-coded status dots.

### `ApiKeyManager`

Inline create-key form (name + scope checkboxes) + key table with revoke buttons.

### `PermissionGate`

Wrapper that conditionally renders children based on permission check:

```tsx
import { PermissionGate } from '@geenius/admin/react'

<PermissionGate admin={admin} permission="users:delete">
  <DeleteButton />
</PermissionGate>
```

## Validation (Zod v4)

```ts
import { AdminUserSchema, ManagedUserSchema, ApiKeySchema, BulkActionSchema } from '@geenius/admin/shared'

// Parse and validate incoming data
const adminUser = AdminUserSchema.parse(rawData)
const bulk = BulkActionSchema.parse({ type: 'ban', userIds: ['u1', 'u2'] })
```

## Design System

Import the stylesheet in your app entry point:

```ts
// React
import '@geenius/admin/react-css'

// SolidJS
import '@geenius/admin/solidjs-css'
```

All colours use OKLCH. Dark mode is handled automatically via `@media (prefers-color-scheme: dark)`.

**CSS custom properties:**

| Token | Light | Dark | Usage |
|---|---|---|---|
| `--admin-primary` | `oklch(0.55 0.2 250)` | `oklch(0.65 0.2 250)` | Buttons, active links |
| `--admin-surface` | `oklch(0.98 0 0)` | `oklch(0.13 0.01 250)` | Card/page backgrounds |
| `--admin-text` | `oklch(0.15 0 0)` | `oklch(0.92 0 0)` | Body text |
| `--admin-border` | `oklch(0.88 0.01 250)` | `oklch(0.28 0.015 250)` | Borders, dividers |
| `--admin-success` | `oklch(0.65 0.2 150)` | `oklch(0.7 0.2 150)` | Active/healthy states |
| `--admin-warning` | `oklch(0.75 0.18 85)` | `oklch(0.78 0.18 85)` | Degraded/suspended |
| `--admin-danger` | `oklch(0.6 0.25 25)` | `oklch(0.68 0.22 25)` | Banned/error/down |

## TypeScript Types

```ts
import type {
  AdminUser, ManagedUser, AdminRole, UserStatus,
  ApiKey, ApiKeyScope, AuditLogEntry, SystemMetrics,
  AdminConfig, SystemConfig, ServiceHealth, BulkAction,
  RoleDefinition, FeatureFlag,
} from '@geenius/admin/shared'
```

## Constants

```ts
import {
  ADMIN_ROLES,         // ['super_admin', 'admin', 'staff', 'moderator', 'viewer']
  USER_STATUSES,       // ['active', 'suspended', 'banned', 'pending']
  API_KEY_SCOPES,      // ['read', 'write', 'admin', 'billing', 'users', 'audit']
  PERMISSIONS,         // full 20-entry permission list
  ROLE_ICONS,          // { super_admin: '👑', admin: '🛡️', staff: '🎯', ... }
  ACTION_ICONS,        // { create: '➕', ban: '🚫', ... }
  STATUS_COLORS,       // oklch color strings keyed by status
  DEFAULT_PAGE_SIZE,   // 25
  MAX_BULK_SELECTION,  // 100
  DEFAULT_ADMIN_CONFIG,
} from '@geenius/admin/shared'
```