| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990 |
- generator client {
- provider = "prisma-client-js"
- }
- datasource db {
- provider = "postgresql"
- url = env("DATABASE_URL")
- }
- model User {
- id String @id @default(cuid())
- name String
- email String @unique
- emailVerified Boolean @default(false)
- image String?
- isSuperAdmin Boolean @default(false)
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- twoFactorEnabled Boolean @default(false)
- termsAcceptedAt DateTime?
- lastLogin DateTime?
- lastSeen DateTime?
- sessions Session[]
- accounts Account[]
- vehicles Vehicle[]
- customers Customer[]
- settings AppSetting[]
- inventoryParts InventoryPart[]
- quotes Quote[]
- customFieldDefinitions CustomFieldDefinition[]
- twoFactor TwoFactor?
- passkeys Passkey[]
- organizationMembers OrganizationMember[]
- @@map("users")
- }
- model AppSetting {
- id String @id @default(cuid())
- key String
- value String
- userId String
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- organizationId String?
- organization Organization? @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- @@unique([organizationId, key])
- @@index([organizationId])
- @@map("app_settings")
- }
- model Session {
- id String @id @default(cuid())
- expiresAt DateTime
- token String @unique
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- ipAddress String?
- userAgent String?
- userId String
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- @@index([userId])
- @@map("sessions")
- }
- model Account {
- id String @id @default(cuid())
- accountId String
- providerId String
- userId String
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- accessToken String?
- refreshToken String?
- idToken String?
- accessTokenExpiresAt DateTime?
- refreshTokenExpiresAt DateTime?
- scope String?
- password String?
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- @@index([userId])
- @@map("accounts")
- }
- model Verification {
- id String @id @default(cuid())
- identifier String @unique
- value String
- expiresAt DateTime
- createdAt DateTime? @default(now())
- updatedAt DateTime? @updatedAt
- @@map("verifications")
- }
- model TwoFactor {
- id String @id @default(cuid())
- secret String
- backupCodes String
- userId String @unique
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- @@map("two_factor")
- }
- model Passkey {
- id String @id @default(cuid())
- name String?
- publicKey String
- userId String
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- credentialID String @unique
- counter Int
- deviceType String
- backedUp Boolean
- transports String?
- aaguid String?
- createdAt DateTime @default(now())
- @@index([userId])
- @@map("passkeys")
- }
- model Vehicle {
- id String @id @default(cuid())
- make String
- model String
- year Int
- vin String?
- licensePlate String?
- color String?
- mileage Int @default(0)
- fuelType String? @default("gasoline")
- transmission String? @default("automatic")
- engineSize String?
- purchaseDate DateTime?
- purchasePrice Float?
- imageUrl String?
- isArchived Boolean @default(false)
- archiveReason String?
- maintenanceDismissed Boolean @default(false)
- maintenanceDismissedAt DateTime?
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- userId String
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- organizationId String?
- organization Organization? @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- customerId String?
- customer Customer? @relation(fields: [customerId], references: [id], onDelete: SetNull)
- serviceRecords ServiceRecord[]
- notes Note[]
- fuelLogs FuelLog[]
- reminders Reminder[]
- quotes Quote[]
- recurringInvoices RecurringInvoice[]
- inspections Inspection[]
- serviceRequests ServiceRequest[]
- @@index([organizationId])
- @@map("vehicles")
- }
- model ServiceRecord {
- id String @id @default(cuid())
- title String
- description String?
- type String @default("maintenance")
- status String @default("completed")
- cost Float @default(0)
- mileage Int?
- serviceDate DateTime @default(now())
- shopName String?
- techName String?
- parts String?
- laborHours Float?
- diagnosticNotes String?
- invoiceNotes String?
- subtotal Float @default(0)
- taxRate Float @default(0)
- taxAmount Float @default(0)
- totalAmount Float @default(0)
- invoiceNumber String?
- discountType String?
- discountValue Float @default(0)
- discountAmount Float @default(0)
- manuallyPaid Boolean @default(false)
- publicToken String? @unique
- sharedAt DateTime?
- viewCount Int @default(0)
- lastViewedAt DateTime?
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- vehicleId String
- vehicle Vehicle @relation(fields: [vehicleId], references: [id], onDelete: Cascade)
- partItems ServicePart[]
- laborItems ServiceLabor[]
- attachments ServiceAttachment[]
- payments Payment[]
- boardAssignments BoardAssignment[]
- @@index([vehicleId])
- @@map("service_records")
- }
- model Note {
- id String @id @default(cuid())
- title String
- content String
- isPinned Boolean @default(false)
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- vehicleId String
- vehicle Vehicle @relation(fields: [vehicleId], references: [id], onDelete: Cascade)
- @@index([vehicleId])
- @@map("notes")
- }
- model FuelLog {
- id String @id @default(cuid())
- date DateTime @default(now())
- mileage Int
- gallons Float
- pricePerGallon Float
- totalCost Float
- isFillUp Boolean @default(true)
- station String?
- notes String?
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- vehicleId String
- vehicle Vehicle @relation(fields: [vehicleId], references: [id], onDelete: Cascade)
- @@index([vehicleId])
- @@map("fuel_logs")
- }
- model Reminder {
- id String @id @default(cuid())
- title String
- description String?
- dueDate DateTime?
- dueMileage Int?
- isCompleted Boolean @default(false)
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- vehicleId String
- vehicle Vehicle @relation(fields: [vehicleId], references: [id], onDelete: Cascade)
- @@index([vehicleId])
- @@map("reminders")
- }
- model Customer {
- id String @id @default(cuid())
- name String
- email String?
- phone String?
- address String?
- company String?
- notes String?
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- userId String
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- organizationId String?
- organization Organization? @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- vehicles Vehicle[]
- quotes Quote[]
- smsMessages SmsMessage[]
- customerSessions CustomerSession[]
- serviceRequests ServiceRequest[]
- @@index([organizationId])
- @@map("customers")
- }
- model Payment {
- id String @id @default(cuid())
- amount Float
- date DateTime @default(now())
- method String @default("other")
- note String?
- provider String?
- externalId String?
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- serviceRecordId String
- serviceRecord ServiceRecord @relation(fields: [serviceRecordId], references: [id], onDelete: Cascade)
- @@index([serviceRecordId])
- @@map("payments")
- }
- model ServiceAttachment {
- id String @id @default(cuid())
- fileName String
- fileUrl String
- fileType String
- fileSize Int
- category String @default("diagnostic")
- description String?
- includeInInvoice Boolean @default(true)
- createdAt DateTime @default(now())
- updatedAt DateTime @default(now()) @updatedAt
- serviceRecordId String
- serviceRecord ServiceRecord @relation(fields: [serviceRecordId], references: [id], onDelete: Cascade)
- @@index([serviceRecordId])
- @@map("service_attachments")
- }
- model ServicePart {
- id String @id @default(cuid())
- partNumber String?
- name String
- quantity Float @default(1)
- unitPrice Float @default(0)
- total Float @default(0)
- createdAt DateTime @default(now())
- updatedAt DateTime @default(now()) @updatedAt
- serviceRecordId String
- serviceRecord ServiceRecord @relation(fields: [serviceRecordId], references: [id], onDelete: Cascade)
- @@index([serviceRecordId])
- @@map("service_parts")
- }
- model ServiceLabor {
- id String @id @default(cuid())
- description String
- hours Float @default(0)
- rate Float @default(0)
- total Float @default(0)
- createdAt DateTime @default(now())
- updatedAt DateTime @default(now()) @updatedAt
- serviceRecordId String
- serviceRecord ServiceRecord @relation(fields: [serviceRecordId], references: [id], onDelete: Cascade)
- @@index([serviceRecordId])
- @@map("service_labor")
- }
- model InventoryPart {
- id String @id @default(cuid())
- partNumber String?
- name String
- description String?
- category String?
- quantity Int @default(0)
- minQuantity Int @default(0)
- unitCost Float @default(0)
- sellPrice Float @default(0)
- supplier String?
- supplierPhone String?
- supplierEmail String?
- supplierUrl String?
- imageUrl String?
- location String?
- isArchived Boolean @default(false)
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- userId String
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- organizationId String?
- organization Organization? @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- @@index([organizationId])
- @@map("inventory_parts")
- }
- model Quote {
- id String @id @default(cuid())
- quoteNumber String?
- title String
- description String?
- status String @default("draft")
- validUntil DateTime?
- subtotal Float @default(0)
- taxRate Float @default(0)
- taxAmount Float @default(0)
- discountType String?
- discountValue Float @default(0)
- discountAmount Float @default(0)
- totalAmount Float @default(0)
- notes String?
- publicToken String?
- sharedAt DateTime?
- viewCount Int @default(0)
- lastViewedAt DateTime?
- customerMessage String?
- convertedToId String?
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- userId String
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- organizationId String?
- organization Organization? @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- customerId String?
- customer Customer? @relation(fields: [customerId], references: [id], onDelete: SetNull)
- vehicleId String?
- vehicle Vehicle? @relation(fields: [vehicleId], references: [id], onDelete: SetNull)
- inspectionId String?
- inspection Inspection? @relation(fields: [inspectionId], references: [id], onDelete: SetNull)
- partItems QuotePart[]
- laborItems QuoteLabor[]
- attachments QuoteAttachment[]
- @@index([organizationId])
- @@map("quotes")
- }
- model QuoteAttachment {
- id String @id @default(cuid())
- fileName String
- fileUrl String
- fileType String
- fileSize Int
- category String @default("image")
- description String?
- includeInInvoice Boolean @default(true)
- createdAt DateTime @default(now())
- updatedAt DateTime @default(now()) @updatedAt
- quoteId String
- quote Quote @relation(fields: [quoteId], references: [id], onDelete: Cascade)
- @@index([quoteId])
- @@map("quote_attachments")
- }
- model QuotePart {
- id String @id @default(cuid())
- partNumber String?
- name String
- quantity Float @default(1)
- unitPrice Float @default(0)
- total Float @default(0)
- excluded Boolean @default(false)
- createdAt DateTime @default(now())
- updatedAt DateTime @default(now()) @updatedAt
- quoteId String
- quote Quote @relation(fields: [quoteId], references: [id], onDelete: Cascade)
- @@index([quoteId])
- @@map("quote_parts")
- }
- model QuoteLabor {
- id String @id @default(cuid())
- description String
- hours Float @default(0)
- rate Float @default(0)
- total Float @default(0)
- excluded Boolean @default(false)
- createdAt DateTime @default(now())
- updatedAt DateTime @default(now()) @updatedAt
- quoteId String
- quote Quote @relation(fields: [quoteId], references: [id], onDelete: Cascade)
- @@index([quoteId])
- @@map("quote_labor")
- }
- model CustomFieldDefinition {
- id String @id @default(cuid())
- name String
- label String
- fieldType String @default("text")
- options String?
- required Boolean @default(false)
- entityType String
- sortOrder Int @default(0)
- isActive Boolean @default(true)
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- userId String
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- organizationId String?
- organization Organization? @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- values CustomFieldValue[]
- @@unique([organizationId, name, entityType])
- @@index([organizationId])
- @@map("custom_field_definitions")
- }
- model CustomFieldValue {
- id String @id @default(cuid())
- value String
- entityId String
- entityType String
- fieldId String
- field CustomFieldDefinition @relation(fields: [fieldId], references: [id], onDelete: Cascade)
- @@unique([fieldId, entityId])
- @@index([fieldId])
- @@map("custom_field_values")
- }
- model Organization {
- id String @id @default(cuid())
- name String
- portalSlug String? @unique
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- members OrganizationMember[]
- roles Role[]
- vehicles Vehicle[]
- customers Customer[]
- quotes Quote[]
- inventoryParts InventoryPart[]
- customFieldDefinitions CustomFieldDefinition[]
- settings AppSetting[]
- subscription Subscription?
- invitations TeamInvitation[]
- inspectionTemplates InspectionTemplate[]
- smsMessages SmsMessage[]
- technicians Technician[]
- syncDeletions SyncDeletion[]
- @@map("organizations")
- }
- model OrganizationMember {
- id String @id @default(cuid())
- role String @default("member")
- userId String
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- organizationId String
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- roleId String?
- customRole Role? @relation(fields: [roleId], references: [id], onDelete: SetNull)
- @@unique([userId, organizationId])
- @@map("organization_members")
- }
- model Role {
- id String @id @default(cuid())
- name String
- isAdmin Boolean @default(false)
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- organizationId String
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- permissions Permission[]
- members OrganizationMember[]
- teamInvitations TeamInvitation[]
- @@unique([organizationId, name])
- @@map("roles")
- }
- model Permission {
- id String @id @default(cuid())
- action String
- subject String
- roleId String
- role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
- @@unique([roleId, action, subject])
- @@index([roleId])
- @@map("permissions")
- }
- model SystemSetting {
- id String @id @default(cuid())
- key String @unique
- value String
- @@map("system_settings")
- }
- model TeamInvitation {
- id String @id @default(cuid())
- email String
- role String @default("member")
- token String @unique
- status String @default("pending") // pending | accepted | cancelled
- expiresAt DateTime
- createdAt DateTime @default(now())
- organizationId String
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- invitedById String
- roleId String?
- customRole Role? @relation(fields: [roleId], references: [id], onDelete: SetNull)
- @@unique([email, organizationId])
- @@index([token])
- @@map("team_invitations")
- }
- // Stripe-ready models (implementation in follow-up)
- model SubscriptionPlan {
- id String @id @default(cuid())
- name String
- stripePriceId String? @unique
- price Float @default(0)
- interval String @default("month") // "month" | "year"
- maxMembers Int @default(1)
- features String? // JSON feature flags
- isActive Boolean @default(true)
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- subscriptions Subscription[]
- @@map("subscription_plans")
- }
- model Subscription {
- id String @id @default(cuid())
- status String @default("active") // active | canceled | past_due | trialing
- stripeSubscriptionId String? @unique
- stripeCustomerId String?
- currentPeriodStart DateTime?
- currentPeriodEnd DateTime?
- cancelAtPeriodEnd Boolean @default(false)
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- organizationId String @unique
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- planId String
- plan SubscriptionPlan @relation(fields: [planId], references: [id])
- @@map("subscriptions")
- }
- model RecurringInvoice {
- id String @id @default(cuid())
- title String
- description String?
- frequency String // "weekly" | "biweekly" | "monthly" | "quarterly" | "yearly"
- nextRunDate DateTime
- endDate DateTime?
- isActive Boolean @default(true)
- lastRunAt DateTime?
- runCount Int @default(0)
- // Template fields (copied to ServiceRecord on generation)
- type String @default("maintenance")
- cost Float @default(0)
- taxRate Float @default(0)
- invoiceNotes String?
- vehicleId String
- vehicle Vehicle @relation(fields: [vehicleId], references: [id], onDelete: Cascade)
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- templateParts RecurringPart[]
- templateLabor RecurringLabor[]
- @@index([vehicleId])
- @@index([nextRunDate, isActive])
- @@map("recurring_invoices")
- }
- model RecurringPart {
- id String @id @default(cuid())
- name String
- partNumber String?
- quantity Int @default(1)
- unitPrice Float @default(0)
- recurringInvoiceId String
- recurringInvoice RecurringInvoice @relation(fields: [recurringInvoiceId], references: [id], onDelete: Cascade)
- @@map("recurring_parts")
- }
- model RecurringLabor {
- id String @id @default(cuid())
- description String
- hours Float @default(0)
- rate Float @default(0)
- recurringInvoiceId String
- recurringInvoice RecurringInvoice @relation(fields: [recurringInvoiceId], references: [id], onDelete: Cascade)
- @@map("recurring_labor")
- }
- model InspectionTemplate {
- id String @id @default(cuid())
- name String
- description String?
- isDefault Boolean @default(false)
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- organizationId String
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- sections InspectionTemplateSection[]
- inspections Inspection[]
- @@index([organizationId])
- @@map("inspection_templates")
- }
- model InspectionTemplateSection {
- id String @id @default(cuid())
- name 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
- sortOrder Int @default(0)
- 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?
- 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
- organizationId String
- items InspectionItem[]
- quoteRequests InspectionQuoteRequest[]
- quotes Quote[]
- boardAssignments BoardAssignment[]
- @@index([vehicleId])
- @@index([organizationId])
- @@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([])
- 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")
- }
- model Notification {
- id String @id @default(cuid())
- type String
- title String
- message String
- entityType String
- entityId String
- entityUrl String
- read Boolean @default(false)
- organizationId String
- createdAt DateTime @default(now())
- @@index([organizationId, createdAt(sort: Desc)])
- @@index([organizationId, read])
- @@map("notifications")
- }
- model SmsMessage {
- id String @id @default(cuid())
- direction String // "inbound" | "outbound"
- fromNumber String
- toNumber String
- body String
- status String @default("queued") // queued | sent | delivered | failed | received
- providerMsgId String?
- errorMessage String?
- relatedEntityType String?
- relatedEntityId String?
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- organizationId String
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- customerId String?
- customer Customer? @relation(fields: [customerId], references: [id], onDelete: SetNull)
- @@index([organizationId, customerId, createdAt(sort: Desc)])
- @@index([organizationId, createdAt(sort: Desc)])
- @@index([toNumber, organizationId])
- @@map("sms_messages")
- }
- model Technician {
- id String @id @default(cuid())
- name String
- color String @default("#3b82f6")
- isActive Boolean @default(true)
- sortOrder Int @default(0)
- memberId String?
- organizationId String
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- assignments BoardAssignment[]
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- @@index([organizationId])
- @@map("technicians")
- }
- model BoardAssignment {
- id String @id @default(cuid())
- date DateTime @db.Date
- sortOrder Int @default(0)
- notes String?
- technicianId String
- technician Technician @relation(fields: [technicianId], references: [id], onDelete: Cascade)
- serviceRecordId String?
- serviceRecord ServiceRecord? @relation(fields: [serviceRecordId], references: [id], onDelete: Cascade)
- inspectionId String?
- inspection Inspection? @relation(fields: [inspectionId], references: [id], onDelete: Cascade)
- organizationId String
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- @@unique([serviceRecordId, date])
- @@unique([inspectionId, date])
- @@index([organizationId, date])
- @@index([technicianId, date])
- @@map("board_assignments")
- }
- model CustomerSession {
- id String @id @default(cuid())
- token String @unique
- expiresAt DateTime
- createdAt DateTime @default(now())
- customerId String
- customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
- organizationId String
- @@index([token])
- @@index([customerId, organizationId])
- @@map("customer_sessions")
- }
- model CustomerMagicLink {
- id String @id @default(cuid())
- token String @unique
- email String
- organizationId String
- expiresAt DateTime
- usedAt DateTime?
- createdAt DateTime @default(now())
- @@index([token])
- @@map("customer_magic_links")
- }
- model ServiceRequest {
- id String @id @default(cuid())
- description String
- preferredDate DateTime?
- status String @default("pending")
- adminNotes String?
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- customerId String
- customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
- vehicleId String
- vehicle Vehicle @relation(fields: [vehicleId], references: [id], onDelete: Cascade)
- organizationId String
- @@index([organizationId, status])
- @@index([customerId])
- @@map("service_requests")
- }
- model SyncDeletion {
- id String @id @default(cuid())
- entity String
- recordId String
- organizationId String
- deletedAt DateTime @default(now())
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
- @@index([organizationId, deletedAt])
- @@map("sync_deletions")
- }
|