# Фронтенд-контракты и Модели данных Krona Control Center
## 1. Концепция Minor Currency Units (Минорные единицы валюты)
Для исключения ошибок округления чисел с плавающей точкой (`0.1 + 0.2 !== 0.3`) все финансовые поля в Control Center хранятся исключительно в минорных единицах (копейки):
- **Хранение**: целочисленные значения `number` (`priceMonthlyMinor`, `mrrMinor`, `amountMinor`).
- **Пример**: `149 000 руб.` представляется как `14900000` (копеек).
- **Форматирование**: компонент `` производит безопасное форматирование с помощью `Intl.NumberFormat('ru-RU', { style: 'currency', currency: 'RUB' })`, деля число на 100 исключительно на этапе рендеринга строки.
---
## 2. Неизменяемый криптографический аудит (SHA-256 Hash Chaining)
Каждое операторское действие формирует блок в локальной цепочке аудита. Порядок связывания:
```typescript
export interface OperatorAuditEvent {
id: string;
timestamp: string;
operatorRole: OperatorRole;
operatorName: string;
actionType: OperatorActionType;
entityType: 'organization' | 'installation' | 'node' | 'module' | 'announcement' | 'incident' | 'system';
entityId: string;
reason: string;
impactSummary: string;
diffBeforeAfter?: {
before: Record;
after: Record;
};
clientIp?: string;
previousHash: string; // Ссылка на хеш предыдущей записи
eventHash: string; // SHA-256(previousHash + timestamp + operatorRole + actionType + entityId + reason)
}
```
### Алгоритм вычисления хеша:
```typescript
export async function computeEventHash(
previousHash: string,
timestamp: string,
operatorRole: string,
actionType: string,
entityId: string,
reason: string
): Promise {
const payload = `${previousHash}|${timestamp}|${operatorRole}|${actionType}|${entityId}|${reason}`;
const msgUint8 = new TextEncoder().encode(payload);
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
}
```
---
## 3. Схема постоянного хранилища IndexedDB
База данных `krona_control_center_db` (версия 1) содержит следующие хранилища объектов (Object Stores):
1. `organizations`: карточки тенантов платформы (`PlatformOrganization`).
2. `module_instances`: установленные модули и версии (`ModuleInstance`).
3. `installations`: физические устройства, кассы, терминалы (`InstallationDevice`).
4. `nodes`: серверные узлы кластера (`ClusterNode`).
5. `announcements`: сервисные сообщения и баннеры (`SystemAnnouncement`).
6. `incidents`: инциденты платформы (`PlatformIncident`).
7. `audit_log`: цепочка блоков аудита с индексом по `timestamp`.
8. `settings`: глобальные флаги (maintenance mode, circuit breaker test flags).
---
## 4. Контракт устойчивости Server Monitor Outage (Circuit Breaker)
При отказе внешнего сервиса мониторинга кластера:
1. `useKccStore.serverMonitorOutage = true`.
2. Интерфейс переходит в режим graceful degradation:
- Отображается аварийный баннер `ServerMonitorOutageBanner` с индикатором «Используются локальные кэшированные метрики».
- Метрики узлов замораживаются на последнем известном валидном снимке из IndexedDB.
- Запрещается автоматическая эвакуация нод без явного ручного подтверждения `force_offline_drain`.