Skip to content

Data Model

  • All timestamps are stored and returned in UTC (ISO 8601 format).
  • All string IDs are cuid format.
  • Deletion is hard delete unless otherwise noted. Cascade rules are specified per foreign key.
User ──< Event (creator)
User ──< Application (applicant)
Event ──< Application (gig applications)
User ──< Collection ──< CollectionItem ──> Event
User ──< Interaction ──> Event
User ──< Conversation ──< Message
User ──< Notification
User ──< Follow ──> User (follower → followee)
Event ──< EventEmbedding (1:1, vector search)
FieldTypeConstraintsNotes
idStringPK, cuid
clerkIdStringuniqueClerk external ID
emailStringuniqueMust be @osu.edu or @buckeyemail.osu.edu
displayNameString?max 100 chars
majorString?max 100 charsFree-text, not validated against a list
gradYearInt?min 2000, max 2100Expected graduation year
interestsString[]Values from the predefined Category vocabulary (see below)
followerCountIntdefault 0Denormalized; incremented/decremented on Follow create/delete
followingCountIntdefault 0Denormalized; incremented/decremented on Follow create/delete
createdAtDateTimedefault now
updatedAtDateTimeauto
FieldTypeConstraintsNotes
idStringPK, cuid
titleStringrequired, max 200 chars
descriptionStringrequired, max 5000 chars
summaryString?max 500 charsAI-generated short summary. Null if AI unavailable
typeEventTypeenumEVENT or GIG
sourceEventSourceenumOSU_API, TICKETMASTER, or USER
externalIdString?uniqueDedup key for external events
categoryString?From Category vocabulary. AI-tagged or user-selected
tagsString[]max 20 items, each max 50 charsAI-generated or manual. Empty array if AI unavailable
imageUrlString?valid URL
ticketUrlString?valid URL
locationLocationrequired, embeddedSee Location value object below
startAtDateTimerequiredUTC
endAtDateTime?must be after startAt if presentUTC
compensationCompensation?embeddedGigs only. See Compensation value object below
statusEventStatusenum, default OPEN
creatorIdString?FK → User, ON DELETE SET NULLNull for external events. Set null if creator account is deleted
createdAtDateTimedefault now
updatedAtDateTimeauto
FieldTypeConstraintsNotes
idStringPK, cuid
gigIdStringFK → Event, ON DELETE CASCADEMust reference an Event with type GIG
applicantIdStringFK → User, ON DELETE CASCADE
messageString?max 1000 charsShort cover note
statusAppStatusenum, default PENDING
createdAtDateTimedefault now
updatedAtDateTimeauto

Unique constraint: (gigId, applicantId) — a user can apply to a gig only once.

FieldTypeConstraintsNotes
idStringPK, cuid
userIdStringFK → User, ON DELETE CASCADEOwner
nameStringrequired, max 100 chars
visibilityCollectionVisibilityenum, default PRIVATEPRIVATE or PUBLIC
createdAtDateTimedefault now
updatedAtDateTimeauto
FieldTypeConstraintsNotes
idStringPK, cuid
collectionIdStringFK → Collection, ON DELETE CASCADE
eventIdStringFK → Event, ON DELETE CASCADE
createdAtDateTimedefault now

Unique constraint: (collectionId, eventId) — an event appears in a collection only once.

FieldTypeConstraintsNotes
idStringPK, cuid
userIdStringFK → User, ON DELETE CASCADE
eventIdStringFK → Event, ON DELETE CASCADE
actionInteractionTypeenum
createdAtDateTimedefault now
FieldTypeConstraintsNotes
idStringPK, cuid
userIdStringFK → User, ON DELETE CASCADE
titleString?max 200 charsAuto-generated from first message. Null if AI unavailable
createdAtDateTimedefault now
updatedAtDateTimeauto
FieldTypeConstraintsNotes
idStringPK, cuid
conversationIdStringFK → Conversation, ON DELETE CASCADE
roleMessageRoleenum
contentStringrequired, max 10000 chars
createdAtDateTimedefault now
FieldTypeConstraintsNotes
idStringPK, cuid
userIdStringFK → User, ON DELETE CASCADERecipient
typeNotificationTypeenum
titleStringrequired, max 200 chars
bodyStringrequired, max 1000 chars
referenceIdString?ID of related entity
referenceTypeReferenceType?enumType of related entity
readBooleandefault false
createdAtDateTimedefault now
FieldTypeConstraintsNotes
idStringPK, cuid
followerIdStringFK → User, ON DELETE CASCADEThe user who follows
followeeIdStringFK → User, ON DELETE CASCADEThe user being followed
createdAtDateTimedefault now

Unique constraint: (followerId, followeeId) — a user can follow another user only once. Check constraint: followerId != followeeId — a user cannot follow themselves.

FieldTypeConstraintsNotes
idStringPK, cuid
eventIdStringFK → Event, ON DELETE CASCADE, uniqueOne embedding per event
embeddingvector(768)not nullpgvector column. Dimensions match embedding model config
textHashStringnot nullHash of source text. Used to detect staleness
createdAtDateTimedefault now
updatedAtDateTimeauto

Requires the pgvector PostgreSQL extension. An HNSW index is created on the embedding column for approximate nearest neighbor search.

These are embedded objects stored as JSON columns or flattened into parent table columns. They do not have their own IDs or tables.

FieldTypeConstraintsNotes
nameStringrequired, max 500 charsHuman-readable (e.g., “Thompson Library”)
latitudeFloat?-90 to 90
longitudeFloat?-180 to 180
FieldTypeConstraintsNotes
amountFloatrequired, min 0Dollar amount
currencyStringdefault “USD”ISO 4217 currency code
typeCompensationTypeenumFIXED or HOURLY
EventType: EVENT | GIG
EventSource: OSU_API | TICKETMASTER | USER
EventStatus: OPEN | IN_PROGRESS | COMPLETED | CANCELLED
AppStatus: PENDING | ACCEPTED | REJECTED
InteractionType: VIEW | SAVE | CLICK | APPLY | DISMISS
MessageRole: USER | ASSISTANT | SYSTEM
CollectionVisibility: PRIVATE | PUBLIC
NotificationType: APPLICATION_RECEIVED | APPLICATION_ACCEPTED | APPLICATION_REJECTED | GIG_COMPLETED | EVENT_REMINDER | NEW_FOLLOWER
ReferenceType: EVENT | APPLICATION | USER
CompensationType: FIXED | HOURLY

A predefined set of interest/event categories. Stored as strings. The set can be extended without a migration.

music | sports | tech | arts | academic | social | career | food | fitness | gaming | outdoors | volunteering | cultural | science | business | other

Users select interests from this list. Events are tagged with a category from this list (AI-tagged or user-selected). Interests and categories that do not match this vocabulary are accepted but ignored by the recommendation model’s category affinity signal.

Parent DeletedChild Behavior
User deletedEvents: creatorId set to NULL (events persist). Applications, Collections, Interactions, Conversations, Notifications, Follows: CASCADE deleted
Event deletedApplications, CollectionItems, Interactions, EventEmbedding: CASCADE deleted
Collection deletedCollectionItems: CASCADE deleted
Conversation deletedMessages: CASCADE deleted