Extract dashboard overview route (#75)

* review: harden readonly git checks and lint verification

* test: satisfy readonly reviewer sandbox typing

* test: fix readonly reviewer sandbox assertions

* test: remove impossible readonly sandbox guards

* test: relax readonly sandbox assertions

* test: cast readonly sandbox expectation shape

* test: cast readonly sandbox expectation through unknown

* Phase 0 — STEP_DONE/TASK_DONE split + owner-follow-up integration smoke

* Add STEP_DONE guards, verdict storage, and stale delivery suppression

* style: format paired stepdone telemetry files

* Route STEP_DONE through reviewer

* Add structured Discord attachments

* style: format structured attachment test

* Fix room thread bot output parity

* Remove duplicate work item attachment migration from owner branch

* Remove legacy dashboard rooms renderer

* Extract dashboard parsed body renderer

* Extract dashboard redaction helpers

* Extract dashboard RoomCardV2 component

* Include RoomCardV2 test in vitest suite

* Extract dashboard RoomBoardV2 component

* Extract dashboard EmptyState component

* Extract dashboard InboxPanel component

* Split dashboard InboxPanel card renderer

* Extract dashboard TaskPanel component

* Extract dashboard UsagePanel component

* Fix dashboard room thread chunk rendering

* Extract dashboard ServicePanel component

* Render dashboard live progress markdown

* Extract dashboard SettingsPanel component

* Fix structured attachment rendering

* Extract dashboard simple route table

* Extract dashboard settings routes

* Extract dashboard service routes

* Extract dashboard room timeline routes

* Extract dashboard task routes

* Extract dashboard overview route
This commit is contained in:
Eyejoker
2026-04-28 19:13:33 +09:00
committed by GitHub
parent 69aa1c72c2
commit 87d0ef8c05
3 changed files with 232 additions and 19 deletions

View File

@@ -0,0 +1,63 @@
import type { StatusSnapshot } from './status-dashboard.js';
import type { PairedTask, ScheduledTask } from './types.js';
import { buildWebDashboardOverview } from './web-dashboard-data.js';
import type { ServiceRestartRecord } from './web-dashboard-service-routes.js';
type JsonResponse = (
value: unknown,
init?: ResponseInit,
request?: Request,
) => Response;
type DismissableInboxItem = {
id: string;
lastOccurredAt: string;
};
export interface OverviewRouteDependencies {
isInboxItemDismissed?: (item: DismissableInboxItem) => boolean;
loadPairedTasks: () => PairedTask[];
loadTasks: () => ScheduledTask[];
readSnapshots: (maxAgeMs: number) => StatusSnapshot[];
recentServiceRestarts: ServiceRestartRecord[];
statusMaxAgeMs: number;
now?: () => string;
}
interface OverviewRouteContext extends OverviewRouteDependencies {
url: URL;
jsonResponse: JsonResponse;
}
export function handleOverviewRoute({
isInboxItemDismissed,
jsonResponse,
loadPairedTasks,
loadTasks,
now,
readSnapshots,
recentServiceRestarts,
statusMaxAgeMs,
url,
}: OverviewRouteContext): Response | null {
if (url.pathname !== '/api/overview') return null;
const snapshots = readSnapshots(statusMaxAgeMs);
const tasks = loadTasks();
const pairedTasks = loadPairedTasks();
const overview = buildWebDashboardOverview({
now: now?.(),
snapshots,
tasks,
pairedTasks,
});
return jsonResponse({
...overview,
operations: {
serviceRestarts: recentServiceRestarts,
},
inbox: isInboxItemDismissed
? overview.inbox.filter((item) => !isInboxItemDismissed(item))
: overview.inbox,
});
}