feat(operations): add audited runtime catalog

This commit is contained in:
chick
2026-07-17 09:07:50 +08:00
parent 243565a75e
commit 8018b36adf
15 changed files with 1617 additions and 21 deletions
+1
View File
@@ -10,6 +10,7 @@
},
"dependencies": {
"@multi-simadmin/contracts": "workspace:*",
"@multi-simadmin/operation-registry": "workspace:*",
"better-sqlite3": "12.11.1",
"drizzle-orm": "0.45.2",
"fastify": "5.10.0"
@@ -0,0 +1,938 @@
[
{
"operationId": "deleteCallHistoryId",
"title": "Delete Call History ID",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.deleteCallHistoryId.parameters.v1"
},
{
"operationId": "deleteEsimProfilesIccid",
"title": "Delete eSIM Profile ICCID",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.deleteEsimProfilesIccid.parameters.v1"
},
{
"operationId": "deleteNotificationsQueueId",
"title": "Delete Notifications Queue ID",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.deleteNotificationsQueueId.parameters.v1"
},
{
"operationId": "deleteSmsConversationPhoneNumber",
"title": "Delete SMS Conversation Phone Number",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.deleteSmsConversationPhoneNumber.parameters.v1"
},
{
"operationId": "deleteSmsMessageId",
"title": "Delete SMS Message ID",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.deleteSmsMessageId.parameters.v1"
},
{
"operationId": "getAirplaneMode",
"title": "Get Airplane Mode",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getAirplaneMode.parameters.v1"
},
{
"operationId": "getApn",
"title": "Get APN",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getApn.parameters.v1"
},
{
"operationId": "getAuthSettings",
"title": "Get Auth Settings",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getAuthSettings.parameters.v1"
},
{
"operationId": "getAuthStatus",
"title": "Get Auth Status",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getAuthStatus.parameters.v1"
},
{
"operationId": "getAutomationConfig",
"title": "Get Automation Config",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getAutomationConfig.parameters.v1"
},
{
"operationId": "getAutomationLogs",
"title": "Get Automation Logs",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getAutomationLogs.parameters.v1"
},
{
"operationId": "getBandLock",
"title": "Get Band Lock",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getBandLock.parameters.v1"
},
{
"operationId": "getBasebandRestartStatus",
"title": "Get Baseband Restart Status",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getBasebandRestartStatus.parameters.v1"
},
{
"operationId": "getCallForwarding",
"title": "Get Call Forwarding",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getCallForwarding.parameters.v1"
},
{
"operationId": "getCallHistory",
"title": "Get Call History",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getCallHistory.parameters.v1"
},
{
"operationId": "getCallSettings",
"title": "Get Call Settings",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getCallSettings.parameters.v1"
},
{
"operationId": "getCallVolume",
"title": "Get Call Volume",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getCallVolume.parameters.v1"
},
{
"operationId": "getCalls",
"title": "Get Calls",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getCalls.parameters.v1"
},
{
"operationId": "getCellLock",
"title": "Get Cell Lock",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getCellLock.parameters.v1"
},
{
"operationId": "getCells",
"title": "Get Cells",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getCells.parameters.v1"
},
{
"operationId": "getConnectivity",
"title": "Get Connectivity",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getConnectivity.parameters.v1"
},
{
"operationId": "getData",
"title": "Get Data",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getData.parameters.v1"
},
{
"operationId": "getDevice",
"title": "Get Device",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getDevice.parameters.v1"
},
{
"operationId": "getDeviceNetworkDdnsConfig",
"title": "Get Device Network DDNS Config",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getDeviceNetworkDdnsConfig.parameters.v1"
},
{
"operationId": "getDeviceNetworkDdnsLogs",
"title": "Get Device Network DDNS Logs",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getDeviceNetworkDdnsLogs.parameters.v1"
},
{
"operationId": "getDeviceNetworkDdnsStatus",
"title": "Get Device Network DDNS Status",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getDeviceNetworkDdnsStatus.parameters.v1"
},
{
"operationId": "getDeviceNetworkWlanProfiles",
"title": "Get Device Network WLAN Profiles",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getDeviceNetworkWlanProfiles.parameters.v1"
},
{
"operationId": "getDeviceNetworkWlanStatus",
"title": "Get Device Network WLAN Status",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getDeviceNetworkWlanStatus.parameters.v1"
},
{
"operationId": "getEsimConfig",
"title": "Get eSIM Config",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getEsimConfig.parameters.v1"
},
{
"operationId": "getEsimEuicc",
"title": "Get eSIM eUICC",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getEsimEuicc.parameters.v1"
},
{
"operationId": "getEsimLpacStatus",
"title": "Get eSIM LPAC Status",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getEsimLpacStatus.parameters.v1"
},
{
"operationId": "getEsimProfiles",
"title": "Get eSIM Profiles",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getEsimProfiles.parameters.v1"
},
{
"operationId": "getHealth",
"title": "Get Health",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getHealth.parameters.v1"
},
{
"operationId": "getImsStatus",
"title": "Get IMS Status",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getImsStatus.parameters.v1"
},
{
"operationId": "getLocationCellInfo",
"title": "Get Location Cell Info",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getLocationCellInfo.parameters.v1"
},
{
"operationId": "getNetwork",
"title": "Get Network",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getNetwork.parameters.v1"
},
{
"operationId": "getNetworkConnectionAddresses",
"title": "Get Network Connection Addresses",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getNetworkConnectionAddresses.parameters.v1"
},
{
"operationId": "getNetworkInterfaces",
"title": "Get Network Interfaces",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getNetworkInterfaces.parameters.v1"
},
{
"operationId": "getNetworkOperators",
"title": "Get Network Operators",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getNetworkOperators.parameters.v1"
},
{
"operationId": "getNetworkOperatorsScan",
"title": "Scan Network Operators",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getNetworkOperatorsScan.parameters.v1"
},
{
"operationId": "getNetworkSignalStrength",
"title": "Get Network Signal Strength",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getNetworkSignalStrength.parameters.v1"
},
{
"operationId": "getNotificationsConfig",
"title": "Get Notifications Config",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getNotificationsConfig.parameters.v1"
},
{
"operationId": "getNotificationsLogs",
"title": "Get Notifications Logs",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getNotificationsLogs.parameters.v1"
},
{
"operationId": "getNotificationsQueue",
"title": "Get Notifications Queue",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getNotificationsQueue.parameters.v1"
},
{
"operationId": "getOtaStatus",
"title": "Get OTA Status",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getOtaStatus.parameters.v1"
},
{
"operationId": "getRadioMode",
"title": "Get Radio Mode",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getRadioMode.parameters.v1"
},
{
"operationId": "getRoaming",
"title": "Get Roaming",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getRoaming.parameters.v1"
},
{
"operationId": "getSim",
"title": "Get SIM",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getSim.parameters.v1"
},
{
"operationId": "getSmsConversation",
"title": "Get SMS Conversation",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getSmsConversation.parameters.v1"
},
{
"operationId": "getSmsList",
"title": "Get SMS List",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getSmsList.parameters.v1"
},
{
"operationId": "getSmsStats",
"title": "Get SMS Stats",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getSmsStats.parameters.v1"
},
{
"operationId": "getStats",
"title": "Get Stats",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getStats.parameters.v1"
},
{
"operationId": "getStatsCpu",
"title": "Get Stats CPU",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getStatsCpu.parameters.v1"
},
{
"operationId": "getVoicemailStatus",
"title": "Get Voicemail Status",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getVoicemailStatus.parameters.v1"
},
{
"operationId": "getWorkMode",
"title": "Get Work Mode",
"riskLevel": "R0",
"capability": "query",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.getWorkMode.parameters.v1"
},
{
"operationId": "postAirplaneMode",
"title": "Set Airplane Mode",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postAirplaneMode.parameters.v1"
},
{
"operationId": "postApn",
"title": "Set APN",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postApn.parameters.v1"
},
{
"operationId": "postAuthLogin",
"title": "Log In",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postAuthLogin.parameters.v1"
},
{
"operationId": "postAuthLogout",
"title": "Log Out",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postAuthLogout.parameters.v1"
},
{
"operationId": "postAuthPassword",
"title": "Change Auth Password",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postAuthPassword.parameters.v1"
},
{
"operationId": "postAuthSettings",
"title": "Set Auth Settings",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postAuthSettings.parameters.v1"
},
{
"operationId": "postAuthSetup",
"title": "Set Up Auth",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postAuthSetup.parameters.v1"
},
{
"operationId": "postAutomationConfig",
"title": "Set Automation Config",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postAutomationConfig.parameters.v1"
},
{
"operationId": "postAutomationLogsClear",
"title": "Clear Automation Logs",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postAutomationLogsClear.parameters.v1"
},
{
"operationId": "postAutomationTestTaskId",
"title": "Test Automation Task ID",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postAutomationTestTaskId.parameters.v1"
},
{
"operationId": "postBandLock",
"title": "Set Band Lock",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postBandLock.parameters.v1"
},
{
"operationId": "postBasebandRestart",
"title": "Restart Baseband",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postBasebandRestart.parameters.v1"
},
{
"operationId": "postCallAnswer",
"title": "Answer Call",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postCallAnswer.parameters.v1"
},
{
"operationId": "postCallDial",
"title": "Dial Call",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postCallDial.parameters.v1"
},
{
"operationId": "postCallForwarding",
"title": "Set Call Forwarding",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postCallForwarding.parameters.v1"
},
{
"operationId": "postCallHangup",
"title": "Hang Up Call",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postCallHangup.parameters.v1"
},
{
"operationId": "postCallHangupAll",
"title": "Hang Up All Calls",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postCallHangupAll.parameters.v1"
},
{
"operationId": "postCallHistoryClear",
"title": "Clear Call History",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postCallHistoryClear.parameters.v1"
},
{
"operationId": "postCallSettings",
"title": "Set Call Settings",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postCallSettings.parameters.v1"
},
{
"operationId": "postCallVolume",
"title": "Set Call Volume",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postCallVolume.parameters.v1"
},
{
"operationId": "postCellLock",
"title": "Set Cell Lock",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postCellLock.parameters.v1"
},
{
"operationId": "postCellLockUnlockAll",
"title": "Unlock All Cell Locks",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postCellLockUnlockAll.parameters.v1"
},
{
"operationId": "postCellMonitorStart",
"title": "Start Cell Monitor",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postCellMonitorStart.parameters.v1"
},
{
"operationId": "postCellMonitorStop",
"title": "Stop Cell Monitor",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postCellMonitorStop.parameters.v1"
},
{
"operationId": "postData",
"title": "Set Data",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postData.parameters.v1"
},
{
"operationId": "postDeviceNetworkDdnsConfig",
"title": "Set Device Network DDNS Config",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postDeviceNetworkDdnsConfig.parameters.v1"
},
{
"operationId": "postDeviceNetworkDdnsLogsClear",
"title": "Clear Device Network DDNS Logs",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postDeviceNetworkDdnsLogsClear.parameters.v1"
},
{
"operationId": "postDeviceNetworkDdnsSync",
"title": "Sync Device Network DDNS",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postDeviceNetworkDdnsSync.parameters.v1"
},
{
"operationId": "postDeviceNetworkWlanConnect",
"title": "Connect Device Network WLAN",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postDeviceNetworkWlanConnect.parameters.v1"
},
{
"operationId": "postDeviceNetworkWlanDisconnect",
"title": "Disconnect Device Network WLAN",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postDeviceNetworkWlanDisconnect.parameters.v1"
},
{
"operationId": "postDeviceNetworkWlanEnabled",
"title": "Set Device Network WLAN Enabled",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postDeviceNetworkWlanEnabled.parameters.v1"
},
{
"operationId": "postDeviceNetworkWlanForget",
"title": "Forget Device Network WLAN",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postDeviceNetworkWlanForget.parameters.v1"
},
{
"operationId": "postDeviceNetworkWlanProfile",
"title": "Set Device Network WLAN Profile",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postDeviceNetworkWlanProfile.parameters.v1"
},
{
"operationId": "postDeviceNetworkWlanScan",
"title": "Scan Device Network WLAN",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postDeviceNetworkWlanScan.parameters.v1"
},
{
"operationId": "postEsimConfig",
"title": "Set eSIM Config",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postEsimConfig.parameters.v1"
},
{
"operationId": "postEsimLpacRepair",
"title": "Repair eSIM LPAC",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postEsimLpacRepair.parameters.v1"
},
{
"operationId": "postEsimProfiles",
"title": "Add eSIM Profile",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postEsimProfiles.parameters.v1"
},
{
"operationId": "postEsimProfilesIccidEnable",
"title": "Enable eSIM Profile ICCID",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postEsimProfilesIccidEnable.parameters.v1"
},
{
"operationId": "postEsimProfilesIccidRename",
"title": "Rename eSIM Profile ICCID",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postEsimProfilesIccidRename.parameters.v1"
},
{
"operationId": "postNetworkRegisterAuto",
"title": "Register Network Automatically",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postNetworkRegisterAuto.parameters.v1"
},
{
"operationId": "postNetworkRegisterManual",
"title": "Register Network Manually",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postNetworkRegisterManual.parameters.v1"
},
{
"operationId": "postNotificationsConfig",
"title": "Set Notifications Config",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postNotificationsConfig.parameters.v1"
},
{
"operationId": "postNotificationsLogsClear",
"title": "Clear Notifications Logs",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postNotificationsLogsClear.parameters.v1"
},
{
"operationId": "postNotificationsQueueClear",
"title": "Clear Notifications Queue",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postNotificationsQueueClear.parameters.v1"
},
{
"operationId": "postNotificationsQueueIdRetry",
"title": "Retry Notifications Queue ID",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postNotificationsQueueIdRetry.parameters.v1"
},
{
"operationId": "postNotificationsQueueRetryAll",
"title": "Retry All Notifications Queue Items",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postNotificationsQueueRetryAll.parameters.v1"
},
{
"operationId": "postNotificationsTestChannel",
"title": "Test Notifications Channel",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postNotificationsTestChannel.parameters.v1"
},
{
"operationId": "postOtaApply",
"title": "Apply OTA",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postOtaApply.parameters.v1"
},
{
"operationId": "postOtaCancel",
"title": "Cancel OTA",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postOtaCancel.parameters.v1"
},
{
"operationId": "postOtaLatestRelease",
"title": "Get OTA Latest Release",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postOtaLatestRelease.parameters.v1"
},
{
"operationId": "postOtaOnlinePrepare",
"title": "Prepare OTA Online",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postOtaOnlinePrepare.parameters.v1"
},
{
"operationId": "postOtaUpload",
"title": "Upload OTA",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postOtaUpload.parameters.v1"
},
{
"operationId": "postRadioMode",
"title": "Set Radio Mode",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postRadioMode.parameters.v1"
},
{
"operationId": "postRoaming",
"title": "Set Roaming",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postRoaming.parameters.v1"
},
{
"operationId": "postServiceRestart",
"title": "Restart Service",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postServiceRestart.parameters.v1"
},
{
"operationId": "postSimCache",
"title": "Run SIM Cache",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postSimCache.parameters.v1"
},
{
"operationId": "postSimDetailsRefresh",
"title": "Run SIM Details Refresh",
"riskLevel": "R1",
"capability": "command",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postSimDetailsRefresh.parameters.v1"
},
{
"operationId": "postSmsBatchDelete",
"title": "Delete SMS Batch",
"riskLevel": "R3",
"capability": "job",
"batchable": true,
"parameterSchemaId": "simadmin.58e2204.postSmsBatchDelete.parameters.v1"
},
{
"operationId": "postSmsClear",
"title": "Clear SMS",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postSmsClear.parameters.v1"
},
{
"operationId": "postSmsSend",
"title": "Send SMS",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postSmsSend.parameters.v1"
},
{
"operationId": "postSystemReboot",
"title": "Reboot System",
"riskLevel": "R3",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postSystemReboot.parameters.v1"
},
{
"operationId": "postWorkMode",
"title": "Set Work Mode",
"riskLevel": "R2",
"capability": "job",
"batchable": false,
"parameterSchemaId": "simadmin.58e2204.postWorkMode.parameters.v1"
}
]
@@ -0,0 +1,7 @@
import catalog from './operation-catalog-58e2204.json' with { type: 'json' };
import type { OperationCatalogRegistry, OperationCatalogRow } from './operation-catalog-service.js';
/** Generated safe six-field projection of the audited 58e2204 registry. */
export const operationCatalogRegistry: OperationCatalogRegistry = Object.freeze({
listOperations: (): readonly OperationCatalogRow[] => catalog as readonly OperationCatalogRow[],
});
@@ -0,0 +1,64 @@
import { describe, expect, it } from 'vitest';
import { operationCatalogRegistry } from './operation-catalog-data.js';
import { OperationCatalogService } from './operation-catalog-service.js';
const service = new OperationCatalogService(operationCatalogRegistry);
describe('OperationCatalogService', () => {
it('returns a frozen contract-safe default page with six fields only', () => {
const page = service.list({});
expect(page.page).toEqual({ page: 1, pageSize: 25, total: 117 });
expect(page.items).toHaveLength(25);
expect(Object.keys(page.items[0]!)).toEqual([
'operationId',
'title',
'risk',
'capability',
'batchable',
'parameterSchemaId',
]);
expect(page.items.map(({ operationId }) => operationId)).toEqual(
[...page.items.map(({ operationId }) => operationId)].sort(),
);
expect(Object.isFrozen(page)).toBe(true);
expect(Object.isFrozen(page.items)).toBe(true);
expect(page.items.every(Object.isFrozen)).toBe(true);
});
it('filters all supported fields and searches case-insensitively', () => {
const filtered = service.list({
risk: 'R0',
capability: 'query',
batchable: false,
search: 'sms',
});
expect(filtered.items.length).toBeGreaterThan(0);
expect(
filtered.items.every(
(item) =>
item.risk === 'R0' &&
item.capability === 'query' &&
!item.batchable &&
/sms/i.test(`${item.operationId} ${item.title}`),
),
).toBe(true);
});
it('keeps operationId ascending as the final tie breaker when descending', () => {
for (const sort of ['operationId', 'risk', 'capability'] as const) {
const page = service.list({ pageSize: 100, sort, direction: 'desc' });
for (let index = 1; index < page.items.length; index += 1) {
const previous = page.items[index - 1]!;
const current = page.items[index]!;
if (previous[sort] === current[sort])
expect(previous.operationId < current.operationId).toBe(true);
}
}
});
it('returns an empty beyond-last page without changing total', () => {
const page = service.list({ page: 999 });
expect(page.items).toEqual([]);
expect(page.page.total).toBe(117);
});
});
@@ -0,0 +1,73 @@
import type {
OperationCatalogEntry,
OperationPage,
OperationPageQuery,
} from '@multi-simadmin/contracts';
export interface OperationCatalogRow {
readonly operationId: string;
readonly title: string;
readonly riskLevel: OperationCatalogEntry['risk'];
readonly capability: string;
readonly batchable: boolean;
readonly parameterSchemaId: string;
}
export interface OperationCatalogRegistry {
listOperations(): readonly OperationCatalogRow[];
}
const freeze = <T>(value: T): T => Object.freeze(value);
const compare = (left: string, right: string): number => (left < right ? -1 : left > right ? 1 : 0);
/** Pure safe projection over the audited runtime registry. */
export class OperationCatalogService {
constructor(private readonly registry: OperationCatalogRegistry) {}
list(query: OperationPageQuery): OperationPage {
const page = query.page ?? 1;
const pageSize = query.pageSize ?? 25;
const search = query.search?.toLowerCase();
const rows: OperationCatalogEntry[] = [];
for (const row of this.registry.listOperations()) {
if (query.risk !== undefined && row.riskLevel !== query.risk) continue;
if (query.capability !== undefined && row.capability !== query.capability) continue;
if (query.batchable !== undefined && row.batchable !== query.batchable) continue;
if (
search !== undefined &&
!row.operationId.toLowerCase().includes(search) &&
!row.title.toLowerCase().includes(search)
) {
continue;
}
rows.push(
freeze({
operationId: row.operationId,
title: row.title,
risk: row.riskLevel,
capability: row.capability,
batchable: row.batchable,
parameterSchemaId: row.parameterSchemaId,
}),
);
}
const sort = query.sort ?? 'operationId';
const direction = query.direction === 'desc' ? -1 : 1;
const value = (row: OperationCatalogEntry): string => {
if (sort === 'risk') return row.risk;
if (sort === 'capability') return row.capability;
return row.operationId;
};
rows.sort((left, right) => {
const byField = compare(value(left), value(right));
return byField === 0 ? compare(left.operationId, right.operationId) : direction * byField;
});
const offset = (page - 1) * pageSize;
return freeze({
items: freeze(rows.slice(offset, offset + pageSize)),
page: freeze({ page, pageSize, total: rows.length }),
});
}
}
@@ -0,0 +1,30 @@
import Database from 'better-sqlite3';
import { expect, it } from 'vitest';
import { buildControlPlaneApp } from './control-plane.js';
import { migrateDatabase } from './infrastructure/database/migrations.js';
it('registers the read-only operations catalog without touching upstream', async () => {
const db = new Database(':memory:');
migrateDatabase(db);
let upstreamCalls = 0;
const app = buildControlPlaneApp({
db,
store: { set: async () => '', get: async () => undefined, delete: async () => false },
upstream: {
get: async () => {
upstreamCalls += 1;
throw new Error('unexpected');
},
request: async () => {
upstreamCalls += 1;
throw new Error('unexpected');
},
},
});
const response = await app.inject('/api/v1/operations?pageSize=1');
expect(response.statusCode).toBe(200);
expect(response.json().page.total).toBe(117);
expect(upstreamCalls).toBe(0);
await app.close();
db.close();
});
+6 -2
View File
@@ -1,4 +1,6 @@
import type Database from 'better-sqlite3';
import { registerOperationRoutes } from './interface/http/operation-routes.js';
import { operationCatalogRegistry } from './application/operations/operation-catalog-data.js';
import type { FastifyInstance } from 'fastify';
import { buildApp, type BuildAppOptions } from './app.js';
import {
@@ -54,8 +56,10 @@ export function buildControlPlaneApp(options: ControlPlaneOptions): ControlPlane
deletion.reconcileInterruptedJobs();
const app = buildApp({
...options.app,
registerRoutes: (app) =>
registerInstanceRoutes(app, { instances, connections, login, deletion }),
registerRoutes: (app) => {
registerInstanceRoutes(app, { instances, connections, login, deletion });
registerOperationRoutes(app, operationCatalogRegistry);
},
});
Object.assign(app, {
retryPendingSecretCleanup: () => instances.retryPendingSecretCleanup(),
@@ -0,0 +1,69 @@
import { afterEach, describe, expect, it } from 'vitest';
import { buildApp } from '../../app.js';
import { operationCatalogRegistry } from '../../application/operations/operation-catalog-data.js';
import { registerOperationRoutes } from './operation-routes.js';
const apps: ReturnType<typeof buildApp>[] = [];
afterEach(async () => Promise.all(apps.splice(0).map((app) => app.close())));
const app = () => {
const instance = buildApp({
registerRoutes: (server) => registerOperationRoutes(server, operationCatalogRegistry),
});
apps.push(instance);
return instance;
};
describe('GET /api/v1/operations', () => {
it('returns only the safe catalog projection', async () => {
const response = await app().inject('/api/v1/operations?pageSize=1');
expect(response.statusCode).toBe(200);
expect(response.json()).toMatchObject({ page: { page: 1, pageSize: 1, total: 117 } });
expect(Object.keys(response.json().items[0])).toEqual([
'operationId',
'title',
'risk',
'capability',
'batchable',
'parameterSchemaId',
]);
for (const forbidden of [
'method',
'pathTemplate',
'sourceEvidence',
'sensitiveFields',
'handler',
])
expect(response.body).not.toContain(`\"${forbidden}\"`);
});
it.each([
'unknown=x',
'page=1&page=2',
'page[]=1',
'page=0',
'page=01',
'page=1.5',
'pageSize=101',
'risk=R4',
'capability=bogus',
'batchable=True',
'batchable=1',
'sort=title',
'direction=down',
`search=${'x'.repeat(201)}`,
])('rejects invalid strict scalar query: %s', async (query) => {
const response = await app().inject(`/api/v1/operations?${query}`);
expect(response.statusCode).toBe(400);
expect(response.headers['content-type']).toContain('application/problem+json');
expect(response.json()).toMatchObject({ code: 'VALIDATION_FAILED', status: 400 });
});
it('accepts every frozen capability including job', async () => {
const response = await app().inject('/api/v1/operations?capability=job&pageSize=100');
expect(response.statusCode).toBe(200);
expect(response.json().items.length).toBeGreaterThan(0);
expect(
response.json().items.every((item: { capability: string }) => item.capability === 'job'),
).toBe(true);
});
});
@@ -0,0 +1,109 @@
import type { OperationPageQuery } from '@multi-simadmin/contracts';
import type { FastifyInstance, FastifyRequest } from 'fastify';
import { OperationCatalogService } from '../../application/operations/operation-catalog-service.js';
import type { OperationCatalogRegistry } from '../../application/operations/operation-catalog-service.js';
const capabilities = new Set(['query', 'command', 'job']);
const keys = new Set([
'page',
'pageSize',
'sort',
'direction',
'risk',
'capability',
'batchable',
'search',
]);
class CatalogValidationError extends Error {}
function scalarQuery(request: FastifyRequest): Record<string, string> {
const raw = request.query;
if (raw === null || typeof raw !== 'object' || Array.isArray(raw))
throw new CatalogValidationError();
const result: Record<string, string> = {};
for (const [key, value] of Object.entries(raw)) {
if (!keys.has(key) || typeof value !== 'string') throw new CatalogValidationError();
result[key] = value;
}
return result;
}
function parseQuery(request: FastifyRequest): OperationPageQuery {
const query = scalarQuery(request);
const result: {
page?: number;
pageSize?: number;
sort?: 'operationId' | 'risk' | 'capability';
direction?: 'asc' | 'desc';
risk?: 'R0' | 'R1' | 'R2' | 'R3';
capability?: string;
batchable?: boolean;
search?: string;
} = {};
const integer = (key: 'page' | 'pageSize', maximum?: number): void => {
const value = query[key];
if (value === undefined) return;
if (!/^[1-9]\d*$/.test(value)) throw new CatalogValidationError();
const parsed = Number(value);
if (!Number.isSafeInteger(parsed) || (maximum !== undefined && parsed > maximum))
throw new CatalogValidationError();
result[key] = parsed;
};
integer('page');
integer('pageSize', 100);
const sort = query.sort;
if (sort !== undefined) {
if (sort !== 'operationId' && sort !== 'risk' && sort !== 'capability')
throw new CatalogValidationError();
result.sort = sort;
}
const direction = query.direction;
if (direction !== undefined) {
if (direction !== 'asc' && direction !== 'desc') throw new CatalogValidationError();
result.direction = direction;
}
const risk = query.risk;
if (risk !== undefined) {
if (risk !== 'R0' && risk !== 'R1' && risk !== 'R2' && risk !== 'R3')
throw new CatalogValidationError();
result.risk = risk;
}
const capability = query.capability;
if (capability !== undefined) {
if (!capabilities.has(capability)) throw new CatalogValidationError();
result.capability = capability;
}
const batchable = query.batchable;
if (batchable !== undefined) {
if (batchable !== 'true' && batchable !== 'false') throw new CatalogValidationError();
result.batchable = batchable === 'true';
}
const search = query.search;
if (search !== undefined) {
if (search.length > 200) throw new CatalogValidationError();
result.search = search;
}
return result;
}
export function registerOperationRoutes(
app: FastifyInstance,
registry: OperationCatalogRegistry,
): void {
const service = new OperationCatalogService(registry);
app.get('/api/v1/operations', async (request, reply) => {
try {
return service.list(parseQuery(request));
} catch (error) {
if (!(error instanceof CatalogValidationError)) throw error;
return reply.code(400).type('application/problem+json').send({
type: 'about:blank',
title: 'Bad Request',
status: 400,
code: 'VALIDATION_FAILED',
detail: 'The request did not satisfy the endpoint schema.',
requestId: request.id,
});
}
});
}