[
  {
    "type": "create_table",
    "description": "Create fpFloorPlans table - store floor plan with SyncFusion canvas data",
    "database": "{{store}}",
    "check_query": "SHOW TABLES LIKE 'fpFloorPlans'",
    "sql": "CREATE TABLE `fpFloorPlans` (\n  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,\n  `name` VARCHAR(100) NOT NULL,\n  `description` TEXT NULL,\n  `canvasWidth` INT UNSIGNED NOT NULL DEFAULT 4000 COMMENT 'Canvas width in pixels',\n  `canvasHeight` INT UNSIGNED NOT NULL DEFAULT 3000 COMMENT 'Canvas height in pixels',\n  `gridSize` ENUM('small','medium','large') DEFAULT 'medium' COMMENT 'Preset size: small=40x30, medium=60x50, large=80x70',\n  `backgroundImageUrl` VARCHAR(255) NULL COMMENT 'Optional user-uploaded background image URL',\n  `backgroundOpacity` DECIMAL(3,2) NOT NULL DEFAULT 0.30 COMMENT '0.00-1.00',\n  `measurementUnit` ENUM('ft') NOT NULL DEFAULT 'ft',\n  `pixelsPerUnit` DECIMAL(10,4) NULL COMMENT 'Scale calibration (pixels per foot); NULL = uncalibrated',\n  `diagramData` LONGTEXT NULL COMMENT 'SyncFusion saveDiagram() JSON output',\n  `thumbnail` LONGTEXT NULL COMMENT 'Base64 encoded preview image',\n  `isActive` TINYINT(1) UNSIGNED DEFAULT 1,\n  `createdBy` INT UNSIGNED NULL COMMENT 'FK to kiosk_users.users.id (no FK constraint in store DB)',\n  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n  PRIMARY KEY (`id`),\n  INDEX `idx_isActive` (`isActive`),\n  INDEX `idx_createdBy` (`createdBy`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Store floor plan with SyncFusion canvas data'"
  },
  {
    "type": "create_table",
    "description": "Create fpRackTypes table - rack template library with all columns",
    "database": "{{store}}",
    "check_query": "SHOW TABLES LIKE 'fpRackTypes'",
    "sql": "CREATE TABLE `fpRackTypes` (\n  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,\n  `name` VARCHAR(50) NOT NULL COMMENT 'e.g., Rounder, 4-Pole H-Rack With Shoes',\n  `category` VARCHAR(50) NOT NULL COMMENT 'Combo, Endcap, Freestanding, Wall, Service',\n  `description` VARCHAR(255) NULL,\n  `defaultSocketCount` INT UNSIGNED DEFAULT 1,\n  `defaultSocketNames` LONGTEXT NULL COMMENT 'JSON array: [\"Left Pole\", \"Right Pole\"]',\n  `defaultSocketPositions` LONGTEXT NULL COMMENT 'JSON array of position objects for diagram layout',\n  `icon` VARCHAR(50) NULL COMMENT 'Font Awesome icon class',\n  `shape` ENUM('rectangle','circle','cross','custom') DEFAULT 'rectangle',\n  `defaultWidth` INT UNSIGNED DEFAULT 100 COMMENT 'Default width in pixels',\n  `defaultHeight` INT UNSIGNED DEFAULT 80 COMMENT 'Default height in pixels',\n  `widthFeet` DECIMAL(5,2) NULL COMMENT 'Width in feet',\n  `depthFeet` DECIMAL(5,2) NULL COMMENT 'Depth in feet',\n  `svgPath` TEXT NULL COMMENT 'Custom SVG path data for SyncFusion node',\n  `maintenanceIntervalDays` INT UNSIGNED DEFAULT 3 COMMENT 'Days between maintenance',\n  `isSystem` TINYINT(1) UNSIGNED DEFAULT 0 COMMENT '1=predefined, 0=custom',\n  `isActive` TINYINT(1) UNSIGNED DEFAULT 1,\n  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n  `defaultRackUnits` DECIMAL(5,2) NOT NULL DEFAULT 2.00 COMMENT 'Default rack capacity in abstract units for replenishment scoring',\n  PRIMARY KEY (`id`),\n  INDEX `idx_isActive` (`isActive`),\n  INDEX `idx_isSystem` (`isSystem`),\n  INDEX `idx_category` (`category`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Rack template library - predefined and custom'"
  },
  {
    "type": "create_table",
    "description": "Create fpRacks table - rack instances placed on floor plan",
    "database": "{{store}}",
    "check_query": "SHOW TABLES LIKE 'fpRacks'",
    "sql": "CREATE TABLE `fpRacks` (\n  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,\n  `floorPlanId` INT UNSIGNED NOT NULL COMMENT 'FK to fpFloorPlans',\n  `rackTypeId` INT UNSIGNED NOT NULL COMMENT 'FK to fpRackTypes',\n  `name` VARCHAR(50) NOT NULL COMMENT 'Unique rack label (auto R1, R2, ...)',\n  `syncfusionNodeId` VARCHAR(50) NOT NULL COMMENT 'SyncFusion diagram node ID',\n  `positionX` DECIMAL(10,2) NOT NULL DEFAULT 0 COMMENT 'X position on canvas',\n  `positionY` DECIMAL(10,2) NOT NULL DEFAULT 0 COMMENT 'Y position on canvas',\n  `width` INT UNSIGNED NOT NULL DEFAULT 100,\n  `height` INT UNSIGNED NOT NULL DEFAULT 80,\n  `rotation` FLOAT DEFAULT 0 COMMENT 'Rotation in degrees',\n  `zIndex` INT DEFAULT 0 COMMENT 'Layer order',\n  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n  PRIMARY KEY (`id`),\n  INDEX `idx_floorPlanId` (`floorPlanId`),\n  INDEX `idx_rackTypeId` (`rackTypeId`),\n  UNIQUE KEY `uk_syncfusionNodeId` (`floorPlanId`, `syncfusionNodeId`),\n  UNIQUE KEY `uk_floorPlan_rackName` (`floorPlanId`, `name`),\n  CONSTRAINT `fk_fpRacks_floorPlanId` FOREIGN KEY (`floorPlanId`) REFERENCES `fpFloorPlans`(`id`) ON DELETE CASCADE,\n  CONSTRAINT `fk_fpRacks_rackTypeId` FOREIGN KEY (`rackTypeId`) REFERENCES `fpRackTypes`(`id`) ON DELETE RESTRICT\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Rack instances placed on floor plan'"
  },
  {
    "type": "create_table",
    "description": "Create fpRackSockets table - individual sockets on each rack",
    "database": "{{store}}",
    "check_query": "SHOW TABLES LIKE 'fpRackSockets'",
    "sql": "CREATE TABLE `fpRackSockets` (\n  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,\n  `rackId` INT UNSIGNED NOT NULL COMMENT 'FK to fpRacks',\n  `name` VARCHAR(50) NOT NULL COMMENT 'e.g., Top Shelf, Shoe Display',\n  `sortOrder` INT UNSIGNED DEFAULT 0 COMMENT 'Display order within rack',\n  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n  PRIMARY KEY (`id`),\n  INDEX `idx_rackId` (`rackId`),\n  UNIQUE KEY `uk_rack_socket` (`rackId`, `name`),\n  CONSTRAINT `fk_fpRackSockets_rackId` FOREIGN KEY (`rackId`) REFERENCES `fpRacks`(`id`) ON DELETE CASCADE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Individual sockets on each rack for category assignment'"
  },
  {
    "type": "alter_table",
    "description": "Add defaultSocketPositions column to fpRackTypes if missing (for databases created from BLANK_STRUCTURE before this column existed)",
    "database": "{{store}}",
    "check_query": "SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'fpRackTypes' AND COLUMN_NAME = 'defaultSocketPositions'",
    "sql": "ALTER TABLE `fpRackTypes` ADD COLUMN `defaultSocketPositions` LONGTEXT NULL COMMENT 'JSON array of position objects for diagram layout' AFTER `defaultSocketNames`"
  },
  {
    "type": "insert",
    "description": "Seed all 30 system rack types - Combo, Freestanding, Wall, Endcap, Service fixtures",
    "database": "{{store}}",
    "check_query": "SELECT id FROM fpRackTypes WHERE isSystem = 1 LIMIT 1",
    "sql": "INSERT INTO `fpRackTypes` (`name`, `category`, `description`, `defaultSocketCount`, `defaultSocketNames`, `defaultSocketPositions`, `icon`, `shape`, `defaultWidth`, `defaultHeight`, `widthFeet`, `depthFeet`, `maintenanceIntervalDays`, `isSystem`, `isActive`, `defaultRackUnits`) VALUES\n('4-Pole H-Rack With Shoes', 'Combo', 'An H-Rack with two poles stacked vertically on each side. 4 Poles total. Shoes on Top', 5, '[\"Left Top Pole\",\"Left Bottom Pole\",\"Right Top Pole\",\"Right Bottom Pole\",\"Shoe Display\"]', '[{\"x\":0.20,\"y\":0.25,\"label\":\"Left Top\"},{\"x\":0.20,\"y\":0.65,\"label\":\"Left Bottom\"},{\"x\":0.80,\"y\":0.25,\"label\":\"Right Top\"},{\"x\":0.80,\"y\":0.65,\"label\":\"Right Bottom\"},{\"x\":0.50,\"y\":0.90,\"label\":\"Shoes\"}]', 'fa-grip-lines', 'rectangle', 180, 55, NULL, NULL, 3, 1, 1, 4.00),\n('4-Pole H-Rack Without Shoes', 'Combo', 'An H-Rack with two poles stacked vertically on each side. 4 Poles total.', 3, '[\"Left Side\",\"Right Side\",\"Top Rail\"]', '[{\"x\":0.20,\"y\":0.50,\"label\":\"Left\"},{\"x\":0.80,\"y\":0.50,\"label\":\"Right\"},{\"x\":0.50,\"y\":0.15,\"label\":\"Top Rail\"}]', 'fa-grip-lines', 'rectangle', 150, 55, NULL, NULL, 3, 1, 1, 4.00),\n('2-Pole H-Rack Without Shoes', 'Combo', 'An H-Rack with one pole on each side. 2 Poles total', 2, '[\"Left Pole\",\"Right Pole\"]', '[{\"x\":0.25,\"y\":0.50,\"label\":\"Left\"},{\"x\":0.75,\"y\":0.50,\"label\":\"Right\"}]', 'fa-grip-lines', 'rectangle', 100, 50, NULL, NULL, 3, 1, 1, 2.00),\n('Rounder - Single Category', 'Freestanding', 'Circular rack - single category focus', 1, '[\"Main\"]', '[{\"x\":0.50,\"y\":0.50,\"label\":\"Main\"}]', 'fa-circle', 'circle', 65, 65, NULL, NULL, 3, 1, 1, 2.00),\n('Rounder - Multiple Category', 'Freestanding', 'Circular rack - multiple category focus', 4, '[\"Front\",\"Right\",\"Back\",\"Left\"]', '[{\"x\":0.50,\"y\":0.15,\"label\":\"Front\"},{\"x\":0.85,\"y\":0.50,\"label\":\"Right\"},{\"x\":0.50,\"y\":0.85,\"label\":\"Back\"},{\"x\":0.15,\"y\":0.50,\"label\":\"Left\"}]', 'fa-arrows-spin', 'circle', 80, 80, NULL, NULL, 3, 1, 1, 4.00),\n('Four-Way Rack', 'Freestanding', 'Cross-shaped multi-directional rack', 4, '[\"North\",\"East\",\"South\",\"West\"]', '[{\"x\":0.50,\"y\":0.15,\"label\":\"North\"},{\"x\":0.85,\"y\":0.50,\"label\":\"East\"},{\"x\":0.50,\"y\":0.85,\"label\":\"South\"},{\"x\":0.15,\"y\":0.50,\"label\":\"West\"}]', 'fa-plus', 'cross', 90, 90, NULL, NULL, 3, 1, 1, 4.00),\n('Wall Rack 1-Pole', 'Wall', 'Standard rectangular wall unit with one single pole for longer items', 1, '[\"Main Pole\"]', '[{\"x\":0.50,\"y\":0.50,\"label\":\"Main\"}]', 'fa-ruler-horizontal', 'rectangle', 200, 30, NULL, NULL, 3, 1, 1, 1.00),\n('Wall Rack 2-Pole', 'Wall', 'Standard rectangular wall unit with 2 poles stacked vertically', 2, '[\"Top Pole\",\"Bottom Pole\"]', '[{\"x\":0.50,\"y\":0.30,\"label\":\"Top\"},{\"x\":0.50,\"y\":0.70,\"label\":\"Bottom\"}]', 'fa-ruler-horizontal', 'rectangle', 200, 35, NULL, NULL, 3, 1, 1, 2.00),\n('2-Pole H-Rack With Shoes', 'Combo', 'An H-Rack with one pole on each side. 2 Poles total. Shoes on top.', 3, '[\"Left Pole\",\"Right Pole\",\"Shoe Display\"]', '[{\"x\":0.25,\"y\":0.40,\"label\":\"Left\"},{\"x\":0.75,\"y\":0.40,\"label\":\"Right\"},{\"x\":0.50,\"y\":0.88,\"label\":\"Shoes\"}]', 'fa-layer-group', 'rectangle', 130, 55, NULL, NULL, 3, 1, 1, 2.00),\n('Cash Wrap', 'Service', 'Checkout counter - impulse items', 1, '[\"Counter Display\"]', '[{\"x\":0.50,\"y\":0.50,\"label\":\"Counter\"}]', 'fa-cash-register', 'rectangle', 180, 70, NULL, NULL, 7, 1, 1, 2.00),\n('Table Display', 'Service', 'Feature table for highlighted items', 1, '[\"Table Top\"]', '[{\"x\":0.50,\"y\":0.50,\"label\":\"Table Top\"}]', 'fa-table', 'rectangle', 120, 80, NULL, NULL, 3, 1, 1, 2.00),\n('Clearance Bin', 'Service', 'Sale/clearance items bin', 1, '[\"Bin\"]', '[{\"x\":0.50,\"y\":0.50,\"label\":\"Bin\"}]', 'fa-box-open', 'rectangle', 70, 70, NULL, NULL, 2, 1, 1, 2.00),\n('End Cap Shelves/Baskets', 'Endcap', 'An endcap with shelves or baskets displaying misc or accessories', 3, '[\"Top Shelf\",\"Middle Shelf\",\"Bottom Shelf\"]', '[{\"x\":0.50,\"y\":0.20,\"label\":\"Top\"},{\"x\":0.50,\"y\":0.50,\"label\":\"Middle\"},{\"x\":0.50,\"y\":0.80,\"label\":\"Bottom\"}]', 'fa-bars', 'rectangle', 80, 55, NULL, NULL, 3, 1, 1, 3.00),\n('End Cap Rounder', 'Endcap', 'An endcap with a round rack displaying hanged apparel', 1, '[\"Main\"]', '[{\"x\":0.50,\"y\":0.50,\"label\":\"Main\"}]', 'fa-circle-dot', 'circle', 65, 65, NULL, NULL, 3, 1, 1, 1.00),\n('End Cap Mannequin', 'Endcap', 'An endcap with mannequin display', 1, '[\"Mannequin\"]', '[{\"x\":0.50,\"y\":0.50,\"label\":\"Mannequin\"}]', 'fa-person', 'rectangle', 45, 45, NULL, NULL, 7, 1, 1, 0.00),\n('Feature Wall', 'Wall', 'Curated slatwall display with face-out shelves on top and hanging rails below for featured items across multiple categories', 3, '[\"Top Shelves\",\"Middle Display\",\"Bottom Rail\"]', '[{\"x\":0.50,\"y\":0.20,\"label\":\"Top Shelves\"},{\"x\":0.50,\"y\":0.50,\"label\":\"Middle Display\"},{\"x\":0.50,\"y\":0.80,\"label\":\"Bottom Rail\"}]', 'fa-star', 'rectangle', 220, 40, NULL, NULL, 5, 1, 1, 1.50),\n('2-Pole H-Rack With Accessories', 'Combo', 'An H-Rack with one pole on each side. 2 Poles total. Accessory shelving on top', 3, '[\"Left Pole\",\"Right Pole\",\"Accessory Shelf\"]', '[{\"x\":0.25,\"y\":0.40,\"label\":\"Left\"},{\"x\":0.75,\"y\":0.40,\"label\":\"Right\"},{\"x\":0.50,\"y\":0.88,\"label\":\"Accessories\"}]', 'fa-layer-group', 'rectangle', 130, 55, NULL, NULL, 3, 1, 1, 2.00),\n('4-Pole H-Rack With Accessories', 'Combo', 'An H-Rack with two poles stacked vertically on each side. 4 Poles total. Accessory shelving on top', 5, '[\"Left Top Pole\",\"Left Bottom Pole\",\"Right Top Pole\",\"Right Bottom Pole\",\"Accessory Shelf\"]', '[{\"x\":0.20,\"y\":0.25,\"label\":\"Left Top\"},{\"x\":0.20,\"y\":0.65,\"label\":\"Left Bottom\"},{\"x\":0.80,\"y\":0.25,\"label\":\"Right Top\"},{\"x\":0.80,\"y\":0.65,\"label\":\"Right Bottom\"},{\"x\":0.50,\"y\":0.90,\"label\":\"Accessories\"}]', 'fa-layer-group', 'rectangle', 180, 55, NULL, NULL, 3, 1, 1, 4.00),\n('2-Pole H-Rack With Double Shoes', 'Combo', 'An H-Rack with one pole on each side. 2 Poles total. 2 shoe racks stacked vertically on top', 4, '[\"Left Pole\",\"Right Pole\",\"Upper Shoe Rack\",\"Lower Shoe Rack\"]', '[{\"x\":0.25,\"y\":0.40,\"label\":\"Left\"},{\"x\":0.75,\"y\":0.40,\"label\":\"Right\"},{\"x\":0.50,\"y\":0.80,\"label\":\"Upper Shoes\"},{\"x\":0.50,\"y\":0.95,\"label\":\"Lower Shoes\"}]', 'fa-shoe-prints', 'rectangle', 130, 55, NULL, NULL, 3, 1, 1, 2.00),\n('End Cap Double Pole', 'Endcap', 'An endcap with 2 hanging poles stacked vertically', 2, '[\"Top Pole\",\"Bottom Pole\"]', '[{\"x\":0.50,\"y\":0.30,\"label\":\"Top\"},{\"x\":0.50,\"y\":0.70,\"label\":\"Bottom\"}]', 'fa-arrows-up-down', 'rectangle', 80, 55, NULL, NULL, 3, 1, 1, 2.00),\n('End Cap Accessories', 'Endcap', 'An endcap display for accessories with 2 display zones', 2, '[\"Top Display\",\"Bottom Display\"]', '[{\"x\":0.50,\"y\":0.30,\"label\":\"Top\"},{\"x\":0.50,\"y\":0.70,\"label\":\"Bottom\"}]', 'fa-gem', 'rectangle', 80, 55, NULL, NULL, 3, 1, 1, 1.50),\n('Pegboard Display', 'Freestanding', 'Freestanding grid/pegboard for individual accessories like jewelry', 1, '[\"Main Grid\"]', '[{\"x\":0.50,\"y\":0.50,\"label\":\"Main\"}]', 'fa-border-all', 'rectangle', 60, 40, NULL, NULL, 5, 1, 1, 1.00),\n('2-Shelf Unit', 'Freestanding', '2 shelves stacked vertically plus floor display below', 3, '[\"Top Shelf\",\"Bottom Shelf\",\"Floor\"]', '[{\"x\":0.50,\"y\":0.20,\"label\":\"Top\"},{\"x\":0.50,\"y\":0.55,\"label\":\"Bottom\"},{\"x\":0.50,\"y\":0.88,\"label\":\"Floor\"}]', 'fa-bars-staggered', 'rectangle', 100, 45, NULL, NULL, 3, 1, 1, 2.00),\n('3-Shelf Unit', 'Freestanding', '3 shelves stacked vertically plus floor display below', 4, '[\"Top Shelf\",\"Middle Shelf\",\"Bottom Shelf\",\"Floor\"]', '[{\"x\":0.50,\"y\":0.15,\"label\":\"Top\"},{\"x\":0.50,\"y\":0.40,\"label\":\"Middle\"},{\"x\":0.50,\"y\":0.65,\"label\":\"Bottom\"},{\"x\":0.50,\"y\":0.90,\"label\":\"Floor\"}]', 'fa-bars-staggered', 'rectangle', 100, 45, NULL, NULL, 3, 1, 1, 3.00),\n('Sunglass Spinner', 'Freestanding', 'Rotating display rack for sunglasses', 1, '[\"Main\"]', '[{\"x\":0.50,\"y\":0.50,\"label\":\"Main\"}]', 'fa-sun', 'circle', 50, 50, NULL, NULL, 7, 1, 1, 0.50),\n('Wall Grid Unit', 'Wall', 'Wall-mounted grid panel with hooks/poles for purses and accessories', 2, '[\"Top Section\",\"Bottom Section\"]', '[{\"x\":0.50,\"y\":0.30,\"label\":\"Top\"},{\"x\":0.50,\"y\":0.70,\"label\":\"Bottom\"}]', 'fa-grip-vertical', 'rectangle', 150, 35, NULL, NULL, 5, 1, 1, 1.50),\n('Rolling Grid - 2 Sided', 'Freestanding', 'Mobile grid display with 2 sides for accessories', 2, '[\"Side A\",\"Side B\"]', '[{\"x\":0.50,\"y\":0.25,\"label\":\"Side A\"},{\"x\":0.50,\"y\":0.75,\"label\":\"Side B\"}]', 'fa-table-cells', 'rectangle', 70, 35, NULL, NULL, 5, 1, 1, 1.50),\n('Rolling Grid - 3 Sided', 'Freestanding', 'Mobile triangular grid display with 3 sides for accessories', 3, '[\"Side A\",\"Side B\",\"Side C\"]', '[{\"x\":0.50,\"y\":0.15,\"label\":\"Side A\"},{\"x\":0.85,\"y\":0.75,\"label\":\"Side B\"},{\"x\":0.15,\"y\":0.75,\"label\":\"Side C\"}]', 'fa-table-cells', 'custom', 65, 65, NULL, NULL, 5, 1, 1, 2.00),\n('Rolling Grid - 4 Sided', 'Freestanding', 'Mobile grid display with 4 sides for accessories', 4, '[\"Side A\",\"Side B\",\"Side C\",\"Side D\"]', '[{\"x\":0.50,\"y\":0.15,\"label\":\"Side A\"},{\"x\":0.85,\"y\":0.50,\"label\":\"Side B\"},{\"x\":0.50,\"y\":0.85,\"label\":\"Side C\"},{\"x\":0.15,\"y\":0.50,\"label\":\"Side D\"}]', 'fa-table-cells', 'rectangle', 70, 70, NULL, NULL, 5, 1, 1, 2.50),\n('Custom Zone', 'Service', 'General-purpose zone for equipment, custom displays, or any other floor item', 1, '[\"Main\"]', '[{\"x\":0.50,\"y\":0.50,\"label\":\"Main\"}]', 'fa-vector-square', 'rectangle', 80, 80, NULL, NULL, 0, 1, 1, 0.00)"
  }
]
