feat(config-service): split config-service from iam for plugin/layout config

- new NestJS service on port 3011/gRPC 50059 (ADR-026)
- owns 6 config_ tables (plugin/role-mapping/role-layout/layout-tpl/user-override/outbox)
- GraphQL Federation 2 subgraph with DataLoader + RouterAuthGuard
- gRPC ConfigService + admin REST CRUD + user REST API
- three-layer merge: registry.defaultProps + roleMapping.widget_props + userOverride.props
- Redis cache with 5min TTL
- registered in apollo-router supergraph + docker-compose + port-allocation

Implements M3 of v2.1 migration plan.
This commit is contained in:
SpecialX
2026-07-15 02:13:03 +08:00
parent 163bff6666
commit 1a5fa78fa6
44 changed files with 3538 additions and 33 deletions

View File

@@ -733,3 +733,84 @@ CREATE TABLE IF NOT EXISTS `msg_announcement_reads` (
UNIQUE KEY `uniq_announcement_user` (`announcement_id`, `user_id`),
INDEX `idx_msg_announcement_reads_user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================================
-- 6. Config 服务services/config-service/src/config-config/config.schema.ts
-- v2.1 M3 / ADR-026从 iam 拆分出插件配置 + 布局 + 用户偏好职责
-- ============================================================
-- 6.1 插件注册表系统级admin 维护;内置插件由构建脚本同步)
CREATE TABLE IF NOT EXISTS `config_plugin_registry` (
`plugin_id` VARCHAR(100) NOT NULL,
`category` VARCHAR(50) NOT NULL,
`version` VARCHAR(50) NULL,
`display_name` VARCHAR(200) NOT NULL,
`description` TEXT NULL,
`required_roles` JSON NULL,
`default_slot` VARCHAR(50) NULL,
`default_size` JSON NULL,
`default_props` JSON NULL,
`props_schema` JSON NULL,
`is_builtin` BOOLEAN NOT NULL DEFAULT TRUE,
`is_active` BOOLEAN NOT NULL DEFAULT TRUE,
`package_url` TEXT NULL,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`plugin_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 6.2 角色-插件映射admin 配置角色可用插件集 + 角色 Layout 默认)
CREATE TABLE IF NOT EXISTS `config_role_plugin_mapping` (
`role` VARCHAR(50) NOT NULL,
`plugin_id` VARCHAR(100) NOT NULL,
`slot` VARCHAR(50) NULL,
`sort_order` INT NOT NULL DEFAULT 0,
`is_enabled` BOOLEAN NOT NULL DEFAULT TRUE,
`widget_props` JSON NULL,
INDEX `idx_config_role_plugin_pk` (`role`, `plugin_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 6.3 角色 Layout 默认admin 配置角色默认模板)
CREATE TABLE IF NOT EXISTS `config_role_layout_default` (
`role` VARCHAR(50) NOT NULL,
`layout_id` VARCHAR(50) NOT NULL,
`slot_overrides` JSON NULL,
PRIMARY KEY (`role`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 6.4 Layout 模板(系统预置 5 种不可改classic/focus/split/triple/canvas
CREATE TABLE IF NOT EXISTS `config_layout_templates` (
`layout_id` VARCHAR(50) NOT NULL,
`display_name` VARCHAR(200) NOT NULL,
`description` TEXT NULL,
`available_slots` JSON NULL,
`layout_schema` JSON NULL,
`is_active` BOOLEAN NOT NULL DEFAULT TRUE,
PRIMARY KEY (`layout_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 6.5 用户布局覆盖(用户自定义)
CREATE TABLE IF NOT EXISTS `config_user_layout_override` (
`user_id` VARCHAR(36) NOT NULL,
`active_layout` VARCHAR(50) NULL,
`slot_overrides` JSON NULL,
`plugin_placements` JSON NULL,
`hidden_plugins` JSON NULL,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 6.6 Config Outbox 表v2.1 ADR-032业务写 outboxDebezium 监听 binlog 投递 Kafka
CREATE TABLE IF NOT EXISTS `config_outbox` (
`event_id` CHAR(36) NOT NULL,
`aggregate_type` VARCHAR(50) NOT NULL,
`aggregate_id` VARCHAR(100) NOT NULL,
`event_type` VARCHAR(100) NOT NULL,
`payload` JSON NOT NULL,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`published_at` TIMESTAMP NULL,
`retry_count` INT NOT NULL DEFAULT 0,
`next_retry_at` TIMESTAMP NULL,
PRIMARY KEY (`event_id`),
INDEX `idx_outbox_unpublished` (`published_at`, `next_retry_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;