diff --git a/src/lib/hosts.ts b/src/lib/hosts.ts index 44478e4..c7e572a 100644 --- a/src/lib/hosts.ts +++ b/src/lib/hosts.ts @@ -113,6 +113,15 @@ export interface HostOperationSummary extends Omit { - const { total } = handle.prepare(`SELECT COUNT(*) AS total FROM ec_host_operations o ${where}`).get() as { total: number }; + const { total } = handle.prepare(`SELECT COUNT(*) AS total FROM ec_host_operations o ${where}`).get(...parameters) as { total: number }; const totalPages = Math.max(1, Math.ceil(total / pageSize)); const currentPage = Math.min(totalPages, Number.isSafeInteger(page) && page > 0 ? page : 1); const operations = handle.prepare(`SELECT o.id,o.host_id AS hostId,h.name AS hostName,o.kind, @@ -411,7 +415,7 @@ export function listHostOperationHistory(page = 1, filter: HostOperationFilter = FROM ec_host_operations o LEFT JOIN ec_hosts h ON h.id=o.host_id AND h.deleted_at IS NULL ${where} ORDER BY o.created_at DESC,o.rowid DESC LIMIT ? OFFSET ?`) - .all(pageSize, (currentPage - 1) * pageSize) as HostOperationHistoryPage['operations']; + .all(...parameters, pageSize, (currentPage - 1) * pageSize) as HostOperationHistoryPage['operations']; return { operations: operations.map(operation => ({ ...operation, routine: !!operation.routine, targetPath: safeOperationTarget(operation.kind, operation.targetPath) })), filter, page: currentPage, pageSize, total, totalPages }; diff --git a/src/lib/server/hosts/schema.ts b/src/lib/server/hosts/schema.ts index 116b63b..72c70d0 100644 --- a/src/lib/server/hosts/schema.ts +++ b/src/lib/server/hosts/schema.ts @@ -110,6 +110,8 @@ export function ensureHostSchema(handle: Database.Database): void { })(); } handle.exec(`CREATE INDEX IF NOT EXISTS ec_host_operations_routine_history ON ec_host_operations(routine,created_at); + CREATE INDEX IF NOT EXISTS ec_host_operations_host_history ON ec_host_operations(host_id,created_at); + CREATE INDEX IF NOT EXISTS ec_host_operations_server_history ON ec_host_operations(server_name,created_at); CREATE INDEX IF NOT EXISTS ec_host_operations_important_history ON ec_host_operations(created_at) WHERE ${importantOperationSql.replaceAll('o.', '')}`); handle.exec('CREATE TABLE IF NOT EXISTS ec_host_schema_migrations (name TEXT PRIMARY KEY)'); diff --git a/src/routes/api/hosts/operations/+server.ts b/src/routes/api/hosts/operations/+server.ts index 25c8121..f11f362 100644 --- a/src/routes/api/hosts/operations/+server.ts +++ b/src/routes/api/hosts/operations/+server.ts @@ -1,7 +1,7 @@ import { error, json } from '@sveltejs/kit'; import { listHostOperationHistory } from '$lib/server/hosts/index.js'; import { requireManagementOrigin } from '$lib/server/hosts/http.js'; -import { isHostOperationFilter } from '$lib/hosts.js'; +import { hostOperationScope, isHostOperationFilter } from '$lib/hosts.js'; export function GET({ request }: { request: Request }) { requireManagementOrigin(request); @@ -10,5 +10,9 @@ export function GET({ request }: { request: Request }) { const filter = params.get('filter') ?? 'important'; if (!Number.isSafeInteger(page) || page < 1) error(400, 'Invalid operation history page.'); if (!isHostOperationFilter(filter)) error(400, 'Invalid operation history filter.'); - return json(listHostOperationHistory(page, filter), { headers: { 'Cache-Control': 'no-store' } }); + const scope = hostOperationScope(params); + for (const key of ['host', 'server'] as const) { + if (params.has(key) && params.get(key) !== scope[key]) error(400, 'Invalid operation history scope.'); + } + return json(listHostOperationHistory(page, filter, scope), { headers: { 'Cache-Control': 'no-store' } }); } diff --git a/src/routes/capacity/+page.svelte b/src/routes/capacity/+page.svelte index ad4730d..6f35012 100644 --- a/src/routes/capacity/+page.svelte +++ b/src/routes/capacity/+page.svelte @@ -1,4 +1,5 @@ -Operation history · Hosts · Electric Cherry +Host operation history · Electric Cherry
- + {#snippet actions()}{/snippet} + {#if $page.url.searchParams.has('returnTo')}{/if} + {#if data.scope.host || data.scope.server}
Showing {data.hostName ? `host: ${data.hostName}` : ''}{data.scope.host && data.scope.server ? ' · ' : ''}{data.scope.server ? `server: ${data.scope.server}` : ''}Clear scope
{/if}