3d77f2846d
The old Repairs module had grown ticketing-system features (status lifecycle, comments, assignee, notes) that duplicate what the external ticketing tool already owns. Vector only needs to track whether maintenance is open or closed. - Rename RepairJob -> Fm (OPEN/CLOSED only), drop RepairComment, assignee, notes - New Repair table: persistent log of physical part swaps, with ingest on unknown broken MPN via partModels.upsertByMpn - New custody model: PENDING_DROP_IN_CUSTODY / PENDING_DESTRUCTION_IN_CUSTODY states + Part.custodianId, with a "My Custody" page for drop-off - PartModel.destroyOnFail routes broken parts to the destruction path - Host lookup on /fms and /repairs accepts hostId XOR assetId - Wire the dormant webhook emitter: fm.opened, fm.closed, repair.logged - Single fresh Prisma migration (dev DB was wiped, no backfill) Tests: 60 passing (custody transitions in parts.test.ts; new fms.test.ts, repairs.test.ts, custody.test.ts covering happy paths, validation failures, webhook emissions, and ingest-on-unknown-MPN). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
38 lines
698 B
TypeScript
38 lines
698 B
TypeScript
import { z } from 'zod';
|
|
import { PartState } from './enums.js';
|
|
|
|
export interface StateCount {
|
|
state: z.infer<typeof PartState>;
|
|
count: number;
|
|
totalPrice: number;
|
|
}
|
|
|
|
export interface AgeBucket {
|
|
label: string;
|
|
count: number;
|
|
}
|
|
|
|
export interface BinCount {
|
|
binId: string;
|
|
label: string;
|
|
count: number;
|
|
}
|
|
|
|
export interface PartModelEolSummary {
|
|
partModelId: string;
|
|
mpn: string;
|
|
manufacturerId: string;
|
|
manufacturerName: string;
|
|
eolDate: string;
|
|
deployedCount: number;
|
|
}
|
|
|
|
export interface DashboardAnalytics {
|
|
totalParts: number;
|
|
byState: StateCount[];
|
|
ageBuckets: AgeBucket[];
|
|
topBins: BinCount[];
|
|
deployedPastEol: PartModelEolSummary[];
|
|
openFms: number;
|
|
}
|