Routing and Layouts
AEGIS uses the Next.js App Router with route groups to separate public pages (login) from authenticated dashboard pages. This page documents the complete routing structure, layout hierarchy, and authentication middleware.
Layout Hierarchy
RootLayout (app/layout.tsx)
├── ThemeProvider (next-themes, dark default)
│ └── AuthProvider (React context for user state)
│ └── TooltipProvider (shadcn/ui tooltips)
│ ├── LoginPage (/login)
│ └── DashboardLayout (app/(dashboard)/layout.tsx)
│ ├── Sidebar (collapsible navigation)
│ ├── Topbar (tenant info, density toggle, theme, user)
│ ├── Toaster (sonner toast notifications)
│ └── DashboardShell
│ ├── DensityProvider (compact/comfortable/spacious)
│ ├── CommandPalette (Cmd+K)
│ └── PageTransition (Framer Motion)
│ └── {page content}Root Layout
Located at src/app/layout.tsx, the root layout wraps the entire application:
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body className={`${inter.variable} ${jetbrainsMono.variable} antialiased`}>
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem>
<AuthProvider>
<TooltipProvider>{children}</TooltipProvider>
</AuthProvider>
</ThemeProvider>
</body>
</html>
);
}Key details:
- Fonts: Inter (body text) and JetBrains Mono (monospace/code) loaded via
next/font/google. - Theme: Dark by default, with system theme detection enabled.
- Auth:
AuthProviderwraps all pages so both login and dashboard pages can access auth state. - Metadata: Title is “AEGIS — Oil & Gas Compliance Platform”.
Root Page
The root page at src/app/page.tsx immediately redirects to the compliance dashboard:
import { redirect } from "next/navigation";
export default function Home() { redirect("/compliance"); }Dashboard Layout
The (dashboard) route group at src/app/(dashboard)/layout.tsx wraps all authenticated pages:
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex h-screen overflow-hidden">
<Sidebar />
<div className="flex-1 flex flex-col overflow-hidden">
<Topbar />
<main className="flex-1 overflow-auto bg-background p-6 flex flex-col">
<DashboardShell>{children}</DashboardShell>
</main>
</div>
<Toaster richColors position="bottom-right" />
</div>
);
}The layout uses a horizontal flex layout: collapsible sidebar on the left, main content area on the right with topbar + scrollable content.
The DashboardShell component provides:
- DensityProvider: manages compact/comfortable/spacious display modes, stored in
localStorage. - CommandPalette: global Cmd+K navigation overlay.
- PageTransition: Framer Motion
AnimatePresencefor smooth page transitions keyed onpathname.
Page Routes
| Path | File | Description |
|---|---|---|
/ | app/page.tsx | Redirects to /compliance |
/login | app/login/page.tsx | Email/password login page |
/compliance | app/(dashboard)/compliance/page.tsx | Compliance dashboard (default landing) |
/compliance/[entityId]/[domain] | app/(dashboard)/compliance/[entityId]/[domain]/page.tsx | Entity compliance workspace (three-panel layout) |
/filings | app/(dashboard)/filings/page.tsx | Filing review queue (HITL approval) |
/flaring | app/(dashboard)/flaring/page.tsx | Flaring dashboard with R-32 tracking |
/events | app/(dashboard)/events/page.tsx | Events timeline |
/events/[eventId] | app/(dashboard)/events/[eventId]/page.tsx | Event detail view |
/conversations | app/(dashboard)/conversations/page.tsx | Agent chat with SSE streaming |
/entity | app/(dashboard)/entity/page.tsx | Redirects to /entity/well |
/entity/[type] | app/(dashboard)/entity/[type]/page.tsx | Entity list by type |
/entity/well/[id] | app/(dashboard)/entity/well/[id]/page.tsx | Well detail view |
/entity/facility/[id] | app/(dashboard)/entity/facility/[id]/page.tsx | Facility detail view |
/entity/[type]/[id] | app/(dashboard)/entity/[type]/[id]/page.tsx | Generic entity detail view |
/configuration/entity-types | app/(dashboard)/configuration/entity-types/page.tsx | Entity type definitions |
/configuration/entity-types/[typeId] | app/(dashboard)/configuration/entity-types/[typeId]/page.tsx | Entity type detail/edit |
/configuration/relationship-types | app/(dashboard)/configuration/relationship-types/page.tsx | Relationship type definitions |
/configuration/relationship-types/[id] | app/(dashboard)/configuration/relationship-types/[id]/page.tsx | Relationship type detail |
/configuration/event-types | app/(dashboard)/configuration/event-types/page.tsx | Event type definitions |
/configuration/event-types/new | app/(dashboard)/configuration/event-types/new/page.tsx | Create new event type |
/configuration/event-types/[typeId]/edit | app/(dashboard)/configuration/event-types/[typeId]/edit/page.tsx | Edit event type |
/configuration/event-types/[typeId]/detection-rules/[ruleId] | nested page | Detection rule editor |
/configuration/prompts | app/(dashboard)/configuration/prompts/page.tsx | Prompt namespace list |
/configuration/prompts/[namespaceKey] | nested page | Namespace detail (templates, settings, tiers, access) |
/configuration/prompts/[ns]/[slug] | nested page | Template detail with version sidebar |
/configuration/prompts/[ns]/[slug]/versions/draft | nested page | Version editor with validation panel |
/configuration/prompts/[ns]/[slug]/versions/history | nested page | Version history table |
/configuration/prompts/[ns]/[slug]/versions/compare | nested page | Side-by-side version comparison |
/configuration/prompts/approvals | app/(dashboard)/configuration/prompts/approvals/page.tsx | Prompt approval queue |
Sidebar Navigation
The sidebar is defined in src/components/sidebar.tsx and features:
- Collapsible with animated width transition (52px collapsed, 240px expanded). State is persisted to
localStorageunderaegis-sidebar-collapsed. - Active indicator — a blue vertical bar animates between items using Framer Motion
layoutId. - Sections: primary navigation items, a divider, and a “Configuration” section with nested children.
Navigation items:
Compliance /compliance (ShieldCheck icon)
Filings /filings (ClipboardList icon)
Flaring /flaring (Flame icon)
Events /events (CalendarClock icon)
Conversations /conversations (MessageSquare icon)
Entity Explorer /entity (Landmark icon)
--- divider ---
Configuration
Entity Types /configuration/entity-types (LayoutGrid icon)
Relationship Types /configuration/relationship-types (GitBranch icon)
Event Types /configuration/event-types (Zap icon)
Prompts /configuration/prompts (FileCode icon)
Approvals /configuration/prompts/approvals (CheckCircle icon)The sidebar footer displays the fixed context “RRC District 08 — Permian Basin”.
Authentication Middleware
The middleware at src/middleware.ts protects all dashboard routes:
const PUBLIC = ["/login", "/_next", "/favicon.ico"];
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
if (PUBLIC.some((p) => pathname.startsWith(p))) return NextResponse.next();
const token = request.cookies.get("aegis_token")?.value;
if (!token) {
const url = new URL("/login", request.url);
url.searchParams.set("redirect", pathname);
return NextResponse.redirect(url);
}
return NextResponse.next();
}
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
};Key behavior:
- Public paths (
/login,/_next,/favicon.ico) are excluded from auth checks. - If no
aegis_tokencookie is found, the user is redirected to/loginwith aredirectquery parameter to return them to their original destination after login. - The middleware only checks for the presence of a cookie — actual token validation happens at the API Gateway when backend requests are made.
Login Page
The login page at src/app/login/page.tsx provides an email + password form:
- User enters their email and password.
- The
login()function inlib/api.tssends a POST to the auth service athttp://localhost:8009/auth/token. - On success, the JWT token is stored in a cookie (
aegis_token) with 24-hour expiry. - User data (
user_id,roles) is stored inlocalStorageandAuthContext. - The user is redirected to their original path or
/conversations.
For local development, log in with admin@aegis.local / aegis-dev-admin (the seeded bootstrap admin). Accounts are admin-provisioned via the auth-service CLI — there is no self-serve signup.
Topbar
The topbar (src/components/topbar.tsx) displays:
- Tenant info: “Permian Basin Energy LLC” with tenant label.
- Search: Cmd+K shortcut button that triggers the command palette.
- Density toggle: Three-mode toggle (compact, comfortable, spacious) for adjusting UI density.
- Admin link: External link to
/admin. - User info: Role badge (Admin/Operator), user ID, theme toggle, and sign-out button.