- 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.
120 lines
3.0 KiB
Protocol Buffer
120 lines
3.0 KiB
Protocol Buffer
syntax = "proto3";
|
||
|
||
package next_edu_cloud.config.v1;
|
||
|
||
import "google/protobuf/empty.proto";
|
||
|
||
// ConfigService 定义插件配置 + 布局 + 用户偏好契约(ADR-026)。
|
||
// 从 iam 服务拆分而来,避免 iam 成为"上帝服务"。
|
||
//
|
||
// 双入口策略(president §2.16):
|
||
// - REST 供 gateway 透传 + portal 直连
|
||
// - gRPC 供 BFF / portal-shell 聚合调用
|
||
//
|
||
// gRPC 端口 50059(v2.1 M3)。
|
||
service ConfigService {
|
||
// 获取用户合并后的插件配置(三层合并)
|
||
rpc GetPluginConfig(GetPluginConfigRequest) returns (PluginConfigResponse);
|
||
// 列出插件注册表
|
||
rpc ListPlugins(ListPluginsRequest) returns (ListPluginsResponse);
|
||
// 获取所有 Layout 模板(5 种内置)
|
||
rpc GetLayoutTemplates(google.protobuf.Empty) returns (LayoutTemplatesResponse);
|
||
// 获取用户布局覆盖
|
||
rpc GetUserLayoutOverride(GetUserLayoutOverrideRequest) returns (UserLayoutOverride);
|
||
// 更新或创建用户布局覆盖
|
||
rpc UpsertUserLayoutOverride(UpsertUserLayoutOverrideRequest) returns (UserLayoutOverride);
|
||
// 重置用户布局覆盖(恢复角色默认)
|
||
rpc ResetUserLayoutOverride(ResetUserLayoutOverrideRequest) returns (ResetResponse);
|
||
}
|
||
|
||
// ========== 请求 / 响应 ==========
|
||
|
||
message GetPluginConfigRequest {
|
||
string user_id = 1;
|
||
string user_role = 2;
|
||
}
|
||
|
||
message ListPluginsRequest {
|
||
string category = 1;
|
||
bool is_active = 2;
|
||
}
|
||
|
||
message ListPluginsResponse {
|
||
repeated PluginRegistryItem plugins = 1;
|
||
}
|
||
|
||
message GetUserLayoutOverrideRequest {
|
||
string user_id = 1;
|
||
}
|
||
|
||
message UpsertUserLayoutOverrideRequest {
|
||
string user_id = 1;
|
||
string active_layout = 2;
|
||
string slot_overrides_json = 3;
|
||
string plugin_placements_json = 4;
|
||
string hidden_plugins_json = 5;
|
||
}
|
||
|
||
message ResetUserLayoutOverrideRequest {
|
||
string user_id = 1;
|
||
}
|
||
|
||
message ResetResponse {
|
||
bool success = 1;
|
||
}
|
||
|
||
message LayoutTemplatesResponse {
|
||
repeated LayoutTemplate templates = 1;
|
||
}
|
||
|
||
// ========== 业务实体 ==========
|
||
|
||
message PluginConfigResponse {
|
||
LayoutTemplate active_layout = 1;
|
||
repeated SlotConfig slots = 2;
|
||
repeated PluginPlacement plugins = 3;
|
||
repeated PluginRegistryItem registry = 4;
|
||
}
|
||
|
||
message LayoutTemplate {
|
||
string layout_id = 1;
|
||
string display_name = 2;
|
||
string description = 3;
|
||
repeated string available_slots = 4;
|
||
string layout_schema_json = 5;
|
||
}
|
||
|
||
message SlotConfig {
|
||
string slot_name = 1;
|
||
repeated string nav_items = 2;
|
||
}
|
||
|
||
message PluginPlacement {
|
||
string plugin_id = 1;
|
||
string slot = 2;
|
||
int32 sort_order = 3;
|
||
string size_json = 4;
|
||
string props_json = 5;
|
||
bool is_visible = 6;
|
||
}
|
||
|
||
message PluginRegistryItem {
|
||
string plugin_id = 1;
|
||
string category = 2;
|
||
string version = 3;
|
||
string display_name = 4;
|
||
string description = 5;
|
||
repeated string required_roles = 6;
|
||
bool is_builtin = 7;
|
||
bool is_active = 8;
|
||
}
|
||
|
||
message UserLayoutOverride {
|
||
string user_id = 1;
|
||
string active_layout = 2;
|
||
string slot_overrides_json = 3;
|
||
string plugin_placements_json = 4;
|
||
repeated string hidden_plugins = 5;
|
||
string updated_at = 6;
|
||
}
|