generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } // ─── Auth (NextAuth v5 + EncryptID) ───────────────────────────── model User { id String @id @default(cuid()) email String @unique name String? did String? @unique // EncryptID DID (passkey identity) emailVerified DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt accounts Account[] sessions Session[] nodes MeshNode[] messages LxmfMessage[] } model Account { id String @id @default(cuid()) userId String type String provider String providerAccountId String refresh_token String? @db.Text access_token String? @db.Text expires_at Int? token_type String? scope String? id_token String? @db.Text session_state String? user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([provider, providerAccountId]) } model Session { id String @id @default(cuid()) sessionToken String @unique userId String expires DateTime user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model VerificationToken { identifier String token String @unique expires DateTime @@unique([identifier, token]) } // ─── Mesh Models ───────────────────────────────────────────────── model MeshNode { id String @id @default(cuid()) name String reticulumHash String? @unique @map("reticulum_hash") nodeType String @default("software") @map("node_type") hardwareType String @default("") @map("hardware_type") firmwareVersion String @default("") @map("firmware_version") location String @default("") latitude Float? longitude Float? isOnline Boolean @default(false) @map("is_online") lastSeenAt DateTime? @map("last_seen_at") metadata Json @default("{}") registeredById String @map("registered_by_id") registeredBy User @relation(fields: [registeredById], references: [id]) spaceSlug String? @map("space_slug") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@index([spaceSlug]) @@index([registeredById]) @@index([nodeType]) @@map("mesh_nodes") } model LxmfMessage { id String @id @default(cuid()) lxmfHash String? @unique @map("lxmf_hash") direction String @default("inbound") senderHash String @default("") @map("sender_hash") recipientHash String @default("") @map("recipient_hash") title String @default("") content String contentType String @default("text/plain") @map("content_type") status String @default("pending") deliveredAt DateTime? @map("delivered_at") userId String? @map("user_id") user User? @relation(fields: [userId], references: [id]) spaceSlug String? @map("space_slug") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@index([spaceSlug]) @@index([userId]) @@index([direction]) @@index([senderHash]) @@map("lxmf_messages") } model TopologySnapshot { id String @id @default(cuid()) nodesJson Json @map("nodes_json") linksJson Json @map("links_json") nodeCount Int @default(0) @map("node_count") linkCount Int @default(0) @map("link_count") spaceSlug String? @map("space_slug") capturedAt DateTime @default(now()) @map("captured_at") @@index([capturedAt]) @@index([spaceSlug]) @@map("topology_snapshots") }