model InspectionTemplate { id String @id @default(cuid()) name String description String? isDefault Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Regulatory profile. `country` is an ISO-3166 alpha-2 code (or null for a // shop-specific checklist), `standard` names the regime the template follows // (e.g. "eu-2014-45"), and `severityScale` picks which defect vocabulary the // technician grades against — see Lib/conditions.ts. country String? standard String? @default("custom") severityScale String @default("eu") /// Provenance, for templates that came from a package rather than being /// written here. `packageId` is namespaced and stable across renames /// ("torqvoice/eu-roadworthiness"), which is what lets the library tell an /// update from a duplicate. Null on a template the workshop wrote itself. packageId String? packageVersion String? /// Where it came from: "builtin", "file" or "catalogue". packageSource String? organizationId String organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) sections InspectionTemplateSection[] inspections Inspection[] @@index([organizationId]) @@index([organizationId, packageId]) @@map("inspection_templates") } model InspectionTemplateSection { id String @id @default(cuid()) name String description String? // Regulation reference for the section, e.g. "1" for Braking equipment in // Directive 2014/45/EU Annex I. code String? sortOrder Int @default(0) templateId String template InspectionTemplate @relation(fields: [templateId], references: [id], onDelete: Cascade) items InspectionTemplateItem[] @@index([templateId]) @@map("inspection_template_sections") } model InspectionTemplateItem { id String @id @default(cuid()) name String description String? // Regulation reference for the check, e.g. "1.1.13". code String? sortOrder Int @default(0) // How the technician records the result: "condition" (defect grading only), // "measurement" (numeric value in `unit`, graded against min/max), // "text" (free text) or "choice" (one of `choices`). inputType String @default("condition") unit String? minValue Float? maxValue Float? choices String[] @default([]) required Boolean @default(false) photoRequired Boolean @default(false) // Defect severity applied when a measurement falls outside min/max. defaultSeverity String? // Phrases this workshop wants offered when a defect is recorded against the // check, on top of the built-in catalogue. See Lib/defectCatalogue.ts. defectSuggestions String[] @default([]) sectionId String section InspectionTemplateSection @relation(fields: [sectionId], references: [id], onDelete: Cascade) @@index([sectionId]) @@map("inspection_template_items") } model Inspection { id String @id @default(cuid()) status String @default("in_progress") mileage Int? notes String? startDateTime DateTime? endDateTime DateTime? publicToken String? @unique completedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt vehicleId String vehicle Vehicle @relation(fields: [vehicleId], references: [id], onDelete: Cascade) templateId String template InspectionTemplate @relation(fields: [templateId], references: [id]) technicianId String? technician Technician? @relation(fields: [technicianId], references: [id], onDelete: SetNull) /// See ServiceRecord.workBayId — an inspection occupies a bay just as a /// repair does, and the work board lanes both the same way. workBayId String? workBay WorkBay? @relation(fields: [workBayId], references: [id], onDelete: SetNull) sortOrder Int @default(0) // Roadworthiness certificate fields required by Directive 2014/45/EU Annex IV. // `inspectorName` and `certificateNumber` are snapshots taken at completion so // the issued certificate stays stable even if staff or settings change later. /// Snapshot of how this inspection was graded, taken when it was created. /// Read in preference to the template's current setting: a workshop that /// later switches a template to the EU scale must not relabel a certificate /// it already issued. Null on inspections that predate the snapshot; those /// fall back to the template, which the migration pinned to its old scale. severityScale String? country String? vehicleCategory String? nextTestDue DateTime? certificateNumber String? inspectorName String? testLocation String? organizationId String items InspectionItem[] quoteRequests InspectionQuoteRequest[] quotes Quote[] serviceRecords ServiceRecord[] importBatchId String? importBatch ImportBatch? @relation(fields: [importBatchId], references: [id], onDelete: SetNull) @@index([vehicleId]) @@index([organizationId]) @@index([technicianId]) @@index([workBayId]) @@map("inspections") } model InspectionItem { id String @id @default(cuid()) name String section String sortOrder Int @default(0) condition String @default("not_inspected") notes String? imageUrls String[] @default([]) // Copied from the template at creation so an inspection stays readable even // after its template is edited or deleted. description String? code String? sectionCode String? inputType String @default("condition") unit String? minValue Float? maxValue Float? choices String[] @default([]) required Boolean @default(false) photoRequired Boolean @default(false) defaultSeverity String? defectSuggestions String[] @default([]) measuredValue Float? textValue String? inspectionId String inspection Inspection @relation(fields: [inspectionId], references: [id], onDelete: Cascade) @@index([inspectionId]) @@map("inspection_items") } model InspectionQuoteRequest { id String @id @default(cuid()) status String @default("pending") message String? selectedItemIds String[] createdAt DateTime @default(now()) inspectionId String inspection Inspection @relation(fields: [inspectionId], references: [id], onDelete: Cascade) organizationId String @@index([organizationId]) @@index([inspectionId]) @@map("inspection_quote_requests") }