---
title: Admin console
description: The admin app - how operators log in and manage the platform's organizations and admins.
---

The admin console (`apps/admin`) is the operations surface where Africa OS staff manage the platform. It is a TanStack Start app separate from the tenant web app, using its own identity system (`@africaos/admin-auth`) and its own UI components.

### The route tree

```txt
routes/
├── login.tsx                    operator sign-in
├── _authenticated.tsx           session guard + admin shell
└── _authenticated/
    ├── index.tsx                overview / stats
    └── organizations.tsx        organization management
```

### Sign-in

`login.tsx` posts credentials to an admin auth server function backed by `AdminAuthService.login`. On success the app stores the returned session token in an HttpOnly cookie, so the token is never reachable from JavaScript.

### The authenticated shell

`routes/_authenticated.tsx` is the guard and layout:

- `beforeLoad` calls `adminGetSessionFn` (which runs `AdminAuthService.getSession` with the cookie token). No valid session means a redirect to `/login`.
- The layout mirrors the web shell's structure - `SidebarProvider` > `AdminSidebar` + `SidebarInset` with a floating header - but uses the admin app's **own components** rather than importing `@africaos/ui`. The admin console deliberately keeps a separate, self-contained component set.

### What it manages

- **Organizations** (`organizations.tsx`) - the tenant lifecycle: reviewing pending organizations, verifying, suspending. This is where the manual verification step of the organization state machine happens.
- **Overview** (`index.tsx`) - platform stats from `AdminAuthService.stats` (admins, active sessions) alongside organization counts from `OrganizationService.count`.

### Separations worth knowing

- **Identity** - operators use `admin.admins`/`admin.sessions`; tenants use Better Auth. They never cross.
- **UI** - the admin app keeps its own component set (base-ui, solar icons, its own `components/ui/*`) instead of `@africaos/ui`. The two apps are visually related but code-independent.
- **Scope** - admin functions read every organization (`OrganizationService.listAll`, `count`), which tenant-facing code must never do. Those methods are documented "admin-console only."

### Next steps

- [Admin auth](/platform/admin-auth) - the service behind the login.
- [Organizations](/platform/organizations) - the lifecycle the console manages.