# Facility Layout Designer & Plant Addressing System ## 🎯 Vision A Figma-like visual layout editor for designing facility layouts with precise plant addressing. Every plant gets a unique, hierarchical address that maps to physical location: ``` PROPERTY → BUILDING → ROOM → SECTION → ROW → COLUMN → POSITION ``` Example: `MAIN.GROW1.VEG-A.LEFT.R3.C5.P1` = Main Property, Grow Building 1, Veg Room A, Left Section, Row 3, Column 5, Position 1 --- ## 📐 Data Model ```prisma // Hierarchical Location Structure model Property { id String @id @default(uuid()) name String address String? licenseNum String? // DCC License Number buildings Building[] createdAt DateTime @default(now()) } model Building { id String @id @default(uuid()) property Property @relation(fields: [propertyId], references: [id]) propertyId String name String // "Grow Building 1", "Processing" code String // Short code: "GROW1" type String // CULTIVATION, PROCESSING, DRYING, STORAGE rooms Room[] layout Json? // Visual layout data (x, y, width, height) createdAt DateTime @default(now()) } model Room { id String @id @default(uuid()) building Building @relation(fields: [buildingId], references: [id]) buildingId String name String code String // "VEG-A" type String // VEG, FLOWER, CLONE, DRY, CURE, TRIM sections Section[] layout Json? // Position within building createdAt DateTime @default(now()) } model Section { id String @id @default(uuid()) room Room @relation(fields: [roomId], references: [id]) roomId String name String // "Left Side", "Center Aisle" code String // "LEFT", "CENTER" type String // FLOOR, TABLE, RACK, HANGER, TRAY rows Row[] layout Json? // Position within room, dimensions createdAt DateTime @default(now()) } model Row { id String @id @default(uuid()) section Section @relation(fields: [sectionId], references: [id]) sectionId String number Int // Row 1, 2, 3... positions Position[] layout Json? // Position within section } model Position { id String @id @default(uuid()) row Row @relation(fields: [rowId], references: [id]) rowId String column Int // Column number slot Int @default(1) // For multi-plant positions plant Plant? @relation(fields: [plantId], references: [id]) plantId String? @unique status String @default("EMPTY") // EMPTY, OCCUPIED, RESERVED, DAMAGED } model Plant { id String @id @default(uuid()) tagNumber String @unique // METRC tag batch Batch @relation(fields: [batchId], references: [id]) batchId String position Position? address String // Full hierarchical address status String // ACTIVE, HARVESTED, DESTROYED, TRANSFERRED history PlantLocationHistory[] createdAt DateTime @default(now()) } model PlantLocationHistory { id String @id @default(uuid()) plant Plant @relation(fields: [plantId], references: [id]) plantId String fromAddress String? toAddress String movedBy String // User ID movedAt DateTime @default(now()) reason String? // TRANSPLANT, REORGANIZE, HARVEST } ``` --- ## 🎨 Layout Editor UI ### Canvas Features (Figma-like) - **Drag & Drop** - Add rooms, sections, rows to canvas - **Resize Handles** - Adjust dimensions - **Grid Snap** - Align to grid - **Zoom & Pan** - Navigate large layouts - **Layers** - Show/hide different elements - **Templates** - Pre-built room layouts ### Element Types #### 1. Floor Plan Elements ``` ┌─────────────────────────────────────────────────────────┐ │ BUILDING: Grow 1 │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ VEG ROOM A │ │ VEG ROOM B │ │ │ │ ┌───┬───┬───┐ │ │ │ │ │ │ │ T1│ T2│ T3│ │ │ │ │ │ │ ├───┼───┼───┤ │ │ │ │ │ │ │ T4│ T5│ T6│ │ │ │ │ │ │ └───┴───┴───┘ │ │ │ │ │ └─────────────────┘ └─────────────────┘ │ │ ┌──────────────────────────────────────┐ │ │ │ FLOWER ROOM A │ │ │ │ [====] [====] [====] [====] │ 4 ft aisles │ │ │ [====] [====] [====] [====] │ │ │ │ [====] [====] [====] [====] │ │ │ └──────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ ``` #### 2. Grow Table/Bed (Grid-based) ``` ┌────────────────────────────────────────┐ │ TABLE T1 - VEG-A.LEFT.T1 │ │ Capacity: 6 rows × 8 columns = 48 │ │ ┌──┬──┬──┬──┬──┬──┬──┬──┐ │ │ │🌱│🌱│🌱│🌱│🌱│🌱│🌱│🌱│ R1 │ │ ├──┼──┼──┼──┼──┼──┼──┼──┤ │ │ │🌱│🌱│🌱│🌱│ │ │🌱│🌱│ R2 │ │ ├──┼──┼──┼──┼──┼──┼──┼──┤ │ │ │🌱│🌱│🌱│🌱│🌱│🌱│🌱│🌱│ R3 │ │ ├──┼──┼──┼──┼──┼──┼──┼──┤ │ │ │ │ │ │ │ │ │ │ │ R4 (empty) │ │ └──┴──┴──┴──┴──┴──┴──┴──┘ │ │ C1 C2 C3 C4 C5 C6 C7 C8 │ └────────────────────────────────────────┘ ``` #### 3. Drying Rack (Hanger-based) ``` ┌────────────────────────────────────────┐ │ DRY RACK 1 - DRY.MAIN.RACK1 │ │ Type: Vertical Hangers │ │ │ │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │ │ │H1│ │H2│ │H3│ │H4│ │H5│ │H6│ Level 1│ │ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ │ │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │ │ │H1│ │H2│ │H3│ │H4│ │H5│ │H6│ Level 2│ │ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ │ │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │ │ │H1│ │H2│ │H3│ │H4│ │H5│ │ │ Level 3│ │ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ │ └────────────────────────────────────────┘ ``` --- ## 🔧 API Endpoints ### Layout Management ``` POST /api/layout/property POST /api/layout/building POST /api/layout/room POST /api/layout/section POST /api/layout/row PUT /api/layout/:entityType/:id DELETE /api/layout/:entityType/:id GET /api/layout/property/:id/full # Full hierarchy GET /api/layout/room/:id/positions # All positions with status ``` ### Plant Placement ``` POST /api/plants Body: { tagNumber, batchId, positionId } POST /api/plants/:id/move Body: { toPositionId, reason } POST /api/plants/bulk-place Body: { batchId, positionIds[] } # Place batch into positions GET /api/plants/by-address/:address # Lookup by address string ``` ### Position Status ``` GET /api/positions/available Query: ?roomId=x&count=48 # Find 48 available positions POST /api/positions/reserve Body: { positionIds[], batchId, until } GET /api/rooms/:id/occupancy Returns: { total, occupied, empty, reserved } ``` --- ## 🎯 METRC Integration Requirements ### Address Format for METRC METRC requires precise location tracking. Our address format maps to: | Our Field | METRC Field | |-----------|-------------| | Property | License Premises | | Building | Area | | Room | Room | | Section + Row + Column | Location (free text) | ### Sync Strategy ``` 1. Plant created → Sync to METRC with location 2. Plant moved → Update METRC location 3. Plant harvested → Report harvest location 4. Audit → Generate location report matching METRC ``` --- ## 🖥️ Frontend Components ### 1. LayoutEditor (Canvas) ```tsx interface LayoutEditorProps { propertyId: string; mode: 'view' | 'edit'; onSave?: (layout: Layout) => void; } // Uses react-konva or @tldraw/tldraw for canvas ``` ### 2. RoomGrid (Position Grid) ```tsx interface RoomGridProps { roomId: string; onPositionClick?: (position: Position) => void; selectedBatch?: string; // Highlight batch plants } showPlantDetails(pos.plant)} /> ``` ### 3. PlantPlacer (Batch Placement Tool) ```tsx interface PlantPlacerProps { batchId: string; plantCount: number; onComplete: (placements: Placement[]) => void; } // Select multiple positions to place plants ``` ### 4. AddressLookup (Quick Find) ```tsx // Scan or type address to jump to location navigateToPlant(plant)} /> // Input: "MAIN.GROW1.VEG-A.LEFT.R3.C5" // Output: Highlights position, shows plant details ``` --- ## 📱 Mobile Flow 1. **Scan Plant Tag** → Shows current position + batch info 2. **Move Plant** → Scan new position QR → Confirm move 3. **Quick Place** → Scan batch → Scan position → Repeat 4. **Audit Walk** → Show expected vs actual by position --- ## 🗓️ Implementation Phases ### Phase 1: Data Model & API (1 week) - [ ] Create Prisma models - [ ] Migrate database - [ ] Build CRUD endpoints - [ ] Address generation logic ### Phase 2: Basic Layout Editor (2 weeks) - [ ] Canvas with react-konva - [ ] Add/edit rooms, sections - [ ] Grid generator for positions - [ ] Save/load layouts ### Phase 3: Plant Placement (1 week) - [ ] Place plants in positions - [ ] Move plants (with history) - [ ] Bulk placement tool - [ ] Position reservation ### Phase 4: Visualization (1 week) - [ ] Room grid view - [ ] Color coding (by batch, stage, health) - [ ] Occupancy heatmaps - [ ] Print floor plans ### Phase 5: METRC Sync (2 weeks) - [ ] Location format mapping - [ ] Sync on plant create/move - [ ] Audit report generation - [ ] Discrepancy detection --- ## 📦 Tech Stack | Component | Technology | |-----------|------------| | Canvas Editor | `react-konva` or `@tldraw/tldraw` | | Grid Display | Custom React + CSS Grid | | Address Parser | Regex + validation | | QR Codes | `qrcode.react` | | Mobile Scan | `@zxing/browser` | | State Mgmt | Zustand (for editor state) | --- ## 🎨 Example Layouts ### Vegetative Room - Tables ```json { "type": "ROOM", "code": "VEG-A", "layout": { "width": 40, // feet "height": 30, "sections": [ { "code": "LEFT", "type": "TABLE", "x": 0, "y": 0, "rows": 6, "columns": 8, "spacing": 12 // inches between plants }, { "code": "RIGHT", "type": "TABLE", "x": 20, "y": 0, "rows": 6, "columns": 8 } ], "aisles": [ { "x": 18, "y": 0, "width": 4, "height": 30 } ] } } ``` ### Drying Room - Racks ```json { "type": "ROOM", "code": "DRY-A", "layout": { "width": 20, "height": 30, "sections": [ { "code": "RACK1", "type": "HANGER", "x": 0, "y": 0, "levels": 4, "hangersPerLevel": 20 }, { "code": "RACK2", "type": "HANGER", "x": 10, "y": 0, "levels": 4, "hangersPerLevel": 20 } ] } } ``` --- ## ✅ Deliverables 1. **Prisma schema** with full hierarchy 2. **API endpoints** for CRUD + plant placement 3. **Layout Editor** component (Figma-like) 4. **Room Grid Viewer** with plant status 5. **Mobile placement flow** with scanning 6. **METRC-compatible address format** 7. **Audit reports** by location