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

@@ -0,0 +1,100 @@
# config-service
> v2.1 M3 / ADR-026从 iam 拆分插件配置 + 布局 + 用户偏好职责
## 端口
- HTTP: 3011
- gRPC: 50059
## 职责
config-service 负责插件化仪表盘的后端配置管理portal-shell spec §6
1. **插件注册表**`config_plugin_registry`):系统级插件元数据
2. **角色-插件映射**`config_role_plugin_mapping`):角色可用插件集
3. **角色 Layout 默认**`config_role_layout_default`):角色默认布局模板
4. **Layout 模板**`config_layout_templates`5 种内置模板
5. **用户布局覆盖**`config_user_layout_override`):用户自定义
6. **Outbox**`config_outbox`v2.1 ADR-032Debezium 监听 binlog
## 不涉及
- DataScope仍归 iam
- 认证 / JWT仍归 iam
- 权限点 DB 查询(简化为角色判断)
## 架构
```
HTTP 3011 ─┬─ /v1/config/plugin-config (用户三层合并)
├─ /v1/config/layout-templates (用户列模板)
├─ /v1/config/user-layout (用户更新布局)
├─ /v1/config/admin/* (admin CRUD)
├─ /healthz, /readyz (健康检查)
├─ /metrics (Prometheus)
└─ /graphql (Federation 子图)
gRPC 50059 ── ConfigService (BFF 聚合调用)
```
## 三层合并算法
`getPluginConfig(userId, userRole)` 的合并逻辑portal-shell spec §6.4
1.`config_plugin_registry WHERE is_active=TRUE`
2.`config_role_plugin_mapping WHERE role=:userRole`
3.`config_user_layout_override WHERE user_id=:userId`
4. 对每个 plugin
- `finalProps = merge(registry.default_props, roleMapping.widget_props, userPlacement.props)`
- `finalSlot = userPlacement.slot ?? roleMapping.slot ?? registry.default_slot`
- `isVisible = !hidden.includes(pluginId) && (roleMapping.is_enabled ?? true) && registry.is_active`
## 缓存
Redis 缓存TTL 5min
- `config:plugin:{pluginId}` — 插件注册表项
- `config:user-layout:{userId}` — 用户布局覆盖
失效策略admin 修改配置或用户更新布局时主动 del。
## 事件
v2.1 ADR-032业务写 `config_outbox`Debezium 监听 binlog 投递到 Kafka。
事件命名:`<Aggregate>.<Action>`
- `PluginRegistry.updated`
- `RolePluginMapping.updated`
- `RoleLayoutDefault.updated`
- `UserLayoutOverride.upserted` / `UserLayoutOverride.reset`
## 开发
```bash
# 安装依赖
pnpm install
# 类型检查
pnpm --filter @edu/config-service run typecheck
# Lint
pnpm --filter @edu/config-service run lint
# 开发模式
pnpm --filter @edu/config-service run dev
```
## 环境变量
| 变量 | 默认值 | 说明 |
| --------------------------- | ----------------- | ------------------------ |
| PORT | 3011 | HTTP 端口 |
| GRPC_PORT | 50059 | gRPC 端口 |
| DATABASE_URL | — | MySQL 连接串 |
| REDIS_URL | — | Redis 连接串 |
| KAFKA_BROKERS | — | Kafka broker 列表 |
| ROUTER_AUTH_SECRET | dev-router-secret | Apollo Router 信任凭证 |
| DEV_MODE | false | 开发模式(放行权限校验) |
| OTEL_EXPORTER_OTLP_ENDPOINT | — | OTLP exporter 端点 |