feat: Phase 4 — inspection sessions (create, execute, complete)
All checks were successful
Deploy to Production / deploy (push) Successful in 1m5s
All checks were successful
Deploy to Production / deploy (push) Successful in 1m5s
Backend: - InspectionSession + InspectionRecord models with alembic migration - 6 API endpoints: create, list, get detail, save records, complete, delete - Auto pass/fail judgment for numeric (spec range) and boolean items - Completed inspections are immutable, required items enforced on complete - 14 new tests (total 53/53 passed) Frontend: - Inspection list page with in_progress/completed tabs - Template select modal for starting new inspections - Inspection execution page with data-type-specific inputs - Auto-save with 1.5s debounce, manual save button - Completion modal with notes and required item validation - Read-only view for completed inspections - Pass/fail badges and color-coded item cards Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import useSWR from 'swr';
|
||||
import { fetcher, getTenantUrl } from './api';
|
||||
import type { Tenant, Machine, MachineDetail, EquipmentPart, InspectionTemplate } from './types';
|
||||
import type { Tenant, Machine, MachineDetail, EquipmentPart, InspectionTemplate, InspectionSession } from './types';
|
||||
|
||||
export function useTenants() {
|
||||
const { data, error, isLoading, mutate } = useSWR<{ tenants: Tenant[] }>(
|
||||
@@ -108,3 +108,39 @@ export function useTemplate(tenantId?: string, templateId?: string) {
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -81,6 +81,57 @@ export interface InspectionTemplateItem {
|
||||
created_at: string | null;
|
||||
}
|
||||
|
||||
export interface InspectionRecord {
|
||||
id: string;
|
||||
session_id: string;
|
||||
template_item_id: string;
|
||||
value_numeric: number | null;
|
||||
value_boolean: boolean | null;
|
||||
value_text: string | null;
|
||||
value_select: string | null;
|
||||
is_pass: boolean | null;
|
||||
recorded_at: string | null;
|
||||
created_at: string | null;
|
||||
updated_at: string | null;
|
||||
}
|
||||
|
||||
export interface InspectionItemDetail {
|
||||
record: InspectionRecord;
|
||||
item: {
|
||||
id: string;
|
||||
name: string;
|
||||
category: string | null;
|
||||
data_type: 'numeric' | 'boolean' | 'text' | 'select';
|
||||
unit: string | null;
|
||||
spec_min: number | null;
|
||||
spec_max: number | null;
|
||||
warning_min: number | null;
|
||||
warning_max: number | null;
|
||||
select_options: string[] | null;
|
||||
is_required: boolean;
|
||||
sort_order: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface InspectionSession {
|
||||
id: string;
|
||||
tenant_id: string;
|
||||
template_id: string;
|
||||
inspector_id: string;
|
||||
status: 'draft' | 'in_progress' | 'completed';
|
||||
started_at: string | null;
|
||||
completed_at: string | null;
|
||||
notes: string | null;
|
||||
template_name: string | null;
|
||||
inspector_name: string | null;
|
||||
items_count: number;
|
||||
records_count: number;
|
||||
records?: InspectionRecord[];
|
||||
items_detail?: InspectionItemDetail[];
|
||||
created_at: string | null;
|
||||
updated_at: string | null;
|
||||
}
|
||||
|
||||
export interface InspectionTemplate {
|
||||
id: string;
|
||||
tenant_id: string;
|
||||
|
||||
Reference in New Issue
Block a user