Skip to main content
Version: 0.58.1-rc.5

Admin Panel

This document describes the Admin Panel architecture and development.

Purpose

The Admin Panel is the main interface for bank staff:

  • Customer management
  • Credit administration
  • Deposit and withdrawal operations
  • Approvals and governance
  • Financial reports

Architecture

Project Structure

apps/admin-panel/
├── src/
│ ├── main.tsx # Application entry
│ ├── runtime-config.ts # Runtime config loader
│ ├── routes/ # TanStack Router file-based routes
│ ├── auth/ # Keycloak integration
│ ├── shell/ # App shell / layout
│ └── generated/ # Generated GraphQL types
├── components/ # React components
├── hooks/ # Custom hooks
└── lib/ # Utilities and Apollo config

Authentication

Keycloak Configuration

import Keycloak from 'keycloak-js';
import { getRuntimeConfig } from '@/src/runtime-config';

const config = getRuntimeConfig();

export const keycloak = new Keycloak({
url: config.keycloakUrl,
realm: config.keycloakRealm,
clientId: config.keycloakClientId,
});

Route Protection

export function ProtectedRoute({ children, requiredRole }) {
const { isAuthenticated, hasRole } = useAuth();

if (!isAuthenticated) {
return <LoginRedirect />;
}

if (requiredRole && !hasRole(requiredRole)) {
return <AccessDenied />;
}

return children;
}

Development

Commands

# Development
pnpm dev

# Production build
pnpm build

# Lint
pnpm lint

# Generate GraphQL types
pnpm codegen

Runtime Configuration

Configuration is injected at runtime via window.__APP_CONFIG__ (populated from an index.html template at deploy time) rather than build-time env vars. Local dev falls back to defaults from src/runtime-config.ts:

// src/runtime-config.ts (excerpt)
const devDefaults: RuntimeConfig = {
keycloakUrl: "http://localhost:8081",
keycloakRealm: "internal",
keycloakClientId: "admin-panel",
keycloakDefaultLoginHint: "admin@galoy.io",
coreAdminGqlUrl: "/graphql",
coreAdminSseUrl: "/graphql/stream",
};