feat(portal): add logical group guidance config

This commit is contained in:
phamnazage-jpg
2026-05-30 10:38:59 +08:00
parent e940ebda2c
commit 3bfd4cfc1c
10 changed files with 144 additions and 11 deletions

View File

@@ -21,6 +21,9 @@ type LogicalGroup struct {
DisplayName string
Status string
Description string
UsageScenario string
Recommendation string
NextStepHint string
RoutePolicy string
StickyMode string
ConversationTTLSeconds int
@@ -52,17 +55,23 @@ func (r *LogicalGroupsRepo) Create(ctx context.Context, group LogicalGroup) (int
display_name,
status,
description,
usage_scenario,
recommendation,
next_step_hint,
route_policy,
sticky_mode,
conversation_ttl_seconds,
user_model_ttl_seconds,
failover_threshold,
cooldown_seconds
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
group.LogicalGroupID,
group.DisplayName,
group.Status,
group.Description,
group.UsageScenario,
group.Recommendation,
group.NextStepHint,
group.RoutePolicy,
group.StickyMode,
group.ConversationTTLSeconds,
@@ -90,7 +99,7 @@ func (r *LogicalGroupsRepo) GetByLogicalGroupID(ctx context.Context, logicalGrou
var group LogicalGroup
if err := r.db.QueryRowContext(
ctx,
`SELECT id, logical_group_id, display_name, status, description, route_policy, sticky_mode, conversation_ttl_seconds, user_model_ttl_seconds, failover_threshold, cooldown_seconds, created_at, updated_at
`SELECT id, logical_group_id, display_name, status, description, usage_scenario, recommendation, next_step_hint, route_policy, sticky_mode, conversation_ttl_seconds, user_model_ttl_seconds, failover_threshold, cooldown_seconds, created_at, updated_at
FROM logical_groups
WHERE logical_group_id = ?`,
logicalGroupID,
@@ -100,6 +109,9 @@ func (r *LogicalGroupsRepo) GetByLogicalGroupID(ctx context.Context, logicalGrou
&group.DisplayName,
&group.Status,
&group.Description,
&group.UsageScenario,
&group.Recommendation,
&group.NextStepHint,
&group.RoutePolicy,
&group.StickyMode,
&group.ConversationTTLSeconds,
@@ -117,7 +129,7 @@ func (r *LogicalGroupsRepo) GetByLogicalGroupID(ctx context.Context, logicalGrou
func (r *LogicalGroupsRepo) List(ctx context.Context) ([]LogicalGroup, error) {
rows, err := r.db.QueryContext(
ctx,
`SELECT id, logical_group_id, display_name, status, description, route_policy, sticky_mode, conversation_ttl_seconds, user_model_ttl_seconds, failover_threshold, cooldown_seconds, created_at, updated_at
`SELECT id, logical_group_id, display_name, status, description, usage_scenario, recommendation, next_step_hint, route_policy, sticky_mode, conversation_ttl_seconds, user_model_ttl_seconds, failover_threshold, cooldown_seconds, created_at, updated_at
FROM logical_groups
ORDER BY id ASC`,
)
@@ -135,6 +147,9 @@ func (r *LogicalGroupsRepo) List(ctx context.Context) ([]LogicalGroup, error) {
&group.DisplayName,
&group.Status,
&group.Description,
&group.UsageScenario,
&group.Recommendation,
&group.NextStepHint,
&group.RoutePolicy,
&group.StickyMode,
&group.ConversationTTLSeconds,
@@ -163,11 +178,14 @@ func (r *LogicalGroupsRepo) UpdateByLogicalGroupID(ctx context.Context, group Lo
result, err := r.db.ExecContext(
ctx,
`UPDATE logical_groups
SET display_name = ?, status = ?, description = ?, route_policy = ?, sticky_mode = ?, conversation_ttl_seconds = ?, user_model_ttl_seconds = ?, failover_threshold = ?, cooldown_seconds = ?, updated_at = CURRENT_TIMESTAMP
SET display_name = ?, status = ?, description = ?, usage_scenario = ?, recommendation = ?, next_step_hint = ?, route_policy = ?, sticky_mode = ?, conversation_ttl_seconds = ?, user_model_ttl_seconds = ?, failover_threshold = ?, cooldown_seconds = ?, updated_at = CURRENT_TIMESTAMP
WHERE logical_group_id = ?`,
group.DisplayName,
group.Status,
group.Description,
group.UsageScenario,
group.Recommendation,
group.NextStepHint,
group.RoutePolicy,
group.StickyMode,
group.ConversationTTLSeconds,
@@ -214,6 +232,9 @@ func normalizeLogicalGroup(group LogicalGroup) (LogicalGroup, error) {
group.DisplayName = strings.TrimSpace(group.DisplayName)
group.Status = strings.TrimSpace(group.Status)
group.Description = strings.TrimSpace(group.Description)
group.UsageScenario = strings.TrimSpace(group.UsageScenario)
group.Recommendation = strings.TrimSpace(group.Recommendation)
group.NextStepHint = strings.TrimSpace(group.NextStepHint)
group.RoutePolicy = strings.TrimSpace(group.RoutePolicy)
group.StickyMode = strings.TrimSpace(group.StickyMode)

View File

@@ -16,6 +16,9 @@ func TestLogicalGroupsRepoCreateGetUpdateDelete(t *testing.T) {
DisplayName: "GPT Shared",
Status: "active",
Description: "shared group",
UsageScenario: "适合统一 GPT 产品入口。",
Recommendation: "优先使用 gpt-5.4。",
NextStepHint: "先创建测试 Key。",
})
if err != nil {
t.Fatalf("Create() error = %v", err)
@@ -34,12 +37,18 @@ func TestLogicalGroupsRepoCreateGetUpdateDelete(t *testing.T) {
if group.StickyMode != defaultLogicalGroupStickyMode {
t.Fatalf("StickyMode = %q, want %q", group.StickyMode, defaultLogicalGroupStickyMode)
}
if group.UsageScenario != "适合统一 GPT 产品入口。" || group.Recommendation != "优先使用 gpt-5.4。" || group.NextStepHint != "先创建测试 Key。" {
t.Fatalf("guidance fields = %+v, want persisted guidance", group)
}
if err := store.LogicalGroups().UpdateByLogicalGroupID(ctx, LogicalGroup{
LogicalGroupID: "gpt-shared",
DisplayName: "GPT Shared Updated",
Status: "paused",
Description: "updated",
UsageScenario: "适合更新后的产品入口。",
Recommendation: "优先做连通性验证。",
NextStepHint: "先确认订阅再调用。",
RoutePolicy: "priority",
StickyMode: "user_preferred",
ConversationTTLSeconds: 3600,
@@ -57,6 +66,9 @@ func TestLogicalGroupsRepoCreateGetUpdateDelete(t *testing.T) {
if updated.DisplayName != "GPT Shared Updated" || updated.Status != "paused" {
t.Fatalf("updated group = %+v, want updated fields", updated)
}
if updated.UsageScenario != "适合更新后的产品入口。" || updated.Recommendation != "优先做连通性验证。" || updated.NextStepHint != "先确认订阅再调用。" {
t.Fatalf("updated guidance = %+v, want updated guidance fields", updated)
}
if err := store.LogicalGroups().DeleteByLogicalGroupID(ctx, "gpt-shared"); err != nil {
t.Fatalf("DeleteByLogicalGroupID() error = %v", err)