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 }