feat(api): absorb the Hub control plane into the local instance model
Add central notification channels, rules, queue and delivery logs, fleet organization groups and tags, device discovery, the device action catalog, instance module reads, the log centre, connection settings and system maintenance as native /api/v1 routes backed by the existing secret store, audit trail and pinned upstream transport.
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Read-only catalog of SimAdmin device endpoints, grouped by the console module that renders
|
||||
* them. Every entry is a GET-safe probe: the control plane never mutates a device through this
|
||||
* catalog, so a module read is always safe to retry and safe to run on a schedule.
|
||||
*/
|
||||
export type InstanceModuleKey =
|
||||
| 'overview'
|
||||
| 'sim'
|
||||
| 'cellular'
|
||||
| 'device-network'
|
||||
| 'esim'
|
||||
| 'calls'
|
||||
| 'configuration'
|
||||
| 'device-backup'
|
||||
| 'notifications'
|
||||
| 'automation'
|
||||
| 'ota'
|
||||
| 'vowifi';
|
||||
|
||||
export interface ModuleProbe {
|
||||
/** Stable identifier the console renders; never a device-controlled value. */
|
||||
readonly key: string;
|
||||
/** Path appended to the instance origin, always rooted at the device /api namespace. */
|
||||
readonly path: string;
|
||||
readonly timeoutMs?: number;
|
||||
}
|
||||
|
||||
export const INSTANCE_MODULE_KEYS: readonly InstanceModuleKey[] = [
|
||||
'overview',
|
||||
'sim',
|
||||
'cellular',
|
||||
'device-network',
|
||||
'esim',
|
||||
'calls',
|
||||
'configuration',
|
||||
'device-backup',
|
||||
'notifications',
|
||||
'automation',
|
||||
'ota',
|
||||
'vowifi',
|
||||
];
|
||||
|
||||
export const INSTANCE_MODULE_PROBES: Readonly<Record<InstanceModuleKey, readonly ModuleProbe[]>> = {
|
||||
overview: [
|
||||
{ key: 'device', path: '/device' },
|
||||
{ key: 'sim', path: '/sim' },
|
||||
{ key: 'network', path: '/network' },
|
||||
{ key: 'stats', path: '/stats' },
|
||||
{ key: 'connectivity', path: '/connectivity' },
|
||||
{ key: 'data', path: '/data' },
|
||||
{ key: 'cpu', path: '/stats/cpu' },
|
||||
{ key: 'smsStats', path: '/sms/stats' },
|
||||
],
|
||||
sim: [
|
||||
{ key: 'sim', path: '/sim' },
|
||||
{ key: 'apn', path: '/apn' },
|
||||
{ key: 'bandLock', path: '/band-lock' },
|
||||
{ key: 'cellLock', path: '/cell-lock' },
|
||||
],
|
||||
cellular: [
|
||||
{ key: 'network', path: '/network' },
|
||||
{ key: 'signalStrength', path: '/network/signal-strength' },
|
||||
{ key: 'cells', path: '/cells' },
|
||||
{ key: 'cellLocation', path: '/location/cell-info' },
|
||||
{ key: 'operators', path: '/network/operators' },
|
||||
{ key: 'roaming', path: '/roaming' },
|
||||
{ key: 'radioMode', path: '/radio-mode' },
|
||||
{ key: 'airplaneMode', path: '/airplane-mode' },
|
||||
{ key: 'basebandRestart', path: '/baseband/restart/status' },
|
||||
{ key: 'cellMonitor', path: '/cell-monitor/status' },
|
||||
],
|
||||
'device-network': [
|
||||
{ key: 'interfaces', path: '/network/interfaces' },
|
||||
{ key: 'addresses', path: '/network/connection-addresses' },
|
||||
{ key: 'wlanStatus', path: '/device-network/wlan/status' },
|
||||
{ key: 'wlanProfiles', path: '/device-network/wlan/profiles' },
|
||||
{ key: 'ddnsStatus', path: '/device-network/ddns/status' },
|
||||
{ key: 'ddnsConfig', path: '/device-network/ddns/config' },
|
||||
{ key: 'ddnsLogs', path: '/device-network/ddns/logs' },
|
||||
],
|
||||
esim: [
|
||||
{ key: 'euicc', path: '/esim/euicc', timeoutMs: 30_000 },
|
||||
{ key: 'profiles', path: '/esim/profiles?cached=1' },
|
||||
{ key: 'config', path: '/esim/config' },
|
||||
{ key: 'lpacStatus', path: '/esim/lpac/status' },
|
||||
],
|
||||
calls: [
|
||||
{ key: 'calls', path: '/calls' },
|
||||
{ key: 'history', path: '/call/history?limit=50' },
|
||||
{ key: 'settings', path: '/call/settings' },
|
||||
{ key: 'forwarding', path: '/call/forwarding' },
|
||||
{ key: 'volume', path: '/call/volume' },
|
||||
{ key: 'voicemail', path: '/voicemail/status' },
|
||||
{ key: 'ims', path: '/ims/status' },
|
||||
],
|
||||
configuration: [
|
||||
{ key: 'workMode', path: '/work-mode' },
|
||||
{ key: 'authSettings', path: '/auth/settings' },
|
||||
{ key: 'authStatus', path: '/auth/status' },
|
||||
{ key: 'hub', path: '/hub' },
|
||||
],
|
||||
'device-backup': [
|
||||
{ key: 'files', path: '/backup/files' },
|
||||
{ key: 'config', path: '/backup/config' },
|
||||
{ key: 'options', path: '/backup/options' },
|
||||
],
|
||||
notifications: [
|
||||
{ key: 'config', path: '/notifications/config' },
|
||||
{ key: 'queue', path: '/notifications/queue?limit=50' },
|
||||
{ key: 'logs', path: '/notifications/logs?limit=50' },
|
||||
],
|
||||
automation: [
|
||||
{ key: 'config', path: '/automation/config' },
|
||||
{ key: 'logs', path: '/automation/logs' },
|
||||
],
|
||||
ota: [{ key: 'status', path: '/ota/status' }],
|
||||
vowifi: [
|
||||
{ key: 'status', path: '/vowifi/status' },
|
||||
{ key: 'control', path: '/vowifi/control' },
|
||||
{ key: 'profile', path: '/vowifi/profile' },
|
||||
{ key: 'profiles', path: '/vowifi/profiles' },
|
||||
// The aggregate diagnostics feed carries the registration timeline the Hub shows.
|
||||
{ key: 'diagnostics', path: '/vowifi/diagnostics?limit=50', timeoutMs: 30_000 },
|
||||
{ key: 'events', path: '/vowifi/events?limit=50', timeoutMs: 10_000 },
|
||||
{ key: 'smsDeliveries', path: '/vowifi/sms/delivery?limit=20', timeoutMs: 10_000 },
|
||||
{ key: 'soakRuns', path: '/vowifi/soak?limit=20', timeoutMs: 10_000 },
|
||||
{ key: 'restore', path: '/vowifi/esim-restore/status', timeoutMs: 10_000 },
|
||||
],
|
||||
};
|
||||
|
||||
export function isInstanceModuleKey(value: unknown): value is InstanceModuleKey {
|
||||
return typeof value === 'string' && (INSTANCE_MODULE_KEYS as readonly string[]).includes(value);
|
||||
}
|
||||
Reference in New Issue
Block a user