- 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.
101 lines
3.5 KiB
Markdown
101 lines
3.5 KiB
Markdown
# 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-032,Debezium 监听 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 端点 |
|