muyu-apiserver/deploy/mysql/migrations/20260329_add_tenant_id_to_legacy.sql
Chever John 1f4ccfb54e feat: multi-tenant CRM with PostgreSQL graph, tenant isolation, and Casbin RBAC
- JWT claims extended with tenantId; login enforces strict tenant verification
- AuthorityMiddleware: tenant scope check + Casbin path permission + anti-spoofing
- CRM relation API (upstream/downstream one-hop, create/update/history, full graph)
- CrmRepo backed by PostgreSQL with $N placeholders
- gRPC tenant propagation via UnaryClientInterceptor (x-tenant-id metadata)
- All legacy tables (12) gain tenant_id column with indexes
- All model queries inject WHERE tenant_id filter
- Casbin gorm-adapter downgraded to v3.28.0 for v2 compatibility
- GraphSyncWorker (Kafka -> Neo4j) with idempotent MERGE
- Full graph API restricted to admin role only
- Database migrations for MySQL (CRM tables + tenant columns) and PostgreSQL (CRM init)
- Docker Compose: added postgres service to main stack, graph stack with Kafka/Debezium/Neo4j

Made-with: Cursor
2026-03-30 02:53:55 +00:00

94 lines
5.8 KiB
SQL

-- Migration: Add tenant_id to all legacy tables
-- Safe to re-run: uses column existence checks via PREPARE/EXECUTE
USE `muyu_wms`;
-- Helper: add tenant_id column if not exists
-- Repeated for each table because MySQL 8 lacks ADD COLUMN IF NOT EXISTS.
-- sys_user
SET @t = 'sys_user';
SET @c = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME=@t AND COLUMN_NAME='tenant_id');
SET @s = IF(@c=0, CONCAT('ALTER TABLE `',@t,'` ADD COLUMN `tenant_id` VARCHAR(32) NOT NULL DEFAULT \'t_default_001\' AFTER `id`'), 'SELECT 1');
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- sys_role
SET @t = 'sys_role';
SET @c = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME=@t AND COLUMN_NAME='tenant_id');
SET @s = IF(@c=0, CONCAT('ALTER TABLE `',@t,'` ADD COLUMN `tenant_id` VARCHAR(32) NOT NULL DEFAULT \'t_default_001\' AFTER `id`'), 'SELECT 1');
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- sys_user_role
SET @t = 'sys_user_role';
SET @c = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME=@t AND COLUMN_NAME='tenant_id');
SET @s = IF(@c=0, CONCAT('ALTER TABLE `',@t,'` ADD COLUMN `tenant_id` VARCHAR(32) NOT NULL DEFAULT \'t_default_001\' AFTER `id`'), 'SELECT 1');
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- sys_menu
SET @t = 'sys_menu';
SET @c = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME=@t AND COLUMN_NAME='tenant_id');
SET @s = IF(@c=0, CONCAT('ALTER TABLE `',@t,'` ADD COLUMN `tenant_id` VARCHAR(32) NOT NULL DEFAULT \'t_default_001\' AFTER `id`'), 'SELECT 1');
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- sys_role_menu
SET @t = 'sys_role_menu';
SET @c = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME=@t AND COLUMN_NAME='tenant_id');
SET @s = IF(@c=0, CONCAT('ALTER TABLE `',@t,'` ADD COLUMN `tenant_id` VARCHAR(32) NOT NULL DEFAULT \'t_default_001\' AFTER `id`'), 'SELECT 1');
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- sys_config
SET @t = 'sys_config';
SET @c = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME=@t AND COLUMN_NAME='tenant_id');
SET @s = IF(@c=0, CONCAT('ALTER TABLE `',@t,'` ADD COLUMN `tenant_id` VARCHAR(32) NOT NULL DEFAULT \'t_default_001\' AFTER `id`'), 'SELECT 1');
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- inv_product
SET @t = 'inv_product';
SET @c = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME=@t AND COLUMN_NAME='tenant_id');
SET @s = IF(@c=0, CONCAT('ALTER TABLE `',@t,'` ADD COLUMN `tenant_id` VARCHAR(32) NOT NULL DEFAULT \'t_default_001\' AFTER `id`'), 'SELECT 1');
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- inv_stock_check
SET @t = 'inv_stock_check';
SET @c = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME=@t AND COLUMN_NAME='tenant_id');
SET @s = IF(@c=0, CONCAT('ALTER TABLE `',@t,'` ADD COLUMN `tenant_id` VARCHAR(32) NOT NULL DEFAULT \'t_default_001\' AFTER `id`'), 'SELECT 1');
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- inv_stock_check_detail
SET @t = 'inv_stock_check_detail';
SET @c = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME=@t AND COLUMN_NAME='tenant_id');
SET @s = IF(@c=0, CONCAT('ALTER TABLE `',@t,'` ADD COLUMN `tenant_id` VARCHAR(32) NOT NULL DEFAULT \'t_default_001\' AFTER `id`'), 'SELECT 1');
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- inv_stock_adjust
SET @t = 'inv_stock_adjust';
SET @c = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME=@t AND COLUMN_NAME='tenant_id');
SET @s = IF(@c=0, CONCAT('ALTER TABLE `',@t,'` ADD COLUMN `tenant_id` VARCHAR(32) NOT NULL DEFAULT \'t_default_001\' AFTER `id`'), 'SELECT 1');
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- inv_stock_adjust_detail
SET @t = 'inv_stock_adjust_detail';
SET @c = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME=@t AND COLUMN_NAME='tenant_id');
SET @s = IF(@c=0, CONCAT('ALTER TABLE `',@t,'` ADD COLUMN `tenant_id` VARCHAR(32) NOT NULL DEFAULT \'t_default_001\' AFTER `id`'), 'SELECT 1');
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- inv_stock_import_log
SET @t = 'inv_stock_import_log';
SET @c = (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='muyu_wms' AND TABLE_NAME=@t AND COLUMN_NAME='tenant_id');
SET @s = IF(@c=0, CONCAT('ALTER TABLE `',@t,'` ADD COLUMN `tenant_id` VARCHAR(32) NOT NULL DEFAULT \'t_default_001\' AFTER `id`'), 'SELECT 1');
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- Add indexes for tenant_id on all tables
CREATE INDEX IF NOT EXISTS idx_sys_user_tenant ON sys_user(tenant_id);
CREATE INDEX IF NOT EXISTS idx_sys_role_tenant ON sys_role(tenant_id);
CREATE INDEX IF NOT EXISTS idx_sys_user_role_tenant ON sys_user_role(tenant_id);
CREATE INDEX IF NOT EXISTS idx_sys_menu_tenant ON sys_menu(tenant_id);
CREATE INDEX IF NOT EXISTS idx_sys_role_menu_tenant ON sys_role_menu(tenant_id);
CREATE INDEX IF NOT EXISTS idx_sys_config_tenant ON sys_config(tenant_id);
CREATE INDEX IF NOT EXISTS idx_inv_product_tenant ON inv_product(tenant_id);
CREATE INDEX IF NOT EXISTS idx_inv_stock_check_tenant ON inv_stock_check(tenant_id);
CREATE INDEX IF NOT EXISTS idx_inv_stock_check_detail_tenant ON inv_stock_check_detail(tenant_id);
CREATE INDEX IF NOT EXISTS idx_inv_stock_adjust_tenant ON inv_stock_adjust(tenant_id);
CREATE INDEX IF NOT EXISTS idx_inv_stock_adjust_detail_tenant ON inv_stock_adjust_detail(tenant_id);
CREATE INDEX IF NOT EXISTS idx_inv_stock_import_log_tenant ON inv_stock_import_log(tenant_id);