PostgreSQL 16 database with Prisma ORM for type-safe database operations.
Stores admin users for authentication.
model User {
id Int @id @default(autoincrement())
email String @unique
name String
password String (hashed with bcryptjs)
role Role @default(ADMIN)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum Role {
ADMIN # Standard admin
SUPER_ADMIN # Full system access
}Represents building floors.
model Floor {
id Int @id @default(autoincrement())
number Int @unique
name String
description String?
rooms Room[] # Related rooms
announcements Announcement[]
nodes Node[] # Display nodes on this floor
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Individual rooms/classrooms.
model Room {
id Int @id @default(autoincrement())
name String
code String @unique # Room identifier
type RoomType # Lecture hall, Lab, etc.
capacity Int?
floor Floor @relation(fields: [floorId], references: [id], onDelete: Cascade)
floorId Int
schedules Schedule[] # Room schedules
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum RoomType {
LECTURE_HALL
LAB
SEMINAR_ROOM
OFFICE
COMMON_AREA
OTHER
}Room availability and bookings.
model Schedule {
id Int @id @default(autoincrement())
room Room @relation(fields: [roomId], references: [id], onDelete: Cascade)
roomId Int
title String
description String?
startTime DateTime
endTime DateTime
recurring Boolean @default(false)
recurrenceRule String? # RRULE format
instructor String?
courseCode String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}System-wide or floor-specific announcements.
model Announcement {
id Int @id @default(autoincrement())
title String
content String
floor Floor? @relation(fields: [floorId], references: [id], onDelete: SetNull)
floorId Int? # Null = global announcement
priority Priority @default(NORMAL)
startDate DateTime
endDate DateTime?
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum Priority {
LOW
NORMAL
HIGH
URGENT
}Display kiosk devices (Raspberry Pi nodes).
model Node {
id Int @id @default(autoincrement())
name String
identifier String @unique # Device ID
floor Floor @relation(fields: [floorId], references: [id], onDelete: Cascade)
floorId Int
location String? # Physical location
isActive Boolean @default(true)
lastHeartbeat DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}cd server
# Generate Prisma Client
npm run db:generate
# Push schema to database
npm run db:pushnpm run db:seedDefault seed creates:
- Super admin user (email: admin@example.com)
- Sample floors
- Sample rooms
- Test schedules
# Create a new migration after schema changes
npm run db:migrate:dev --name "description_of_changes"
# Deploy existing migrations
npm run db:migrate
# Reset database (⚠️ deletes all data)
npx prisma migrate resetGUI for database management:
npm run db:studio
# Opens at http://localhost:5555View and edit data directly without SQL.
# Connect to PostgreSQL via psql
docker exec -it displaydb psql -U postgres -d display_db
# Useful commands:
\dt # List tables
\d <table> # Describe table
SELECT * FROM "User";// Via API or admin panel
const user = await prisma.user.create({
data: {
email: "user@example.com",
name: "John Doe",
password: await bcrypt.hash("password", 10),
role: "ADMIN"
}
});const floor = await prisma.floor.create({
data: {
number: 1,
name: "First Floor",
description: "Main entrance floor"
}
});const room = await prisma.room.create({
data: {
name: "Lecture Hall A",
code: "A101",
type: "LECTURE_HALL",
capacity: 100,
floorId: 1
}
});const schedule = await prisma.schedule.create({
data: {
title: "Advanced Mathematics",
roomId: 1,
startTime: new Date("2024-03-15T09:00:00"),
endTime: new Date("2024-03-15T11:00:00"),
instructor: "Dr. Smith",
courseCode: "MATH301"
}
});postgresql://[user]:[password]@[host]:[port]/[database]
Example:
postgresql://postgres:postgres@localhost:5432/display_db
docker exec displaydb pg_dump -U postgres display_db > backup.sqldocker exec -i displaydb psql -U postgres display_db < backup.sql- Add indexes for frequently queried fields
- Use Prisma's
selectto limit returned fields - Implement pagination for large result sets
- Cache frequently accessed data client-side