project-nomad/admin/start/routes.ts

754 lines
27 KiB
TypeScript

/*
|--------------------------------------------------------------------------
| Routes file
|--------------------------------------------------------------------------
|
| The routes file is used for defining the HTTP routes.
|
*/
import BenchmarkController from '#controllers/benchmark_controller'
import ChatsController from '#controllers/chats_controller'
import DocsController from '#controllers/docs_controller'
import DownloadsController from '#controllers/downloads_controller'
import EasySetupController from '#controllers/easy_setup_controller'
import HomeController from '#controllers/home_controller'
import MapsController from '#controllers/maps_controller'
import OllamaController from '#controllers/ollama_controller'
import OpenApiController from '#controllers/openapi_controller'
import RagController from '#controllers/rag_controller'
import SettingsController from '#controllers/settings_controller'
import SupplyDepotController from '#controllers/supply_depot_controller'
import SystemController from '#controllers/system_controller'
import CollectionUpdatesController from '#controllers/collection_updates_controller'
import ZimController from '#controllers/zim_controller'
import router from '@adonisjs/core/services/router'
import transmit from '@adonisjs/transmit/services/main'
import { documented } from '#start/openapi/documented'
import {
remoteDownloadValidator,
remoteDownloadWithMetadataValidator,
remoteDownloadValidatorOptional,
filenameParamValidator,
downloadCollectionValidator,
downloadCategoryTierValidator,
selectWikipediaValidator,
applyContentUpdateValidator,
applyAllContentUpdatesValidator,
mapExtractPreflightValidator,
mapExtractValidator,
} from '#validators/common'
import {
listRemoteZimValidator,
addCustomLibraryValidator,
browseLibraryValidator,
idParamValidator,
} from '#validators/zim'
import {
getJobStatusSchema,
deleteFileSchema,
embedFileSchema,
fileSourceSchema,
estimateBatchSchema,
} from '#validators/rag'
import {
installServiceValidator,
affectServiceValidator,
subscribeToReleaseNotesValidator,
checkLatestVersionValidator,
updateServiceValidator,
preflightValidator,
setServiceAutoUpdateValidator,
preflightCustomValidator,
customAppValidator,
setServiceCustomUrlValidator,
deleteCustomAppValidator,
uninstallServiceValidator,
serviceLogsValidator,
updateCustomAppValidator,
} from '#validators/system'
import {
chatSchema,
unloadChatModelsSchema,
getAvailableModelsSchema,
} from '#validators/ollama'
import { getSettingSchema, updateSettingSchema } from '#validators/settings'
import {
createSessionSchema,
updateSessionSchema,
addMessageSchema,
} from '#validators/chat'
import { downloadJobsByFiletypeSchema, modelNameSchema } from '#validators/download'
import { runBenchmarkValidator, submitBenchmarkValidator } from '#validators/benchmark'
import { healthResponse, errorResponse } from '#validators/responses/common'
import {
chatSessionResponse,
chatSessionListResponse,
chatMessageResponse,
} from '#validators/responses/chat'
transmit.registerRoutes()
router.get('/', [HomeController, 'index'])
router.get('/home', [HomeController, 'home'])
router.on('/about').renderInertia('about')
router.get('/chat', [ChatsController, 'inertia'])
router.get('/maps', [MapsController, 'index'])
router.get('/supply-depot', [SupplyDepotController, 'index'])
router.on('/knowledge-base').redirectToPath('/chat?knowledge_base=true') // redirect for legacy knowledge-base links
router.get('/easy-setup', [EasySetupController, 'index'])
router.get('/easy-setup/complete', [EasySetupController, 'complete'])
documented(
router.get('/api/easy-setup/curated-categories', [EasySetupController, 'listCuratedCategories']),
{
summary: 'List curated easy-setup categories',
tags: ['easy-setup'],
}
)
documented(router.post('/api/manifests/refresh', [EasySetupController, 'refreshManifests']), {
summary: 'Refresh content manifests',
tags: ['easy-setup'],
})
router
.group(() => {
documented(router.post('/check', [CollectionUpdatesController, 'checkForUpdates']), {
summary: 'Check for available content updates',
tags: ['content-updates'],
})
documented(router.post('/apply', [CollectionUpdatesController, 'applyUpdate']), {
summary: 'Apply a content update',
tags: ['content-updates'],
request: applyContentUpdateValidator,
})
documented(router.post('/apply-all', [CollectionUpdatesController, 'applyAllUpdates']), {
summary: 'Apply all available content updates',
tags: ['content-updates'],
request: applyAllContentUpdatesValidator,
})
})
.prefix('/api/content-updates')
router
.group(() => {
router.get('/system', [SettingsController, 'system'])
router.on('/apps').redirectToPath('/supply-depot') // superseded by Supply Depot
router.get('/legal', [SettingsController, 'legal'])
router.get('/maps', [SettingsController, 'maps'])
router.get('/models', [SettingsController, 'models'])
router.get('/update', [SettingsController, 'update'])
router.get('/zim', [SettingsController, 'zim'])
router.get('/zim/remote-explorer', [SettingsController, 'zimRemote'])
router.get('/benchmark', [SettingsController, 'benchmark'])
router.get('/support', [SettingsController, 'support'])
router.get('/advanced', [SettingsController, 'advanced'])
})
.prefix('/settings')
router
.group(() => {
router.get('/:slug', [DocsController, 'show'])
router.get('/', ({ response }) => {
// redirect to /docs/home if accessing root
response.redirect('/docs/home')
})
})
.prefix('/docs')
router
.group(() => {
documented(router.get('/regions', [MapsController, 'listRegions']), {
summary: 'List available map regions',
tags: ['maps'],
})
documented(router.get('/styles', [MapsController, 'styles']), {
summary: 'List available map styles',
tags: ['maps'],
})
documented(router.get('/curated-collections', [MapsController, 'listCuratedCollections']), {
summary: 'List curated map collections',
tags: ['maps'],
})
documented(router.post('/fetch-latest-collections', [MapsController, 'fetchLatestCollections']), {
summary: 'Fetch the latest map collections',
tags: ['maps'],
})
documented(router.post('/download-base-assets', [MapsController, 'downloadBaseAssets']), {
summary: 'Download base map assets',
tags: ['maps'],
request: remoteDownloadValidatorOptional,
})
documented(router.post('/download-remote', [MapsController, 'downloadRemote']), {
summary: 'Queue a remote map download',
tags: ['maps'],
request: remoteDownloadValidator,
})
documented(router.post('/download-remote-preflight', [MapsController, 'downloadRemotePreflight']), {
summary: 'Preflight a remote map download',
tags: ['maps'],
request: remoteDownloadValidator,
})
documented(router.post('/download-collection', [MapsController, 'downloadCollection']), {
summary: 'Download a map collection',
tags: ['maps'],
request: downloadCollectionValidator,
})
documented(router.get('/global-map-info', [MapsController, 'globalMapInfo']), {
summary: 'Get global map information',
tags: ['maps'],
})
documented(router.post('/download-global-map', [MapsController, 'downloadGlobalMap']), {
summary: 'Download the global map',
tags: ['maps'],
})
documented(router.get('/countries', [MapsController, 'listCountries']), {
summary: 'List available countries',
tags: ['maps'],
})
documented(router.get('/country-groups', [MapsController, 'listCountryGroups']), {
summary: 'List country groups',
tags: ['maps'],
})
documented(router.post('/extract-preflight', [MapsController, 'extractPreflight']), {
summary: 'Preflight a map region extraction',
tags: ['maps'],
request: mapExtractPreflightValidator,
})
documented(router.post('/extract', [MapsController, 'extractRegion']), {
summary: 'Extract a map region',
tags: ['maps'],
request: mapExtractValidator,
})
documented(router.get('/markers', [MapsController, 'listMarkers']), {
summary: 'List map markers',
tags: ['maps'],
})
documented(router.post('/markers', [MapsController, 'createMarker']), {
summary: 'Create a map marker',
tags: ['maps'],
})
documented(router.patch('/markers/:id', [MapsController, 'updateMarker']), {
summary: 'Update a map marker',
tags: ['maps'],
})
documented(router.delete('/markers/:id', [MapsController, 'deleteMarker']), {
summary: 'Delete a map marker',
tags: ['maps'],
})
documented(router.delete('/:filename', [MapsController, 'delete']), {
summary: 'Delete a map file',
tags: ['maps'],
params: filenameParamValidator,
})
})
.prefix('/api/maps')
router
.group(() => {
documented(router.get('/list', [DocsController, 'list']), {
summary: 'List documentation pages',
tags: ['docs'],
})
})
.prefix('/api/docs')
router
.group(() => {
documented(router.get('/jobs', [DownloadsController, 'index']), {
summary: 'List download jobs',
tags: ['downloads'],
})
documented(router.get('/jobs/:filetype', [DownloadsController, 'filetype']), {
summary: 'List download jobs by filetype',
tags: ['downloads'],
params: downloadJobsByFiletypeSchema,
})
documented(router.delete('/jobs/:jobId', [DownloadsController, 'removeJob']), {
summary: 'Remove a download job',
tags: ['downloads'],
})
documented(router.post('/jobs/:jobId/cancel', [DownloadsController, 'cancelJob']), {
summary: 'Cancel a download job',
tags: ['downloads'],
})
})
.prefix('/api/downloads')
documented(
router.get('/api/health', () => {
return { status: 'ok' }
}),
{ summary: 'Health check', tags: ['meta'], responses: { 200: healthResponse } }
)
// Self-generating API docs: OpenAPI spec + Scalar UI. Registered top-level so
// they stay clear of the `/docs/:slug` markdown catch-all above. The Scalar
// bundle is served from this app (not a CDN) for offline appliances.
router.get('/api/openapi.json', [OpenApiController, 'spec'])
router.get('/reference', [OpenApiController, 'reference'])
router.get('/reference/assets/standalone.js', [OpenApiController, 'standalone'])
router
.group(() => {
documented(router.post('/chat', [OllamaController, 'chat']), {
summary: 'Send a chat completion request',
tags: ['ollama'],
request: chatSchema,
})
documented(router.get('/models', [OllamaController, 'availableModels']), {
summary: 'List available models',
tags: ['ollama'],
query: getAvailableModelsSchema,
})
documented(router.post('/models', [OllamaController, 'dispatchModelDownload']), {
summary: 'Queue a model download',
tags: ['ollama'],
request: modelNameSchema,
})
documented(router.delete('/models', [OllamaController, 'deleteModel']), {
summary: 'Delete a model',
tags: ['ollama'],
request: modelNameSchema,
})
documented(router.get('/installed-models', [OllamaController, 'installedModels']), {
summary: 'List installed models',
tags: ['ollama'],
})
documented(router.post('/unload-chat-models', [OllamaController, 'unloadChatModels']), {
summary: 'Unload chat models from memory',
tags: ['ollama'],
request: unloadChatModelsSchema,
})
documented(router.post('/configure-remote', [OllamaController, 'configureRemote']), {
summary: 'Configure a remote Ollama endpoint',
tags: ['ollama'],
})
documented(router.get('/remote-status', [OllamaController, 'remoteStatus']), {
summary: 'Get remote Ollama status',
tags: ['ollama'],
})
})
.prefix('/api/ollama')
router
.group(() => {
documented(router.get('/', [ChatsController, 'index']), {
summary: 'List chat sessions',
tags: ['chat'],
responses: { 200: chatSessionListResponse },
})
documented(router.post('/', [ChatsController, 'store']), {
summary: 'Create a chat session',
tags: ['chat'],
request: createSessionSchema,
responses: {
201: { description: 'The created session', schema: chatSessionResponse },
500: errorResponse,
},
})
documented(router.delete('/all', [ChatsController, 'destroyAll']), {
summary: 'Delete all chat sessions',
tags: ['chat'],
responses: { 204: { description: 'All sessions deleted' } },
})
documented(router.get('/:id', [ChatsController, 'show']), {
summary: 'Get a chat session',
tags: ['chat'],
responses: {
200: chatSessionResponse,
404: { description: 'Session not found', schema: errorResponse },
},
})
documented(router.put('/:id', [ChatsController, 'update']), {
summary: 'Update a chat session',
tags: ['chat'],
request: updateSessionSchema,
responses: { 200: chatSessionResponse, 500: errorResponse },
})
documented(router.delete('/:id', [ChatsController, 'destroy']), {
summary: 'Delete a chat session',
tags: ['chat'],
responses: { 204: { description: 'Session deleted' } },
})
documented(router.post('/:id/messages', [ChatsController, 'addMessage']), {
summary: 'Add a message to a chat session',
tags: ['chat'],
request: addMessageSchema,
responses: {
201: { description: 'The created message', schema: chatMessageResponse },
500: errorResponse,
},
})
})
.prefix('/api/chat/sessions')
documented(router.get('/api/chat/suggestions', [ChatsController, 'suggestions']), {
summary: 'List chat suggestions',
tags: ['chat'],
})
router
.group(() => {
documented(router.post('/upload', [RagController, 'upload']), {
summary: 'Upload a file for RAG',
tags: ['rag'],
})
documented(router.get('/files', [RagController, 'getStoredFiles']), {
summary: 'List stored RAG files',
tags: ['rag'],
})
documented(router.get('/file-warnings', [RagController, 'getFileWarnings']), {
summary: 'List RAG file warnings',
tags: ['rag'],
})
documented(router.delete('/files', [RagController, 'deleteFile']), {
summary: 'Delete a RAG file',
tags: ['rag'],
query: deleteFileSchema,
})
documented(router.post('/files/embed', [RagController, 'embedFile']), {
summary: 'Embed a RAG file',
tags: ['rag'],
request: embedFileSchema,
})
documented(router.get('/files/content', [RagController, 'getFileContent']), {
summary: 'Get RAG file content',
tags: ['rag'],
query: fileSourceSchema,
})
documented(router.get('/files/download', [RagController, 'downloadFile']), {
summary: 'Download a RAG file',
tags: ['rag'],
query: fileSourceSchema,
})
documented(router.get('/active-jobs', [RagController, 'getActiveJobs']), {
summary: 'List active RAG jobs',
tags: ['rag'],
})
documented(router.get('/failed-jobs', [RagController, 'getFailedJobs']), {
summary: 'List failed RAG jobs',
tags: ['rag'],
})
documented(router.delete('/failed-jobs', [RagController, 'cleanupFailedJobs']), {
summary: 'Clean up failed RAG jobs',
tags: ['rag'],
})
documented(router.delete('/jobs', [RagController, 'cancelAllJobs']), {
summary: 'Cancel all RAG jobs',
tags: ['rag'],
})
documented(router.get('/job-status', [RagController, 'getJobStatus']), {
summary: 'Get RAG job status',
tags: ['rag'],
query: getJobStatusSchema,
})
documented(router.post('/sync', [RagController, 'scanAndSync']), {
summary: 'Scan and sync RAG files',
tags: ['rag'],
})
documented(router.post('/re-embed-all', [RagController, 'reembedAll']), {
summary: 'Re-embed all RAG files',
tags: ['rag'],
})
documented(router.post('/reset-and-rebuild', [RagController, 'resetAndRebuild']), {
summary: 'Reset and rebuild the RAG index',
tags: ['rag'],
})
documented(router.post('/estimate-batch', [RagController, 'estimateBatch']), {
summary: 'Estimate a RAG embedding batch',
tags: ['rag'],
request: estimateBatchSchema,
})
documented(router.get('/policy-prompt-state', [RagController, 'policyPromptState']), {
summary: 'Get RAG policy prompt state',
tags: ['rag'],
})
documented(router.get('/health', [RagController, 'health']), {
summary: 'RAG health check',
tags: ['rag'],
})
})
.prefix('/api/rag')
router
.group(() => {
documented(router.get('/debug-info', [SystemController, 'getDebugInfo']), {
summary: 'Get system debug information',
tags: ['system'],
})
documented(router.get('/info', [SystemController, 'getSystemInfo']), {
summary: 'Get system information',
tags: ['system'],
})
documented(router.get('/internet-status', [SystemController, 'getInternetStatus']), {
summary: 'Get internet connectivity status',
tags: ['system'],
})
documented(router.get('/services', [SystemController, 'getServices']), {
summary: 'List services',
tags: ['system'],
})
documented(router.post('/services/affect', [SystemController, 'affectService']), {
summary: 'Start, stop, or restart a service',
tags: ['system'],
request: affectServiceValidator,
})
documented(router.post('/services/install', [SystemController, 'installService']), {
summary: 'Install a service',
tags: ['system'],
request: installServiceValidator,
})
documented(router.post('/services/force-reinstall', [SystemController, 'forceReinstallService']), {
summary: 'Force reinstall a service',
tags: ['system'],
request: installServiceValidator,
})
documented(router.post('/services/uninstall', [SystemController, 'uninstallService']), {
summary: 'Uninstall a service',
tags: ['system'],
request: uninstallServiceValidator,
})
documented(router.post('/services/check-updates', [SystemController, 'checkServiceUpdates']), {
summary: 'Check for service updates',
tags: ['system'],
})
documented(router.get('/services/preflight', [SystemController, 'preflightCheck']), {
summary: 'Preflight a service install',
tags: ['system'],
query: preflightValidator,
})
documented(router.get('/services/suggest-port', [SystemController, 'suggestCustomPort']), {
summary: 'Suggest an available custom port',
tags: ['system'],
})
documented(router.post('/services/preflight-custom', [SystemController, 'preflightCustomApp']), {
summary: 'Preflight a custom app install',
tags: ['system'],
request: preflightCustomValidator,
})
documented(router.post('/services/custom', [SystemController, 'createCustomApp']), {
summary: 'Create a custom app',
tags: ['system'],
request: customAppValidator,
})
documented(router.put('/services/custom', [SystemController, 'updateCustomApp']), {
summary: 'Update a custom app',
tags: ['system'],
request: updateCustomAppValidator,
})
documented(router.post('/services/custom/update', [SystemController, 'updateCustomApp_pullLatest']), {
summary: 'Pull the latest version of a custom app',
tags: ['system'],
request: installServiceValidator,
})
documented(router.delete('/services/custom', [SystemController, 'deleteCustomApp']), {
summary: 'Delete a custom app',
tags: ['system'],
request: deleteCustomAppValidator,
})
documented(router.get('/services/custom/:name', [SystemController, 'getCustomApp']), {
summary: 'Get a custom app',
tags: ['system'],
})
documented(router.put('/services/custom-url', [SystemController, 'setServiceCustomUrl']), {
summary: 'Set a service custom URL',
tags: ['system'],
request: setServiceCustomUrlValidator,
})
documented(router.get('/services/:name/logs', [SystemController, 'getServiceLogs']), {
summary: 'Get service logs',
tags: ['system'],
query: serviceLogsValidator,
})
documented(router.get('/services/:name/stats', [SystemController, 'getServiceStats']), {
summary: 'Get service stats',
tags: ['system'],
})
documented(router.get('/services/:name/available-versions', [SystemController, 'getAvailableVersions']), {
summary: 'List available service versions',
tags: ['system'],
})
documented(router.post('/services/update', [SystemController, 'updateService']), {
summary: 'Update a service',
tags: ['system'],
request: updateServiceValidator,
})
documented(router.post('/services/auto-update', [SystemController, 'setServiceAutoUpdate']), {
summary: 'Set service auto-update',
tags: ['system'],
request: setServiceAutoUpdateValidator,
})
documented(router.get('/apps/auto-update/status', [SystemController, 'getAppAutoUpdateStatus']), {
summary: 'Get app auto-update status',
tags: ['system'],
})
documented(router.get('/content/auto-update/status', [SystemController, 'getContentAutoUpdateStatus']), {
summary: 'Get content auto-update status',
tags: ['system'],
})
documented(router.post('/subscribe-release-notes', [SystemController, 'subscribeToReleaseNotes']), {
summary: 'Subscribe to release notes',
tags: ['system'],
request: subscribeToReleaseNotesValidator,
})
documented(router.get('/latest-version', [SystemController, 'checkLatestVersion']), {
summary: 'Check the latest available version',
tags: ['system'],
query: checkLatestVersionValidator,
})
documented(router.post('/update', [SystemController, 'requestSystemUpdate']), {
summary: 'Request a system update',
tags: ['system'],
})
documented(router.get('/update/status', [SystemController, 'getSystemUpdateStatus']), {
summary: 'Get system update status',
tags: ['system'],
})
documented(router.get('/update/logs', [SystemController, 'getSystemUpdateLogs']), {
summary: 'Get system update logs',
tags: ['system'],
})
documented(router.get('/auto-update/status', [SystemController, 'getAutoUpdateStatus']), {
summary: 'Get system auto-update status',
tags: ['system'],
})
documented(router.get('/settings', [SettingsController, 'getSetting']), {
summary: 'Get a system setting',
tags: ['system'],
query: getSettingSchema,
})
documented(router.patch('/settings', [SettingsController, 'updateSetting']), {
summary: 'Update a system setting',
tags: ['system'],
request: updateSettingSchema,
})
})
.prefix('/api/system')
router
.group(() => {
documented(router.get('/list', [ZimController, 'list']), {
summary: 'List installed ZIM files',
tags: ['zim'],
})
documented(router.get('/list-remote', [ZimController, 'listRemote']), {
summary: 'List remote ZIM files',
tags: ['zim'],
query: listRemoteZimValidator,
})
documented(router.get('/curated-categories', [ZimController, 'listCuratedCategories']), {
summary: 'List curated ZIM categories',
tags: ['zim'],
})
documented(router.post('/download-remote', [ZimController, 'downloadRemote']), {
summary: 'Queue a remote ZIM download',
tags: ['zim'],
request: remoteDownloadWithMetadataValidator,
})
documented(router.post('/download-category-tier', [ZimController, 'downloadCategoryTier']), {
summary: 'Download a ZIM category tier',
tags: ['zim'],
request: downloadCategoryTierValidator,
})
documented(router.post('/upload', [ZimController, 'upload']), {
summary: 'Upload a ZIM file',
tags: ['zim'],
})
documented(router.get('/wikipedia', [ZimController, 'getWikipediaState']), {
summary: 'Get Wikipedia ZIM state',
tags: ['zim'],
})
documented(router.post('/wikipedia/select', [ZimController, 'selectWikipedia']), {
summary: 'Select a Wikipedia ZIM edition',
tags: ['zim'],
request: selectWikipediaValidator,
})
documented(router.get('/custom-libraries', [ZimController, 'listCustomLibraries']), {
summary: 'List custom ZIM libraries',
tags: ['zim'],
})
documented(router.post('/custom-libraries', [ZimController, 'addCustomLibrary']), {
summary: 'Add a custom ZIM library',
tags: ['zim'],
request: addCustomLibraryValidator,
})
documented(router.delete('/custom-libraries/:id', [ZimController, 'removeCustomLibrary']), {
summary: 'Remove a custom ZIM library',
tags: ['zim'],
params: idParamValidator,
})
documented(router.get('/browse-library', [ZimController, 'browseLibrary']), {
summary: 'Browse a ZIM library',
tags: ['zim'],
query: browseLibraryValidator,
})
documented(router.post('/rescan-library', [ZimController, 'rescanLibrary']), {
summary: 'Rescan the ZIM library',
tags: ['zim'],
})
documented(router.delete('/:filename', [ZimController, 'delete']), {
summary: 'Delete a ZIM file',
tags: ['zim'],
params: filenameParamValidator,
})
})
.prefix('/api/zim')
router
.group(() => {
documented(router.post('/run', [BenchmarkController, 'run']), {
summary: 'Run a benchmark',
tags: ['benchmark'],
request: runBenchmarkValidator,
})
documented(router.post('/run/system', [BenchmarkController, 'runSystem']), {
summary: 'Run a system benchmark',
tags: ['benchmark'],
})
documented(router.post('/run/ai', [BenchmarkController, 'runAI']), {
summary: 'Run an AI benchmark',
tags: ['benchmark'],
})
documented(router.get('/results', [BenchmarkController, 'results']), {
summary: 'List benchmark results',
tags: ['benchmark'],
})
documented(router.get('/results/latest', [BenchmarkController, 'latest']), {
summary: 'Get the latest benchmark result',
tags: ['benchmark'],
})
documented(router.get('/results/:id', [BenchmarkController, 'show']), {
summary: 'Get a benchmark result',
tags: ['benchmark'],
})
documented(router.post('/submit', [BenchmarkController, 'submit']), {
summary: 'Submit a benchmark result',
tags: ['benchmark'],
request: submitBenchmarkValidator,
})
documented(router.post('/builder-tag', [BenchmarkController, 'updateBuilderTag']), {
summary: 'Update the builder tag',
tags: ['benchmark'],
})
documented(router.get('/comparison', [BenchmarkController, 'comparison']), {
summary: 'Get benchmark comparison data',
tags: ['benchmark'],
})
documented(router.get('/status', [BenchmarkController, 'status']), {
summary: 'Get benchmark status',
tags: ['benchmark'],
})
documented(router.get('/settings', [BenchmarkController, 'settings']), {
summary: 'Get benchmark settings',
tags: ['benchmark'],
})
documented(router.post('/settings', [BenchmarkController, 'updateSettings']), {
summary: 'Update benchmark settings',
tags: ['benchmark'],
})
})
.prefix('/api/benchmark')