feat: add Z12/Z13 bind APIs, stock import, and sync docs

Enable auto default sync channels on agent activate, bind-code/phone confirm flows, publish ALTER, and align admin/yuheng docs with the production bind path.
This commit is contained in:
whm
2026-08-05 11:47:20 +08:00
parent b04b180d30
commit cb56e6847e
31 changed files with 1882 additions and 91 deletions

View File

@@ -0,0 +1,92 @@
package schema
import (
"context"
"database/sql"
"fmt"
"strings"
"aijianzhan/platform/internal/blueprint"
)
// BuildPostgresAlterDDL 对比蓝图与已有表,生成 ADD COLUMN IF NOT EXISTSZ11a
// db 可为 nil则只返回空调用方应先 CREATE TABLE
func BuildPostgresAlterDDL(ctx context.Context, db *sql.DB, bp *blueprint.Blueprint) ([]string, error) {
if bp == nil || bp.Storage.SchemaName == "" {
return nil, fmt.Errorf("schema_name empty")
}
if db == nil {
return nil, nil
}
schemaName := bp.Storage.SchemaName
var stmts []string
for _, e := range bp.Entities {
existing, err := listTableColumns(ctx, db, schemaName, e.Table)
if err != nil {
return nil, err
}
if existing == nil {
// 表尚不存在:由 CREATE TABLE IF NOT EXISTS 处理
continue
}
for _, f := range e.Fields {
if _, ok := existing[f.Name]; ok {
continue
}
sqlType, err := mapType(f)
if err != nil {
return nil, err
}
// 存量表补列一律可空,避免非空约束导致迁库失败
stmts = append(stmts, fmt.Sprintf(
`ALTER TABLE %s.%s ADD COLUMN IF NOT EXISTS %s %s`,
quoteIdent(schemaName), quoteIdent(e.Table), quoteIdent(f.Name), sqlType,
))
}
}
return stmts, nil
}
func listTableColumns(ctx context.Context, db *sql.DB, schemaName, table string) (map[string]struct{}, error) {
const q = `
SELECT column_name FROM information_schema.columns
WHERE table_schema = $1 AND table_name = $2`
rows, err := db.QueryContext(ctx, q, schemaName, table)
if err != nil {
return nil, err
}
defer rows.Close()
out := map[string]struct{}{}
found := false
for rows.Next() {
found = true
var name string
if err := rows.Scan(&name); err != nil {
return nil, err
}
out[name] = struct{}{}
}
if err := rows.Err(); err != nil {
return nil, err
}
if !found {
return nil, nil
}
return out, nil
}
// MergeDDL 将 alter 语句追加到 create ddl 之后。
func MergeDDL(create, alter []string) []string {
if len(alter) == 0 {
return create
}
out := make([]string, 0, len(create)+len(alter))
out = append(out, create...)
out = append(out, alter...)
return out
}
// Quote for tests
func normalizeSchemaTable(s string) string {
return strings.TrimSpace(s)
}