f65b2ca8d8
- AdminBillingView: 4 stats (MRR, Выручка, Просрочка, Возвраты) + v-data-table 7 колонок (Тенант с ИНН / Тариф / Баланс с error-color / пополнения / списания / MRR / Статус-chip) + поиск
- AdminIncidentsView: 3 stats + 5 фильтров статуса + v-list с incident_id (INC-YYYY-MMDD-NNNN) + severity/status/РКН-pending chips + дедлайн 24ч по 152-ФЗ
- AdminSystemView: read-only warning + поиск + v-list 7 system_settings (webhook_rate_limit, login_max_attempts, retention и т.д.) с type-chip и updated_at
- composables/mockAdmin.ts: AdminBillingTenantRow + AdminIncidentRow + AdminSystemSetting + mock-данные
- Router: /admin/{billing,incidents,system} → реальные views (не placeholder)
- Vitest +13 (179/179 за 11.98с)
- TODO: edit-flow для system_settings + backend /api/admin/* endpoints
- Регресс: lint+type+format OK; build 743ms; story:build 21/28 за 31.5с
- CLAUDE.md v1.42→v1.43, реестр v1.51→v1.52
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
217 lines
6.2 KiB
TypeScript
217 lines
6.2 KiB
TypeScript
/**
|
||
* Mock-данные для admin-views (Биллинг / Инциденты / Система).
|
||
*
|
||
* На MVP — frontend-only с предсказуемым набором данных. Backend подключение
|
||
* через отдельные endpoints `/api/admin/*` — отдельный коммит.
|
||
*/
|
||
|
||
// === BILLING ===
|
||
|
||
export interface AdminBillingTenantRow {
|
||
id: number;
|
||
name: string;
|
||
inn: string;
|
||
tariff: 'start' | 'basic' | 'pro' | 'enterprise';
|
||
balance_rub: number;
|
||
monthly_topups_rub: number;
|
||
monthly_charges_rub: number;
|
||
mrr_rub: number;
|
||
last_payment_at: string | null;
|
||
status: 'active' | 'overdue' | 'suspended';
|
||
}
|
||
|
||
export interface AdminBillingSummary {
|
||
total_mrr_rub: number;
|
||
monthly_revenue_rub: number;
|
||
overdue_count: number;
|
||
refunds_count_30d: number;
|
||
avg_balance_rub: number;
|
||
}
|
||
|
||
export const ADMIN_BILLING_SUMMARY: AdminBillingSummary = {
|
||
total_mrr_rub: 1_248_600,
|
||
monthly_revenue_rub: 1_318_400,
|
||
overdue_count: 5,
|
||
refunds_count_30d: 3,
|
||
avg_balance_rub: 12_840,
|
||
};
|
||
|
||
export const ADMIN_BILLING_TENANTS: AdminBillingTenantRow[] = [
|
||
{
|
||
id: 1,
|
||
name: 'ООО «Окна Москва»',
|
||
inn: '7707083893',
|
||
tariff: 'pro',
|
||
balance_rub: 14_250,
|
||
monthly_topups_rub: 30_000,
|
||
monthly_charges_rub: 25_400,
|
||
mrr_rub: 4_990,
|
||
last_payment_at: '2026-05-04T10:23:00Z',
|
||
status: 'active',
|
||
},
|
||
{
|
||
id: 2,
|
||
name: 'ИП Сидоров А.А.',
|
||
inn: '500102310123',
|
||
tariff: 'basic',
|
||
balance_rub: -1_200,
|
||
monthly_topups_rub: 5_000,
|
||
monthly_charges_rub: 6_200,
|
||
mrr_rub: 990,
|
||
last_payment_at: '2026-04-28T14:10:00Z',
|
||
status: 'overdue',
|
||
},
|
||
{
|
||
id: 3,
|
||
name: 'ООО «Натяжные потолки СПб»',
|
||
inn: '7806012345',
|
||
tariff: 'pro',
|
||
balance_rub: 8_900,
|
||
monthly_topups_rub: 20_000,
|
||
monthly_charges_rub: 18_400,
|
||
mrr_rub: 4_990,
|
||
last_payment_at: '2026-05-02T09:00:00Z',
|
||
status: 'active',
|
||
},
|
||
{
|
||
id: 4,
|
||
name: 'ООО «BigCorp Холдинг»',
|
||
inn: '7710140020',
|
||
tariff: 'enterprise',
|
||
balance_rub: 89_000,
|
||
monthly_topups_rub: 100_000,
|
||
monthly_charges_rub: 76_400,
|
||
mrr_rub: 14_990,
|
||
last_payment_at: '2026-05-01T08:00:00Z',
|
||
status: 'active',
|
||
},
|
||
{
|
||
id: 5,
|
||
name: 'ИП Петров В.В.',
|
||
inn: '770212098765',
|
||
tariff: 'start',
|
||
balance_rub: 0,
|
||
monthly_topups_rub: 0,
|
||
monthly_charges_rub: 0,
|
||
mrr_rub: 0,
|
||
last_payment_at: null,
|
||
status: 'suspended',
|
||
},
|
||
];
|
||
|
||
// === INCIDENTS ===
|
||
|
||
export interface AdminIncidentRow {
|
||
id: number;
|
||
incident_id: string;
|
||
title: string;
|
||
severity: 'critical' | 'high' | 'medium' | 'low';
|
||
category: 'pdn_breach' | 'service_outage' | 'security' | 'billing' | 'data_loss';
|
||
status: 'open' | 'investigating' | 'resolved' | 'closed';
|
||
detected_at: string;
|
||
affected_tenants: number;
|
||
rkn_notified: boolean;
|
||
rkn_deadline_at: string | null;
|
||
}
|
||
|
||
export const ADMIN_INCIDENTS: AdminIncidentRow[] = [
|
||
{
|
||
id: 1,
|
||
incident_id: 'INC-2026-0507-0034',
|
||
title: 'API timeout: рост 502 ошибок на webhook-приёме',
|
||
severity: 'high',
|
||
category: 'service_outage',
|
||
status: 'investigating',
|
||
detected_at: '2026-05-09T12:34:00Z',
|
||
affected_tenants: 12,
|
||
rkn_notified: false,
|
||
rkn_deadline_at: null,
|
||
},
|
||
{
|
||
id: 2,
|
||
incident_id: 'INC-2026-0506-0028',
|
||
title: 'Утечка ПДн через логи (REQ-3F8A2)',
|
||
severity: 'critical',
|
||
category: 'pdn_breach',
|
||
status: 'open',
|
||
detected_at: '2026-05-08T18:00:00Z',
|
||
affected_tenants: 1,
|
||
rkn_notified: false,
|
||
rkn_deadline_at: '2026-05-09T18:00:00Z',
|
||
},
|
||
{
|
||
id: 3,
|
||
incident_id: 'INC-2026-0501-0019',
|
||
title: 'YooKassa: задержка вебхуков об оплате',
|
||
severity: 'medium',
|
||
category: 'billing',
|
||
status: 'resolved',
|
||
detected_at: '2026-05-01T10:15:00Z',
|
||
affected_tenants: 5,
|
||
rkn_notified: false,
|
||
rkn_deadline_at: null,
|
||
},
|
||
];
|
||
|
||
// === SYSTEM SETTINGS ===
|
||
|
||
export interface AdminSystemSetting {
|
||
key: string;
|
||
value: string;
|
||
type: 'int' | 'string' | 'bool' | 'json';
|
||
description: string;
|
||
updated_at: string;
|
||
}
|
||
|
||
export const ADMIN_SYSTEM_SETTINGS: AdminSystemSetting[] = [
|
||
{
|
||
key: 'webhook_rate_limit_rps',
|
||
value: '100',
|
||
type: 'int',
|
||
description: 'Лимит запросов в секунду на токен Webhook (ТЗ §10).',
|
||
updated_at: '2026-05-01T00:00:00Z',
|
||
},
|
||
{
|
||
key: 'api_rate_limit_per_minute',
|
||
value: '60',
|
||
type: 'int',
|
||
description: 'Лимит запросов API на ключ в минуту.',
|
||
updated_at: '2026-05-01T00:00:00Z',
|
||
},
|
||
{
|
||
key: 'login_max_attempts',
|
||
value: '5',
|
||
type: 'int',
|
||
description: 'Макс. неудачных попыток входа в окне 15 минут (ТЗ §22.4.4).',
|
||
updated_at: '2026-05-09T00:00:00Z',
|
||
},
|
||
{
|
||
key: 'password_min_length',
|
||
value: '10',
|
||
type: 'int',
|
||
description: 'Минимальная длина пароля (ТЗ §22.4.1).',
|
||
updated_at: '2026-05-01T00:00:00Z',
|
||
},
|
||
{
|
||
key: 'webhook_log_retention_days',
|
||
value: '90',
|
||
type: 'int',
|
||
description: 'Сколько дней хранить raw_payload Webhook.',
|
||
updated_at: '2026-05-01T00:00:00Z',
|
||
},
|
||
{
|
||
key: 'maintenance_mode',
|
||
value: 'false',
|
||
type: 'bool',
|
||
description: 'Глобальный maintenance — webhook-приём и UI отключаются.',
|
||
updated_at: '2026-05-01T00:00:00Z',
|
||
},
|
||
{
|
||
key: 'fallback_supplier_id',
|
||
value: '1',
|
||
type: 'int',
|
||
description: 'Резервный supplier_id для проектов без активного supplier (ProcessWebhookJob).',
|
||
updated_at: '2026-05-08T00:00:00Z',
|
||
},
|
||
];
|