fix: Z35 map Chinese display names to stable physical DB names

Keep Chinese on Binding for UI; Agents use user_{id} or db{hash}; sanitize on attach/heal/publish.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
whm
2026-08-07 02:12:55 +08:00
parent 7290f91d3a
commit 4b6c90904b
8 changed files with 146 additions and 32 deletions

View File

@@ -0,0 +1,33 @@
package schema
import "testing"
func TestSafeSyncDatabaseName(t *testing.T) {
// 有用户:中文昵称 → 稳定 user_{id}(改昵称不换库)
if got := SafeSyncDatabaseName("婷婷管理员", 12, 34); got != "user_34" {
t.Fatalf("want user_34, got %s", got)
}
// 无用户:中文/非法标签 → 稳定哈希
h1 := SafeSyncDatabaseName("婷婷管理员", 12, 0)
h2 := SafeSyncDatabaseName("婷婷管理员", 12, 0)
if h1 != h2 || !ValidDBName(h1) || h1[:2] != "db" {
t.Fatalf("hash mapping bad: %s", h1)
}
if SafeSyncDatabaseName("另一中文", 12, 0) == h1 {
t.Fatal("different labels should hash differently")
}
if got := SafeSyncDatabaseName("ok_db", 1, 2); got != "ok_db" {
t.Fatalf("want ok_db, got %s", got)
}
if !ValidDBName("user_1") || ValidDBName("婷婷管理员") {
t.Fatal("ValidDBName mismatch")
}
}
func TestHashLabelDBNameStable(t *testing.T) {
a := HashLabelDBName("宇信达", 7)
b := HashLabelDBName("宇信达", 7)
if a != b || !ValidDBName(a) {
t.Fatalf("unstable or invalid: %s", a)
}
}

View File

@@ -2,11 +2,14 @@ package schema
import (
"context"
"crypto/sha256"
"database/sql"
"encoding/hex"
"fmt"
"net/url"
"regexp"
"strings"
"unicode"
)
var dbNameRe = regexp.MustCompile(`^[a-z][a-z0-9_]{1,47}$`)
@@ -108,3 +111,52 @@ func SafePhysicalDBName(preferred, fallback string) string {
}
return "appdb_default"
}
// SafeSyncDatabaseName Z35智能体同步落点的 Postgres 物理库名。
// - 已是合法 ASCII → 原样
// - 中文/非法串:有 userID → user_{id}(昵称可变仍稳定);否则对标签做稳定哈希 db{hex}
// - 展示中文请写 Binding.DisplayName / Binding.DatabaseName可读名勿把物理名当展示名
func SafeSyncDatabaseName(preferred string, agentID, userID int64) string {
p := strings.TrimSpace(preferred)
if ValidDBName(p) {
return p
}
// 有登录用户:物理名跟用户稳定绑定;中文昵称只作展示
if userID > 0 {
n := fmt.Sprintf("user_%d", userID)
if ValidDBName(n) {
return n
}
}
if p != "" {
return HashLabelDBName(p, agentID)
}
if agentID > 0 {
n := fmt.Sprintf("agent_%d", agentID)
if ValidDBName(n) {
return n
}
}
return "appdb_default"
}
// HashLabelDBName 将任意标签含中文稳定映射为合法物理库名db + 16 hex。
func HashLabelDBName(label string, agentID int64) string {
label = strings.TrimSpace(label)
sum := sha256.Sum256([]byte(fmt.Sprintf("ajz-db:%d:%s", agentID, label)))
return "db" + hex.EncodeToString(sum[:8])
}
// IsDisplayLabel 是否更像「展示名」而非物理库名(含非 ASCII / 大写 / 连字符等)。
func IsDisplayLabel(s string) bool {
s = strings.TrimSpace(s)
if s == "" || ValidDBName(s) {
return false
}
for _, r := range s {
if r > unicode.MaxASCII || unicode.Is(unicode.Han, r) {
return true
}
}
return true
}