feat: complete house plan maker application

Full-featured house/apartment floor plan editor with:

- Turborepo monorepo (React/Vite client, Fastify/Prisma server, shared Zod schemas)
- 2D room editor with walls, doors, windows, furniture, electrical elements
- 3D room preview with Three.js (auto-hide nearest walls, bird's eye default)
- Wall projection views with interactive drag (elevation, position)
- Apartment floor plan view with room positioning
- Copy/paste, alignment tools, measurement tool, annotations
- Item-attached annotations with leader lines (visible on projections)
- Door open direction (LEFT/RIGHT/INWARD/OUTWARD) with swing arc
- Floor type textures (wood, tile, concrete, laminate, herringbone)
- Wall color picker for 3D view
- Furniture: bed, desk, wardrobe, sofa, table, chair, shelf, nightstand, dresser, bookcase, TV (with stand toggle), AC unit
- Furniture elevation support (wall-mounted items)
- Auto-save with dirty state tracking, batch save API
- Rotation-aware collision detection (SAT/OBB) with 3D elevation check
- Rotation-aware hit testing
- i18n (English/Russian) with locale-aware number formatting
- Dark mode with system preference detection
- Undo/redo, keyboard shortcuts, scale bar
- PDF/PNG/JSON export and JSON import
- Focus trap modal, toast notifications, tooltips
- Responsive layout with overlay palettes
This commit is contained in:
2026-04-05 22:34:03 +03:00
parent b84807bbdb
commit af8b9fe00f
188 changed files with 35795 additions and 0 deletions
+108
View File
@@ -0,0 +1,108 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model Apartment {
id String @id @default(cuid())
name String
address String?
totalArea Float?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
rooms Room[]
}
model Room {
id String @id @default(cuid())
apartmentId String
name String
shape String @default("[]") // JSON array of {x, y} points
width Float?
height Float?
wallHeight Float @default(2.7)
plinthHeight Float @default(0.06)
plinthThickness Float @default(0.01)
order Int @default(0)
posX Float @default(0)
posY Float @default(0)
floorType String @default("CONCRETE")
wallColor String @default("#f5f0eb")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
apartment Apartment @relation(fields: [apartmentId], references: [id], onDelete: Cascade)
walls Wall[]
openings WallOpening[]
electricalItems ElectricalItem[]
furnitureItems FurnitureItem[]
@@index([apartmentId])
}
model Wall {
id String @id @default(cuid())
roomId String
startX Float
startY Float
endX Float
endY Float
thickness Float @default(0.1)
direction String @default("OTHER") // NORTH, SOUTH, EAST, WEST, OTHER
room Room @relation(fields: [roomId], references: [id], onDelete: Cascade)
openings WallOpening[]
@@index([roomId])
}
model WallOpening {
id String @id @default(cuid())
roomId String
wallId String
type String // DOOR, WINDOW
positionAlongWall Float
width Float
height Float
elevationFromFloor Float @default(0)
openDirection String @default("LEFT") // LEFT, RIGHT, INWARD, OUTWARD
room Room @relation(fields: [roomId], references: [id], onDelete: Cascade)
wall Wall @relation(fields: [wallId], references: [id], onDelete: Cascade)
@@index([roomId])
@@index([wallId])
}
model ElectricalItem {
id String @id @default(cuid())
roomId String
type String // OUTLET, SWITCH, JUNCTION_BOX, LIGHT_CEILING, LIGHT_WALL, CABLE_ROUTE
x Float
y Float
wallId String?
elevationFromFloor Float?
rotation Float @default(0)
metadata String? // JSON
room Room @relation(fields: [roomId], references: [id], onDelete: Cascade)
@@index([roomId])
}
model FurnitureItem {
id String @id @default(cuid())
roomId String
type String // BED, DESK, WARDROBE, SOFA, TABLE, CHAIR, SHELF, NIGHTSTAND, DRESSER, BOOKCASE, OTHER
x Float
y Float
width Float
depth Float
height Float
rotation Float @default(0)
elevationFromFloor Float @default(0)
label String?
room Room @relation(fields: [roomId], references: [id], onDelete: Cascade)
@@index([roomId])
}