Разработка админ-панели криптобиржи
Административная панель биржи — это оперативный центр управления. Операторы мониторят торговлю, команда поддержки обрабатывает тикеты, compliance офицер проверяет подозрительные транзакции, финансовая команда управляет резервами. Один инструмент для всего — значит, нужна правильная система ролей и чёткое разделение доступа.
Архитектура ролей и разрешений
RBAC (Role-Based Access Control)
type Permission string
const (
// Пользователи
ViewUsers Permission = "users:view"
EditUsers Permission = "users:edit"
FreezeUsers Permission = "users:freeze"
// KYC/AML
ViewKYC Permission = "kyc:view"
ApproveKYC Permission = "kyc:approve"
ViewAML Permission = "aml:view"
ManageAML Permission = "aml:manage"
// Торговля
ViewOrders Permission = "orders:view"
CancelOrders Permission = "orders:cancel"
// Финансы
ViewBalances Permission = "finance:view"
ViewWithdrawals Permission = "finance:withdrawals:view"
ApproveWithdrawals Permission = "finance:withdrawals:approve"
// Система
ViewSystemMetrics Permission = "system:metrics"
ManageConfig Permission = "system:config"
ManageTradingPairs Permission = "markets:manage"
)
type Role struct {
Name string
Permissions []Permission
}
var Roles = map[string]Role{
"super_admin": {
Name: "Super Admin",
Permissions: AllPermissions,
},
"compliance": {
Name: "Compliance Officer",
Permissions: []Permission{
ViewUsers, ViewKYC, ApproveKYC, ViewAML, ManageAML,
ViewOrders, ViewBalances, ViewWithdrawals,
},
},
"support": {
Name: "Support Agent",
Permissions: []Permission{
ViewUsers, ViewOrders, ViewKYC,
},
},
"finance": {
Name: "Finance",
Permissions: []Permission{
ViewBalances, ViewWithdrawals, ApproveWithdrawals,
},
},
"marketing": {
Name: "Marketing",
Permissions: []Permission{
ViewUsers, // read-only analytics
},
},
}
Ключевые модули админ-панели
Dashboard — главный экран
// Ключевые метрики на главной странице
interface DashboardMetrics {
// Торговля
volume24h: string;
trades24h: number;
activeUsers24h: number;
// Финансы
totalDeposits24h: string;
totalWithdrawals24h: string;
pendingWithdrawals: number;
pendingWithdrawalsUSD: string;
// KYC
pendingKYCApprovals: number;
// Система
matchingEngineLatency: number; // мс
wsConnections: number;
apiRps: number;
// Алерты
activeAlerts: SystemAlert[];
}
function AdminDashboard() {
const { data } = useQuery('dashboard-metrics', fetchMetrics, {
refetchInterval: 30000, // обновляем каждые 30 сек
});
return (
<Grid>
<MetricCard title="24h Volume" value={data?.volume24h} trend={data?.volumeTrend} />
<MetricCard title="Pending Withdrawals" value={data?.pendingWithdrawalsUSD}
alert={data?.pendingWithdrawals > 50} />
<MetricCard title="KYC Queue" value={data?.pendingKYCApprovals} />
<ActiveAlerts alerts={data?.activeAlerts} />
<RecentTradesTable />
<SystemHealthIndicators />
</Grid>
);
}
Управление пользователями
function UserManagement() {
const [filters, setFilters] = useState({
search: '',
kycStatus: 'all',
frozen: false,
country: '',
});
return (
<div>
<UserFilters filters={filters} onChange={setFilters} />
<DataTable
columns={[
{ key: 'id', label: 'ID' },
{ key: 'email', label: 'Email' },
{ key: 'fullName', label: 'Name' },
{ key: 'kycTier', label: 'KYC Tier', render: (v) => <KYCBadge tier={v} /> },
{ key: 'registeredAt', label: 'Registered', render: (v) => formatDate(v) },
{ key: 'volume30d', label: '30d Volume' },
{ key: 'status', render: (_, row) => <UserStatusActions user={row} /> },
]}
fetchData={(params) => fetchUsers({ ...params, ...filters })}
onRowClick={(user) => openUserDetail(user.id)}
/>
</div>
);
}
function UserDetail({ userId }: { userId: number }) {
const { data: user } = useQuery(['user', userId], () => fetchUser(userId));
return (
<Tabs>
<Tab label="Overview">
<UserInfo user={user} />
<BalanceSummary userId={userId} />
</Tab>
<Tab label="KYC Documents">
<KYCDocumentViewer userId={userId} />
<KYCApprovalActions userId={userId} />
</Tab>
<Tab label="Orders">
<OrderHistory userId={userId} />
</Tab>
<Tab label="Transactions">
<TransactionHistory userId={userId} />
</Tab>
<Tab label="Activity Log">
<UserActivityLog userId={userId} />
</Tab>
<Tab label="Actions">
<FreezeAccount userId={userId} />
<AdjustBalance userId={userId} />
<AddKYCNote userId={userId} />
</Tab>
</Tabs>
);
}
Управление выводами
Крупные выводы требуют ручной апрув. Интерфейс для compliance/finance команды:
function WithdrawalQueue() {
const { data: withdrawals } = useQuery('pending-withdrawals', fetchPendingWithdrawals);
return (
<div>
<StatsBar
total={withdrawals?.total}
totalUSD={withdrawals?.totalUSD}
flagged={withdrawals?.flaggedCount}
/>
{withdrawals?.items.map(w => (
<WithdrawalCard key={w.id} withdrawal={w}>
<UserRiskIndicator userId={w.userId} />
<AMLCheckResult withdrawalId={w.id} />
<BlockchainAddressInfo address={w.address} />
<ActionButtons>
<ApproveButton withdrawalId={w.id} requiresReason={w.amount > 10000} />
<RejectButton withdrawalId={w.id} />
<FlagForReviewButton withdrawalId={w.id} />
</ActionButtons>
</WithdrawalCard>
))}
</div>
);
}
Управление торговыми парами
interface TradingPairConfig {
pair: string;
baseAsset: string;
quoteAsset: string;
status: 'active' | 'suspended' | 'delisted';
// Ценовые ограничения
minPrice: string;
maxPrice: string;
tickSize: string; // шаг цены
// Объёмные ограничения
minQty: string;
maxQty: string;
stepSize: string; // шаг количества
// Комиссии (override глобальных)
makerFee?: string;
takerFee?: string;
// Listing
listedAt: string;
}
function TradingPairsManager() {
return (
<div>
<Button onClick={() => openAddPairModal()}>Add Trading Pair</Button>
<PairsTable
onStatusChange={(pair, status) => updatePairStatus(pair, status)}
onConfigEdit={(pair) => openConfigModal(pair)}
/>
</div>
);
}
Системный мониторинг
function SystemMonitoring() {
const metrics = useRealtimeMetrics(); // WebSocket
return (
<Grid>
<GaugeChart
title="Matching Engine Latency"
value={metrics.matchingLatencyP99}
unit="ms"
thresholds={[{ value: 10, color: 'green' }, { value: 100, color: 'yellow' }, { value: 500, color: 'red' }]}
/>
<TimeseriesChart
title="API Requests/sec"
data={metrics.apiRpsHistory}
/>
<GaugeChart
title="WebSocket Connections"
value={metrics.wsConnections}
max={100000}
/>
<ServiceHealthGrid services={metrics.services} />
</Grid>
);
}
Безопасность админ-панели
2FA обязателен для всех операторов
// Middleware: требуем 2FA для чувствительных операций
function RequireRecentMFA({ children }: { children: React.ReactNode }) {
const { lastMFAAt } = useAdminSession();
const isRecent = lastMFAAt && Date.now() - lastMFAAt < 30 * 60 * 1000; // 30 минут
if (!isRecent) {
return <MFAChallengeModal onSuccess={refreshSession} />;
}
return <>{children}</>;
}
Admin Audit Log
Каждое действие оператора логируется — who, what, when, on what:
type AdminAuditEntry struct {
AdminID int64
AdminEmail string
Action string // "approve_withdrawal", "freeze_user", "update_config"
EntityType string // "withdrawal", "user", "trading_pair"
EntityID string
Before string // JSON состояние до изменения
After string // JSON состояние после
IPAddress string
CreatedAt time.Time
}
// Middleware для автоматического логирования
func AuditMiddleware(db *DB) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Записываем до
recorder := &ResponseRecorder{ResponseWriter: w}
next.ServeHTTP(recorder, r)
// Логируем только успешные изменения (2xx)
if recorder.StatusCode >= 200 && recorder.StatusCode < 300 {
if isWriteOperation(r.Method) {
go db.WriteAuditLog(buildAuditEntry(r, recorder))
}
}
})
}
}
IP restriction
Админ-панель доступна только с корпоративного VPN или фиксированных IP:
location /area51/ {
allow 10.0.0.0/8; # корпоративная сеть
allow 1.2.3.4; # IP офиса
deny all;
proxy_pass http://admin-backend;
}
Технический стек
| Компонент | Технология |
|---|---|
| Frontend | React + TypeScript + TanStack Query |
| UI Kit | Shadcn/ui + Tailwind |
| Charts | Recharts / TradingView Lightweight |
| Realtime | WebSocket + Zustand |
| Backend | Go REST API |
| Auth | JWT + TOTP 2FA |
| RBAC | Custom middleware |
| Audit | PostgreSQL + immutable log |
Сроки разработки
| Модуль | Срок |
|---|---|
| Аутентификация + RBAC | 2–3 недели |
| Dashboard с метриками | 2–3 недели |
| User management | 3–4 недели |
| KYC approval workflow | 2–3 недели |
| Withdrawal queue | 2–3 недели |
| Market management | 2–3 недели |
| System monitoring | 2–3 недели |
| Audit log | 1–2 недели |
Полная административная панель: 3–4 месяца.







