126 lines
3.7 KiB
Plaintext
126 lines
3.7 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "sqlite"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
// prisma/schema.prisma
|
|
|
|
// Enums
|
|
// VillageObjectType: Defines the possible types of objects that can be placed in the village grid.
|
|
enum VillageObjectType {
|
|
HOUSE
|
|
FIELD
|
|
ROAD
|
|
FENCE
|
|
OBSTACLE
|
|
}
|
|
|
|
// CropType: Defines the types of crops that can be planted.
|
|
enum CropType {
|
|
BLUEBERRIES
|
|
CORN
|
|
}
|
|
|
|
// User: Represents a registered user and stores their core profile,
|
|
// settings, and in-game resources like coins and experience points.
|
|
model User {
|
|
id Int @id @default(autoincrement())
|
|
email String @unique
|
|
password String
|
|
nickname String?
|
|
avatar String? @default("/avatars/default.png")
|
|
|
|
coins Int @default(0)
|
|
exp Int @default(0)
|
|
|
|
// User settings
|
|
soundOn Boolean @default(true)
|
|
confettiOn Boolean @default(true)
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
habits Habit[]
|
|
dailyVisits DailyVisit[]
|
|
village Village?
|
|
}
|
|
|
|
// Habit: A recurring task a user wants to build. Each habit belongs to a
|
|
// single user. The `daysOfWeek` field stores which days the habit is active.
|
|
model Habit {
|
|
id Int @id @default(autoincrement())
|
|
name String
|
|
// `daysOfWeek` is a JSON array of numbers [0, 1, ..., 6], where 0 is Sunday.
|
|
daysOfWeek Json
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
userId Int
|
|
completions HabitCompletion[]
|
|
}
|
|
|
|
// HabitCompletion: Records a single completion of a habit on a specific date.
|
|
// This creates a history of the user's progress for each habit.
|
|
model HabitCompletion {
|
|
id Int @id @default(autoincrement())
|
|
date DateTime // Store only the date part
|
|
|
|
// Relations
|
|
habit Habit @relation(fields: [habitId], references: [id], onDelete: Cascade)
|
|
habitId Int
|
|
|
|
@@unique([habitId, date]) // A habit can only be completed once per day
|
|
}
|
|
|
|
// DailyVisit: Tracks the user's daily visit for the "I visited the site today"
|
|
// quest and for calculating 5-day streaks.
|
|
model DailyVisit {
|
|
id Int @id @default(autoincrement())
|
|
date DateTime // Store only the date part
|
|
|
|
// Relations
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
userId Int
|
|
|
|
@@unique([userId, date]) // A user can only have one recorded visit per day
|
|
}
|
|
|
|
// Village: The user's personal village, which acts as a container for all
|
|
// village objects. Each user has exactly one village.
|
|
model Village {
|
|
id Int @id @default(autoincrement())
|
|
|
|
// Relations
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
userId Int @unique // Each user has only one village
|
|
objects VillageObject[]
|
|
}
|
|
|
|
// VillageObject: An object (e.g., house, field, obstacle) placed on the
|
|
// village grid. It stores the object's type, its coordinates, and optionally
|
|
// details if it's an obstacle or a planted crop.
|
|
model VillageObject {
|
|
id Int @id @default(autoincrement())
|
|
type VillageObjectType
|
|
x Int
|
|
y Int
|
|
obstacleMetadata String? // Stores metadata for obstacles (e.g., "rock", "bush").
|
|
|
|
// Crop details (only if type is FIELD)
|
|
cropType CropType?
|
|
plantedAt DateTime?
|
|
|
|
// Relations
|
|
village Village @relation(fields: [villageId], references: [id], onDelete: Cascade)
|
|
villageId Int
|
|
|
|
@@unique([villageId, x, y]) // Ensure only one object per grid cell per village
|
|
}
|