Files
drop/prisma/models/content.prisma
DecDuck 8363de2eed Store overhaul (#142)
* feat: small library tweaks + company page

* feat: new store view

* fix: ci merge error

* feat: add genres to store page

* feat: sorting

* feat: lock game/version imports while their tasks are running

* feat: feature games

* feat: tag based filtering

* fix: make tags alphabetical

* refactor: move a bunch of i18n to common

* feat: add localizations for everything

* fix: title description on panel

* fix: feature carousel text

* fix: i18n footer strings

* feat: add tag page

* fix: develop merge

* feat: offline games support (don't error out if provider throws)

* feat: tag management

* feat: show library next to game import + small fixes

* feat: most of the company and tag managers

* feat: company text field editing

* fix: small fixes + tsgo experiemental

* feat: upload icon and banner

* feat: store infinite scrolling and bulk import mode

* fix: lint

* fix: add drop-base to prettier ignore
2025-07-30 13:40:49 +10:00

185 lines
4.7 KiB
Plaintext

enum MetadataSource {
Manual
GiantBomb
PCGamingWiki
IGDB
Metacritic
OpenCritic
}
model Game {
id String @id @default(uuid())
metadataSource MetadataSource
metadataId String
created DateTime @default(now())
// Any field prefixed with m is filled in from metadata
// Acts as a cache so we can search and filter it
mName String // Name of game
mShortDescription String // Short description
mDescription String // Supports markdown
mReleased DateTime // When the game was released
ratings GameRating[]
featured Boolean @default(false)
mIconObjectId String // linked to objects in s3
mBannerObjectId String // linked to objects in s3
mCoverObjectId String
mImageCarouselObjectIds String[] // linked to below array
mImageLibraryObjectIds String[] // linked to objects in s3
versions GameVersion[]
// These fields will not be optional in the next version
// Any game without a library ID will be assigned one at startup, based on the defaults
libraryId String?
library Library? @relation(fields: [libraryId], references: [id])
libraryPath String
collections CollectionEntry[]
saves SaveSlot[]
screenshots Screenshot[]
tags GameTag[]
playtime Playtime[]
developers Company[] @relation(name: "developers")
publishers Company[] @relation(name: "publishers")
@@unique([metadataSource, metadataId], name: "metadataKey")
@@unique([libraryId, libraryPath], name: "libraryKey")
}
model GameTag {
id String @id @default(uuid())
name String @unique
games Game[]
@@index([name(ops: raw("gist_trgm_ops(siglen=32)"))], type: Gist)
}
model GameRating {
id String @id @default(uuid())
metadataSource MetadataSource
metadataId String
created DateTime @default(now())
mReviewCount Int
mReviewRating Float // 0 to 1
mReviewHref String?
game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
gameId String
@@unique([metadataSource, metadataId], name: "metadataKey")
}
// A particular set of files that relate to the version
model GameVersion {
gameId String
game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
versionName String // Sub directory for the game files
created DateTime @default(now())
platform Platform
launchCommand String @default("") // Command to run to start. Platform-specific. Windows games on Linux will wrap this command in Proton/Wine
launchArgs String[]
setupCommand String @default("") // Command to setup game (dependencies and such)
setupArgs String[]
onlySetup Boolean @default(false)
umuIdOverride String?
dropletManifest Json // Results from droplet
versionIndex Int
delta Boolean @default(false)
@@id([gameId, versionName])
}
// A save slot for a game
model SaveSlot {
gameId String
game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
index Int
createdAt DateTime @default(now())
playtime Float @default(0) // hours
lastUsedClientId String?
lastUsedClient Client? @relation(fields: [lastUsedClientId], references: [id])
historyObjectIds String[] // list of objects
historyChecksums String[] // list of hashes
@@id([gameId, userId, index], name: "id")
}
model Screenshot {
id String @id @default(uuid())
gameId String
game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
objectId String
private Boolean // if other users can see
createdAt DateTime @default(now()) @db.Timestamptz(0)
@@index([gameId, userId])
@@index([userId])
}
model Playtime {
gameId String
game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
seconds Int // seconds user has spent playing the game
updatedAt DateTime @updatedAt @db.Timestamptz(6)
createdAt DateTime @default(now()) @db.Timestamptz(6)
@@id([gameId, userId])
@@index([userId])
}
model Company {
id String @id @default(uuid())
metadataSource MetadataSource
metadataId String
metadataOriginalQuery String
mName String
mShortDescription String
mDescription String
mLogoObjectId String
mBannerObjectId String
mWebsite String
developed Game[] @relation(name: "developers")
published Game[] @relation(name: "publishers")
@@unique([metadataSource, metadataId], name: "metadataKey")
}
model ObjectHash {
id String @id
hash String
}