Files
ai-gateway-go/internal/workbench/service.go
T
superidou 5759c1862e AI Gateway Go 0.10.0 源码快照 + 旗舰版需求规划报告
M0-M7 已完成:核心网关(身份/RBAC/TOTP/OIDC/SAML/Provider/配额/路由/内容策略/审计/定价)+ 资源市场(MCP/Skills/数字员工)。
含 22 个 PostgreSQL 迁移、管理端/门户端前端源码、OpenAPI 契约、部署 compose。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-12 11:45:54 +08:00

70 lines
1.7 KiB
Go

package workbench
import (
"context"
"encoding/json"
"errors"
"fmt"
"strings"
platformid "aigateway.local/core/internal/platform/id"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool"
)
type Service struct{ pool *pgxpool.Pool }
func NewService(pool *pgxpool.Pool) *Service { return &Service{pool: pool} }
func newUUID() (string, error) { return platformid.NewUUID() }
func emit(ctx context.Context, tx pgx.Tx, eventType, aggregateType, aggregateID, actorID string, values map[string]any) error {
eventID, err := newUUID()
if err != nil {
return err
}
if values == nil {
values = make(map[string]any)
}
values[aggregateType+"_id"] = aggregateID
values["actor_id"] = actorID
payload, err := json.Marshal(values)
if err != nil {
return err
}
_, err = tx.Exec(ctx, `INSERT INTO gateway.outbox_events(event_id,event_type,event_version,aggregate_type,aggregate_id,payload) VALUES($1,$2,1,$3,$4,$5)`, eventID, eventType, aggregateType, aggregateID, payload)
return err
}
func normalizeStrings(values []string, maximum int) ([]string, error) {
seen := make(map[string]struct{}, len(values))
result := make([]string, 0, len(values))
for _, value := range values {
value = strings.TrimSpace(value)
if value == "" {
continue
}
if len(value) > 255 {
return nil, errors.New("列表项过长")
}
if _, ok := seen[value]; ok {
continue
}
seen[value] = struct{}{}
result = append(result, value)
}
if len(result) > maximum {
return nil, fmt.Errorf("列表最多允许 %d 项", maximum)
}
return result, nil
}
func mapNotFound(err error) error {
if errors.Is(err, pgx.ErrNoRows) {
return ErrNotFound
}
return err
}
func rollback(ctx context.Context, tx pgx.Tx) { _ = tx.Rollback(ctx) }