-- Phase 1: companies, memberships, devices, report scoping. -- Idempotent on fresh DB; existing installs: prefer app auto-migration (Database::ensureRbacSchema). -- Manual run: mysql -u root -p androidcast_crashes < sql/migrations/001_rbac_companies.sql USE androidcast_crashes; CREATE TABLE IF NOT EXISTS companies ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, slug VARCHAR(64) NOT NULL, name VARCHAR(128) NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uq_companies_slug (slug) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS company_memberships ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, user_id INT UNSIGNED NOT NULL, company_id INT UNSIGNED NOT NULL, role ENUM('owner', 'admin', 'member') NOT NULL DEFAULT 'member', permissions_json LONGTEXT NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uq_membership_user_company (user_id, company_id), KEY idx_membership_company (company_id), CONSTRAINT fk_membership_user FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE, CONSTRAINT fk_membership_company FOREIGN KEY (company_id) REFERENCES companies (id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS devices ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, company_id INT UNSIGNED NOT NULL, external_id VARCHAR(128) NOT NULL, display_name VARCHAR(256) NULL, manufacturer VARCHAR(128) NULL, model VARCHAR(128) NULL, source ENUM('auto', 'manual', 'barcode') NOT NULL DEFAULT 'auto', registered_at_ms BIGINT NOT NULL, last_seen_at_ms BIGINT NOT NULL, meta_json LONGTEXT NULL, UNIQUE KEY uq_devices_company_external (company_id, external_id), KEY idx_devices_company (company_id), CONSTRAINT fk_devices_company FOREIGN KEY (company_id) REFERENCES companies (id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- reports.company_id / reports.device_id: run 002_reports_company_columns.sql as root (app user cannot ALTER) INSERT IGNORE INTO companies (id, slug, name) VALUES (1, 'default', 'Default');