createTable('menu'); $menu->addColumn('id', 'string', ['length' => 64]); $menu->addColumn('website_id', 'string', ['length' => 64]); $menu->addColumn('locale', 'string', ['length' => 12]); // One menu per slot and locale; the slot is what a template asks for. $menu->addColumn('slot', 'string', ['length' => 32]); $menu->addColumn('name', 'string', ['length' => 120]); $menu->addColumn('items', 'json'); // Optimistic locking, same contract as pages: a stale form must not overwrite newer items. $menu->addColumn('version', 'integer', ['default' => 0]); $menu->setPrimaryKey(['id']); $menu->addUniqueIndex(['website_id', 'locale', 'slot'], 'uniq_menu_slot'); } public function down(Schema $schema): void { $this->throwIrreversibleMigrationException('Contains the site navigation. Restore a verified database backup with matching code.'); } }