revents-online/prisma/schema.prisma

119 lines
4.0 KiB
Plaintext

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
did String @unique
username String?
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
eventSources EventSource[]
events Event[]
@@map("users")
}
// External event source (Luma, Meetup, iCal feed, manual, etc.)
model EventSource {
id String @id @default(cuid())
name String
sourceType String @map("source_type") // luma, meetup, ical, manual, rss
color String @default("#6b7280")
isActive Boolean @default(true) @map("is_active")
// Connection config (API key, feed URL, org slug, etc.)
config Json @default("{}")
lastSyncedAt DateTime? @map("last_synced_at")
lastSyncError String @default("") @map("last_sync_error")
eventCount Int @default(0) @map("event_count")
createdById String @map("created_by_id")
createdBy User @relation(fields: [createdById], references: [id])
// Space scoping
spaceSlug String? @map("space_slug")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
events Event[]
@@index([createdById])
@@index([spaceSlug])
@@map("event_sources")
}
model Event {
id String @id @default(cuid())
sourceId String @map("source_id")
externalId String @default("") @map("external_id")
externalUrl String @default("") @map("external_url")
// Core
title String
description String @default("")
start DateTime
end DateTime
allDay Boolean @default(false) @map("all_day")
timezoneStr String @default("UTC") @map("timezone_str")
rrule String @default("")
isRecurring Boolean @default(false) @map("is_recurring")
// Location
locationName String @default("") @map("location_name")
locationAddress String @default("") @map("location_address")
latitude Float?
longitude Float?
isVirtual Boolean @default(false) @map("is_virtual")
virtualUrl String @default("") @map("virtual_url")
virtualPlatform String @default("") @map("virtual_platform")
// Organizer / participants
organizerName String @default("") @map("organizer_name")
organizerEmail String @default("") @map("organizer_email")
organizerUrl String @default("") @map("organizer_url")
attendeeCount Int @default(0) @map("attendee_count")
maxAttendees Int? @map("max_attendees")
rsvpUrl String @default("") @map("rsvp_url")
// Categorization
status String @default("confirmed") // confirmed, tentative, cancelled
visibility String @default("public")
category String @default("") // conference, meetup, workshop, social, etc.
tags String[] @default([])
imageUrl String @default("") @map("image_url")
cost String @default("") // free, $10, etc.
// rStack integration
rToolSource String? @map("r_tool_source") // e.g. "rcal", "rinbox"
rToolEntityId String? @map("r_tool_entity_id")
syncedToRcal Boolean @default(false) @map("synced_to_rcal")
metadata Json?
// Ownership
createdById String? @map("created_by_id")
createdBy User? @relation(fields: [createdById], references: [id])
spaceSlug String? @map("space_slug")
// Timestamps
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
// Relations
source EventSource @relation(fields: [sourceId], references: [id], onDelete: Cascade)
@@unique([sourceId, externalId])
@@index([sourceId])
@@index([start, end])
@@index([spaceSlug])
@@index([category])
@@index([rToolSource, rToolEntityId])
@@map("events")
}