Files
factoryOps-v2/dashboard/lib/hooks.ts
Johngreen 843f72e048
All checks were successful
Deploy to Production / deploy (push) Successful in 1m17s
feat: Phase 6 — alarm system (auto-generate, list, acknowledge)
- Add Alarm model with tenant/part/machine relationships and 3 indexes
- Add alembic migration c5d6e7f8a9b0_add_alarms
- Add alarms API: list (filter by ack/severity), summary, acknowledge
- Auto-generate alarms on counter update (threshold warning, critical at 100%)
- Duplicate alarm prevention for same part+alarm_type
- Add alarms frontend page with active/acknowledged tabs, summary badges
- 9 new tests (67/67 total passing)

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
2026-02-10 14:39:03 +09:00

198 lines
5.1 KiB
TypeScript

import useSWR from 'swr';
import { fetcher, getTenantUrl } from './api';
import type { Tenant, Machine, MachineDetail, EquipmentPart, InspectionTemplate, InspectionSession, PartReplacementLog, Alarm, AlarmSummary } from './types';
export function useTenants() {
const { data, error, isLoading, mutate } = useSWR<{ tenants: Tenant[] }>(
'/api/tenants',
fetcher,
);
return {
tenants: data?.tenants || [],
error,
isLoading,
mutate,
};
}
export function useTenantData<T>(path: string, tenantId?: string) {
const url = tenantId ? getTenantUrl(path, tenantId) : null;
const { data, error, isLoading, mutate } = useSWR<T>(url, fetcher);
return {
data: data ?? null,
error,
isLoading,
mutate,
};
}
export function useMachines(tenantId?: string) {
const url = tenantId ? `/api/${tenantId}/machines` : null;
const { data, error, isLoading, mutate } = useSWR<{ machines: Machine[] }>(
url,
fetcher,
{ refreshInterval: 30000, dedupingInterval: 2000 },
);
return {
machines: data?.machines || [],
error,
isLoading,
mutate,
};
}
export function useMachine(tenantId?: string, machineId?: string) {
const url = tenantId && machineId ? `/api/${tenantId}/machines/${machineId}` : null;
const { data, error, isLoading, mutate } = useSWR<MachineDetail>(
url,
fetcher,
{ refreshInterval: 30000, dedupingInterval: 2000 },
);
return {
machine: data ?? null,
error,
isLoading,
mutate,
};
}
export function useEquipmentParts(tenantId?: string, machineId?: string) {
const url = tenantId && machineId ? `/api/${tenantId}/machines/${machineId}/parts` : null;
const { data, error, isLoading, mutate } = useSWR<{ parts: EquipmentPart[] }>(
url,
fetcher,
{ refreshInterval: 30000, dedupingInterval: 2000 },
);
return {
parts: data?.parts || [],
error,
isLoading,
mutate,
};
}
export function useTemplates(tenantId?: string, subjectType?: string) {
const params = subjectType ? `?subject_type=${subjectType}` : '';
const url = tenantId ? `/api/${tenantId}/templates${params}` : null;
const { data, error, isLoading, mutate } = useSWR<{ templates: InspectionTemplate[] }>(
url,
fetcher,
{ refreshInterval: 30000, dedupingInterval: 2000 },
);
return {
templates: data?.templates || [],
error,
isLoading,
mutate,
};
}
export function useTemplate(tenantId?: string, templateId?: string) {
const url = tenantId && templateId ? `/api/${tenantId}/templates/${templateId}` : null;
const { data, error, isLoading, mutate } = useSWR<InspectionTemplate>(
url,
fetcher,
{ refreshInterval: 30000, dedupingInterval: 2000 },
);
return {
template: data ?? null,
error,
isLoading,
mutate,
};
}
export function useReplacements(tenantId?: string, partId?: string) {
const url = tenantId && partId ? `/api/${tenantId}/parts/${partId}/replacements` : null;
const { data, error, isLoading, mutate } = useSWR<{ replacements: PartReplacementLog[] }>(
url,
fetcher,
{ dedupingInterval: 2000 },
);
return {
replacements: data?.replacements || [],
error,
isLoading,
mutate,
};
}
export function useAlarms(tenantId?: string, isAcknowledged?: boolean) {
const params = new URLSearchParams();
if (isAcknowledged !== undefined) params.set('is_acknowledged', String(isAcknowledged));
const qs = params.toString();
const url = tenantId ? `/api/${tenantId}/alarms${qs ? `?${qs}` : ''}` : null;
const { data, error, isLoading, mutate } = useSWR<{ alarms: Alarm[] }>(
url,
fetcher,
{ refreshInterval: 10000, dedupingInterval: 2000 },
);
return {
alarms: data?.alarms || [],
error,
isLoading,
mutate,
};
}
export function useAlarmSummary(tenantId?: string) {
const url = tenantId ? `/api/${tenantId}/alarms/summary` : null;
const { data, error, isLoading, mutate } = useSWR<AlarmSummary>(
url,
fetcher,
{ refreshInterval: 10000, dedupingInterval: 2000 },
);
return {
summary: data ?? null,
error,
isLoading,
mutate,
};
}
export function useInspections(tenantId?: string, status?: string, templateId?: string) {
const params = new URLSearchParams();
if (status) params.set('status', status);
if (templateId) params.set('template_id', templateId);
const qs = params.toString();
const url = tenantId ? `/api/${tenantId}/inspections${qs ? `?${qs}` : ''}` : null;
const { data, error, isLoading, mutate } = useSWR<{ inspections: InspectionSession[] }>(
url,
fetcher,
{ refreshInterval: 10000, dedupingInterval: 2000 },
);
return {
inspections: data?.inspections || [],
error,
isLoading,
mutate,
};
}
export function useInspection(tenantId?: string, inspectionId?: string) {
const url = tenantId && inspectionId ? `/api/${tenantId}/inspections/${inspectionId}` : null;
const { data, error, isLoading, mutate } = useSWR<InspectionSession>(
url,
fetcher,
{ refreshInterval: 5000, dedupingInterval: 2000 },
);
return {
inspection: data ?? null,
error,
isLoading,
mutate,
};
}