auth.prisma 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. model User {
  2. id String @id @default(cuid())
  3. name String
  4. email String @unique
  5. emailVerified Boolean @default(false)
  6. /// The mobile a technician signs in with, and the number a workshop holds
  7. /// for whoever this is.
  8. ///
  9. /// Deliberately not unique. When a desk creates an account for a mechanic
  10. /// standing at the counter, a second workshop may create another for the
  11. /// same human, and neither should be able to block the other. Every lookup
  12. /// reaches it through a technician row and so is already scoped to one
  13. /// workshop; the number alone is never the question being asked.
  14. phone String?
  15. image String?
  16. isSuperAdmin Boolean @default(false)
  17. createdAt DateTime @default(now())
  18. updatedAt DateTime @updatedAt
  19. twoFactorEnabled Boolean @default(false)
  20. termsAcceptedAt DateTime?
  21. lastLogin DateTime?
  22. lastSeen DateTime?
  23. /// App version this user last saw/dismissed the update banner for.
  24. /// Null = never seeded (seeded silently on first load, no banner).
  25. lastSeenVersion String?
  26. /// The release the update banner is up for, and when it first appeared to
  27. /// this user on any device. The hour it stays up runs from here, so a
  28. /// second device does not restart them and a closed tab cannot stop them.
  29. updateBannerVersion String?
  30. updateBannerShownAt DateTime?
  31. /// Per-user dashboard grid layout (card positions/sizes/hidden set).
  32. /// Null = default layout. Shape validated in dashboardLayoutActions.
  33. dashboardLayout Json?
  34. sessions Session[]
  35. devices UserDevice[]
  36. accounts Account[]
  37. pushDevices PushDevice[]
  38. appSetupCodes TechnicianSetupCode[]
  39. vehicles Vehicle[]
  40. customers Customer[]
  41. settings AppSetting[]
  42. inventoryParts InventoryPart[]
  43. quotes Quote[]
  44. customFieldDefinitions CustomFieldDefinition[]
  45. twoFactor TwoFactor?
  46. passkeys Passkey[]
  47. organizationMembers OrganizationMember[]
  48. dashboardWidgets DashboardWidget[]
  49. auditLogs AuditLog[]
  50. openedServiceRecords ServiceRecord[] @relation("ServiceRecordCreatedBy")
  51. confirmedConcerns ServiceConcern[] @relation("ConcernConfirmedBy")
  52. technicians Technician[]
  53. stockMovements StockMovement[]
  54. tireWarehouses TireWarehouse[]
  55. tireSets TireSet[]
  56. tireSetAttachments TireSetAttachment[]
  57. tireMeasurements TireMeasurement[]
  58. tireMovements TireMovement[]
  59. tireTreatments TireTreatment[]
  60. importBatches ImportBatch[]
  61. @@map("users")
  62. }
  63. model Session {
  64. id String @id @default(cuid())
  65. expiresAt DateTime
  66. token String @unique
  67. createdAt DateTime @default(now())
  68. updatedAt DateTime @updatedAt
  69. ipAddress String?
  70. userAgent String?
  71. userId String
  72. user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  73. @@index([userId])
  74. @@map("sessions")
  75. }
  76. model Account {
  77. id String @id @default(cuid())
  78. accountId String
  79. providerId String
  80. userId String
  81. user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  82. accessToken String?
  83. refreshToken String?
  84. idToken String?
  85. accessTokenExpiresAt DateTime?
  86. refreshTokenExpiresAt DateTime?
  87. scope String?
  88. password String?
  89. createdAt DateTime @default(now())
  90. updatedAt DateTime @updatedAt
  91. @@index([userId])
  92. @@map("accounts")
  93. }
  94. model Verification {
  95. id String @id @default(cuid())
  96. identifier String @unique
  97. value String
  98. expiresAt DateTime
  99. createdAt DateTime? @default(now())
  100. updatedAt DateTime? @updatedAt
  101. @@map("verifications")
  102. }
  103. model TwoFactor {
  104. id String @id @default(cuid())
  105. secret String
  106. backupCodes String
  107. userId String @unique
  108. user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  109. // better-auth's two-factor plugin writes these three since 1.6: a secret
  110. // stays unverified until the first code is entered, and repeated wrong
  111. // codes lock the method for a while. Rows from before default to verified,
  112. // because those people already proved their app worked.
  113. verified Boolean @default(true)
  114. failedVerificationCount Int @default(0)
  115. lockedUntil DateTime?
  116. @@map("two_factor")
  117. }
  118. model Passkey {
  119. id String @id @default(cuid())
  120. name String?
  121. publicKey String
  122. userId String
  123. user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  124. credentialID String @unique
  125. counter Int
  126. deviceType String
  127. backedUp Boolean
  128. transports String?
  129. aaguid String?
  130. createdAt DateTime @default(now())
  131. @@index([userId])
  132. @@map("passkeys")
  133. }
  134. /// A browser or phone this person has signed in from before.
  135. ///
  136. /// Sessions come and go (sign-out, expiry, a password change that ends the
  137. /// others), so the session table cannot say whether a device is new; this can.
  138. /// A browser is known by a random id in a long-lived cookie, set the first
  139. /// time it signs in; a client without cookies, such as the technician app,
  140. /// is known by its user agent. The first device an account ever sees is
  141. /// recorded quietly; every later one earns a "new sign-in" mail.
  142. model UserDevice {
  143. id String @id @default(cuid())
  144. /// Cookie id, or a hash of the user agent when no cookie can be kept.
  145. deviceKey String
  146. userAgent String?
  147. lastIp String?
  148. firstSeenAt DateTime @default(now())
  149. lastSeenAt DateTime @default(now())
  150. userId String
  151. user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  152. @@unique([userId, deviceKey])
  153. @@index([userId])
  154. @@map("user_devices")
  155. }