feat: add sections with plant positions to demo facility layout
Some checks are pending
Deploy to Production / deploy (push) Waiting to run
Test / backend-test (push) Waiting to run
Test / frontend-test (push) Waiting to run

- 22 sections (tables/racks) across all rooms
- Each section has grid positions for plants
- Proper sizing in pixels for canvas rendering
- Veg, Flower, Mother, Dry, Cure rooms all have layout data
This commit is contained in:
fullsizemalt 2025-12-12 21:41:33 -08:00
parent 15b50a74c6
commit b0cd3bdcf9

View file

@ -141,27 +141,28 @@ async function main() {
floors[`${f.buildingCode}-F${f.number}`] = floor; floors[`${f.buildingCode}-F${f.number}`] = floor;
} }
// Create Facility Rooms (mapped to grow rooms) // Create Facility Rooms with Sections (mapped to grow rooms)
const facilityRoomsData = [ const facilityRoomsData = [
{ floorKey: 'GROW1-F1', name: 'Veg Room 1', code: 'VEG-A', type: 'VEG', posX: 10, posY: 10, width: 40, height: 30 }, { floorKey: 'GROW1-F1', name: 'Veg Room 1', code: 'VEG-A', type: 'VEG', posX: 10, posY: 10, width: 800, height: 600 },
{ floorKey: 'GROW1-F1', name: 'Veg Room 2', code: 'VEG-B', type: 'VEG', posX: 55, posY: 10, width: 35, height: 25 }, { floorKey: 'GROW1-F1', name: 'Veg Room 2', code: 'VEG-B', type: 'VEG', posX: 850, posY: 10, width: 700, height: 500 },
{ floorKey: 'GROW1-F1', name: 'Mother Room', code: 'MTHR', type: 'MOTHER', posX: 10, posY: 45, width: 20, height: 20 }, { floorKey: 'GROW1-F1', name: 'Mother Room', code: 'MTHR', type: 'MOTHER', posX: 10, posY: 650, width: 400, height: 400 },
{ floorKey: 'GROW1-F2', name: 'Flower Room A', code: 'FLR-A', type: 'FLOWER', posX: 5, posY: 5, width: 45, height: 35 }, { floorKey: 'GROW1-F2', name: 'Flower Room A', code: 'FLR-A', type: 'FLOWER', posX: 50, posY: 50, width: 900, height: 700 },
{ floorKey: 'GROW1-F2', name: 'Flower Room B', code: 'FLR-B', type: 'FLOWER', posX: 52, posY: 5, width: 45, height: 35 }, { floorKey: 'GROW1-F2', name: 'Flower Room B', code: 'FLR-B', type: 'FLOWER', posX: 1000, posY: 50, width: 900, height: 700 },
{ floorKey: 'GROW1-F2', name: 'Flower Room C', code: 'FLR-C', type: 'FLOWER', posX: 5, posY: 42, width: 40, height: 30 }, { floorKey: 'GROW1-F2', name: 'Flower Room C', code: 'FLR-C', type: 'FLOWER', posX: 50, posY: 800, width: 800, height: 600 },
{ floorKey: 'PROC1-F1', name: 'Dry Room', code: 'DRY', type: 'DRY', posX: 5, posY: 5, width: 25, height: 30 }, { floorKey: 'PROC1-F1', name: 'Dry Room', code: 'DRY', type: 'DRY', posX: 50, posY: 50, width: 500, height: 600 },
{ floorKey: 'PROC1-F1', name: 'Cure Room', code: 'CURE', type: 'CURE', posX: 35, posY: 5, width: 20, height: 30 }, { floorKey: 'PROC1-F1', name: 'Cure Room', code: 'CURE', type: 'CURE', posX: 600, posY: 50, width: 400, height: 600 },
]; ];
const facilityRooms = {};
for (const fr of facilityRoomsData) { for (const fr of facilityRoomsData) {
const floorId = floors[fr.floorKey]?.id; const floorId = floors[fr.floorKey]?.id;
if (!floorId) continue; if (!floorId) continue;
const existing = await prisma.facilityRoom.findFirst({ let room = await prisma.facilityRoom.findFirst({
where: { code: fr.code, floorId } where: { code: fr.code, floorId }
}); });
if (!existing) { if (!room) {
await prisma.facilityRoom.create({ room = await prisma.facilityRoom.create({
data: { data: {
floorId, floorId,
name: fr.name, name: fr.name,
@ -174,9 +175,103 @@ async function main() {
} }
}); });
} }
facilityRooms[fr.code] = room;
} }
console.log(' ✓ 8 facility rooms mapped'); console.log(' ✓ 8 facility rooms mapped');
// Create Sections (Tables/Beds) with Plant Positions
console.log('\n🌿 Creating Grow Sections...');
const sectionsData = [
// Veg Room 1 - 4 tables, 4x4 each
{ roomCode: 'VEG-A', name: 'Table 1', code: 'T1', type: 'TABLE', posX: 50, posY: 50, width: 160, height: 320, rows: 4, columns: 4 },
{ roomCode: 'VEG-A', name: 'Table 2', code: 'T2', type: 'TABLE', posX: 230, posY: 50, width: 160, height: 320, rows: 4, columns: 4 },
{ roomCode: 'VEG-A', name: 'Table 3', code: 'T3', type: 'TABLE', posX: 410, posY: 50, width: 160, height: 320, rows: 4, columns: 4 },
{ roomCode: 'VEG-A', name: 'Table 4', code: 'T4', type: 'TABLE', posX: 590, posY: 50, width: 160, height: 320, rows: 4, columns: 4 },
// Flower Room A - 6 tables, 5x8 each (for flowering plants)
{ roomCode: 'FLR-A', name: 'Table A1', code: 'A1', type: 'TABLE', posX: 50, posY: 50, width: 200, height: 280, rows: 5, columns: 8 },
{ roomCode: 'FLR-A', name: 'Table A2', code: 'A2', type: 'TABLE', posX: 270, posY: 50, width: 200, height: 280, rows: 5, columns: 8 },
{ roomCode: 'FLR-A', name: 'Table A3', code: 'A3', type: 'TABLE', posX: 490, posY: 50, width: 200, height: 280, rows: 5, columns: 8 },
{ roomCode: 'FLR-A', name: 'Table A4', code: 'A4', type: 'TABLE', posX: 50, posY: 370, width: 200, height: 280, rows: 5, columns: 8 },
{ roomCode: 'FLR-A', name: 'Table A5', code: 'A5', type: 'TABLE', posX: 270, posY: 370, width: 200, height: 280, rows: 5, columns: 8 },
{ roomCode: 'FLR-A', name: 'Table A6', code: 'A6', type: 'TABLE', posX: 490, posY: 370, width: 200, height: 280, rows: 5, columns: 8 },
// Flower Room B - 6 tables
{ roomCode: 'FLR-B', name: 'Table B1', code: 'B1', type: 'TABLE', posX: 50, posY: 50, width: 200, height: 280, rows: 5, columns: 8 },
{ roomCode: 'FLR-B', name: 'Table B2', code: 'B2', type: 'TABLE', posX: 270, posY: 50, width: 200, height: 280, rows: 5, columns: 8 },
{ roomCode: 'FLR-B', name: 'Table B3', code: 'B3', type: 'TABLE', posX: 490, posY: 50, width: 200, height: 280, rows: 5, columns: 8 },
{ roomCode: 'FLR-B', name: 'Table B4', code: 'B4', type: 'TABLE', posX: 50, posY: 370, width: 200, height: 280, rows: 5, columns: 8 },
{ roomCode: 'FLR-B', name: 'Table B5', code: 'B5', type: 'TABLE', posX: 270, posY: 370, width: 200, height: 280, rows: 5, columns: 8 },
{ roomCode: 'FLR-B', name: 'Table B6', code: 'B6', type: 'TABLE', posX: 490, posY: 370, width: 200, height: 280, rows: 5, columns: 8 },
// Mother Room - 2 tables
{ roomCode: 'MTHR', name: 'Mother Table 1', code: 'M1', type: 'TABLE', posX: 50, posY: 50, width: 140, height: 280, rows: 4, columns: 3 },
{ roomCode: 'MTHR', name: 'Mother Table 2', code: 'M2', type: 'TABLE', posX: 220, posY: 50, width: 140, height: 280, rows: 4, columns: 3 },
// Dry Room - Drying racks
{ roomCode: 'DRY', name: 'Dry Rack 1', code: 'D1', type: 'RACK', posX: 50, posY: 50, width: 180, height: 240, rows: 6, columns: 4 },
{ roomCode: 'DRY', name: 'Dry Rack 2', code: 'D2', type: 'RACK', posX: 260, posY: 50, width: 180, height: 240, rows: 6, columns: 4 },
// Cure Room - Cure shelves
{ roomCode: 'CURE', name: 'Cure Shelf 1', code: 'C1', type: 'RACK', posX: 50, posY: 50, width: 140, height: 480, rows: 8, columns: 3 },
{ roomCode: 'CURE', name: 'Cure Shelf 2', code: 'C2', type: 'RACK', posX: 220, posY: 50, width: 140, height: 480, rows: 8, columns: 3 },
];
let sectionCount = 0;
let positionCount = 0;
for (const s of sectionsData) {
const room = facilityRooms[s.roomCode];
if (!room) continue;
let section = await prisma.facilitySection.findFirst({
where: { code: s.code, roomId: room.id }
});
if (!section) {
section = await prisma.facilitySection.create({
data: {
roomId: room.id,
name: s.name,
code: s.code,
type: s.type,
posX: s.posX,
posY: s.posY,
width: s.width,
height: s.height,
rows: s.rows,
columns: s.columns,
spacing: 12
}
});
sectionCount++;
// Create plant positions for this section
const cellWidth = Math.floor(s.width / s.columns);
const cellHeight = Math.floor(s.height / s.rows);
for (let row = 0; row < s.rows; row++) {
for (let col = 0; col < s.columns; col++) {
await prisma.facilityPosition.create({
data: {
sectionId: section.id,
row: row + 1,
column: col + 1,
posX: col * cellWidth + Math.floor(cellWidth / 2),
posY: row * cellHeight + Math.floor(cellHeight / 2),
status: 'EMPTY',
notes: null
}
});
positionCount++;
}
}
}
}
console.log(`${sectionCount} sections with ${positionCount} plant positions`);
// ==================== BATCHES ==================== // ==================== BATCHES ====================
console.log('\n🌱 Creating Batches...'); console.log('\n🌱 Creating Batches...');
const batchesData = [ const batchesData = [