mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-02 19:55:18 +02:00
refactor(automations): source runs list from Zero
useAutomationRuns now reads from the zero_publication thin column set and adapts rows to LiveRunSummary (RunSummary + step_results). The detail hook stays on REST for the heavy fields.
This commit is contained in:
parent
c73f7ef03a
commit
69eb64db08
1 changed files with 83 additions and 16 deletions
|
|
@ -1,42 +1,109 @@
|
|||
"use client";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import type { Run, RunListResponse } from "@/contracts/types/automation.types";
|
||||
import { useQuery as useZeroQuery } from "@rocicorp/zero/react";
|
||||
import { useQuery as useReactQuery } from "@tanstack/react-query";
|
||||
import { useMemo } from "react";
|
||||
import type { Run, RunStepResult, RunSummary } from "@/contracts/types/automation.types";
|
||||
import { automationsApiService } from "@/lib/apis/automations-api.service";
|
||||
import { cacheKeys } from "@/lib/query-client/cache-keys";
|
||||
import { queries } from "@/zero/queries";
|
||||
|
||||
const DEFAULT_LIMIT = 50;
|
||||
const DEFAULT_OFFSET = 0;
|
||||
|
||||
/**
|
||||
* Thin live row sourced from Zero. Strict superset of {@link RunSummary} —
|
||||
* existing consumers that only look at the summary fields keep working,
|
||||
* while the run detail panel can read ``step_results`` directly for the
|
||||
* live step ticker without a second REST round-trip.
|
||||
*/
|
||||
export interface LiveRunSummary extends RunSummary {
|
||||
step_results: RunStepResult[];
|
||||
}
|
||||
|
||||
export interface UseAutomationRunsOptions {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
/** Paginated run history for one automation. Newest-first per backend. */
|
||||
interface UseAutomationRunsResult {
|
||||
data: { items: LiveRunSummary[]; total: number } | undefined;
|
||||
isLoading: boolean;
|
||||
error: Error | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Live run history for one automation, newest-first. Sourced from Zero's
|
||||
* thin ``automation_runs`` publication so status and per-step progress
|
||||
* tick in real time without polling. Heavy fields (output, artifacts,
|
||||
* inputs, error, definition_snapshot) are still fetched lazily via
|
||||
* {@link useAutomationRun}.
|
||||
*/
|
||||
export function useAutomationRuns(
|
||||
automationId: number | undefined,
|
||||
{ limit = DEFAULT_LIMIT, offset = DEFAULT_OFFSET, enabled = true }: UseAutomationRunsOptions = {}
|
||||
) {
|
||||
return useQuery<RunListResponse, Error>({
|
||||
queryKey: cacheKeys.automations.runs(automationId ?? 0, limit, offset),
|
||||
queryFn: () => automationsApiService.listRuns(automationId as number, { limit, offset }),
|
||||
enabled: enabled && !!automationId,
|
||||
staleTime: 30_000,
|
||||
});
|
||||
{ limit = DEFAULT_LIMIT }: UseAutomationRunsOptions = {}
|
||||
): UseAutomationRunsResult {
|
||||
const [rows, result] = useZeroQuery(
|
||||
queries.automationRuns.byAutomation({ automationId: automationId ?? -1 })
|
||||
);
|
||||
|
||||
const items = useMemo<LiveRunSummary[]>(() => {
|
||||
if (!automationId) return [];
|
||||
return rows.slice(0, limit).map(toLiveRunSummary);
|
||||
}, [automationId, rows, limit]);
|
||||
|
||||
const total = automationId ? rows.length : 0;
|
||||
|
||||
// Pre-hydration window: nothing visible AND Zero hasn't confirmed
|
||||
// completeness yet. After the first sync (even an empty set) we stop
|
||||
// showing the skeleton so the empty-state copy can take over.
|
||||
const isLoading = !!automationId && result.type !== "complete" && rows.length === 0;
|
||||
|
||||
return {
|
||||
data: automationId ? { items, total } : undefined,
|
||||
isLoading,
|
||||
error: null,
|
||||
};
|
||||
}
|
||||
|
||||
/** Single run with the full snapshot, step results, output and artifacts. */
|
||||
/**
|
||||
* Full run record (definition snapshot, inputs, output, artifacts, error).
|
||||
* Stays on REST: these fields are large and largely static after the run
|
||||
* finishes, so they're not worth replicating to every connected client.
|
||||
*/
|
||||
export function useAutomationRun(
|
||||
automationId: number | undefined,
|
||||
runId: number | undefined,
|
||||
options: { enabled?: boolean } = {}
|
||||
) {
|
||||
const { enabled = true } = options;
|
||||
return useQuery<Run, Error>({
|
||||
return useReactQuery<Run, Error>({
|
||||
queryKey: cacheKeys.automations.run(automationId ?? 0, runId ?? 0),
|
||||
queryFn: () => automationsApiService.getRun(automationId as number, runId as number),
|
||||
enabled: enabled && !!automationId && !!runId,
|
||||
staleTime: 30_000,
|
||||
});
|
||||
}
|
||||
|
||||
interface ZeroAutomationRunRow {
|
||||
id: number;
|
||||
automationId: number;
|
||||
triggerId?: number | null;
|
||||
status: string;
|
||||
stepResults: unknown;
|
||||
startedAt?: number | null;
|
||||
finishedAt?: number | null;
|
||||
createdAt: number;
|
||||
}
|
||||
|
||||
/** Adapt a Zero camelCase row (epoch ms timestamps) to the snake_case
|
||||
* ISO-string ``RunSummary`` shape the existing UI already consumes. */
|
||||
function toLiveRunSummary(row: ZeroAutomationRunRow): LiveRunSummary {
|
||||
return {
|
||||
id: row.id,
|
||||
automation_id: row.automationId,
|
||||
trigger_id: row.triggerId ?? null,
|
||||
status: row.status as RunSummary["status"],
|
||||
started_at: row.startedAt ? new Date(row.startedAt).toISOString() : null,
|
||||
finished_at: row.finishedAt ? new Date(row.finishedAt).toISOString() : null,
|
||||
created_at: new Date(row.createdAt).toISOString(),
|
||||
step_results: Array.isArray(row.stepResults) ? (row.stepResults as RunStepResult[]) : [],
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue