提供接入码配对、配置查询、本地策略修改、验证、激活、回滚、禁用和公开运行时状态接口。写操作强制 Idempotency-Key 与 If-Match,后台 Exchange 支持重启恢复和过期收敛,并记录脱敏 Trace 与审计。\n\n验证:go test 相关 identity、store、identityruntime、httpapi 包;go vet ./apps/api/...
90 lines
3.7 KiB
Go
90 lines
3.7 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/easyai/easyai-ai-gateway/apps/api/internal/identity"
|
|
"github.com/jackc/pgx/v5"
|
|
)
|
|
|
|
const identityPairingColumns = `
|
|
id::text,revision_id::text,remote_exchange_id::text,exchange_token_ref,status,remote_version,expires_at,version,
|
|
COALESCE(last_error_category,''),COALESCE(auth_center_audit_id,''),COALESCE(last_trace_id,''),created_at,updated_at`
|
|
|
|
func (s *Store) CreateIdentityPairingExchange(ctx context.Context, exchange identity.PairingExchange) (identity.PairingExchange, error) {
|
|
return scanIdentityPairing(s.pool.QueryRow(ctx, `
|
|
INSERT INTO gateway_identity_onboarding_exchanges (
|
|
id,revision_id,remote_exchange_id,exchange_token_ref,status,remote_version,expires_at,last_trace_id
|
|
) VALUES ($1::uuid,$2::uuid,$3::uuid,$4,$5,$6,$7,NULLIF($8,''))
|
|
RETURNING `+identityPairingColumns,
|
|
exchange.ID, exchange.RevisionID, exchange.RemoteExchangeID, exchange.ExchangeTokenRef,
|
|
exchange.Status, exchange.RemoteVersion, exchange.ExpiresAt, exchange.LastTraceID,
|
|
))
|
|
}
|
|
|
|
func (s *Store) IdentityPairingExchange(ctx context.Context, id string) (identity.PairingExchange, error) {
|
|
exchange, err := scanIdentityPairing(s.pool.QueryRow(ctx, `SELECT `+identityPairingColumns+`
|
|
FROM gateway_identity_onboarding_exchanges WHERE id=$1::uuid`, id))
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return identity.PairingExchange{}, identity.ErrRevisionNotFound
|
|
}
|
|
return exchange, err
|
|
}
|
|
|
|
func (s *Store) IdentityPairingExchangeForRevision(ctx context.Context, revisionID string) (identity.PairingExchange, error) {
|
|
exchange, err := scanIdentityPairing(s.pool.QueryRow(ctx, `SELECT `+identityPairingColumns+`
|
|
FROM gateway_identity_onboarding_exchanges WHERE revision_id=$1::uuid`, revisionID))
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return identity.PairingExchange{}, identity.ErrRevisionNotFound
|
|
}
|
|
return exchange, err
|
|
}
|
|
|
|
func (s *Store) PendingIdentityPairingExchanges(ctx context.Context) ([]identity.PairingExchange, error) {
|
|
rows, err := s.pool.Query(ctx, `SELECT `+identityPairingColumns+`
|
|
FROM gateway_identity_onboarding_exchanges
|
|
WHERE status IN ('metadata_pending','preparing','ready','credentials_saved') ORDER BY created_at`)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
exchanges := make([]identity.PairingExchange, 0)
|
|
for rows.Next() {
|
|
exchange, scanErr := scanIdentityPairing(rows)
|
|
if scanErr != nil {
|
|
return nil, scanErr
|
|
}
|
|
exchanges = append(exchanges, exchange)
|
|
}
|
|
return exchanges, rows.Err()
|
|
}
|
|
|
|
func (s *Store) UpdateIdentityPairingExchange(ctx context.Context, id string, expectedVersion int64, update identity.PairingExchangeUpdate) (identity.PairingExchange, error) {
|
|
exchange, err := scanIdentityPairing(s.pool.QueryRow(ctx, `
|
|
UPDATE gateway_identity_onboarding_exchanges SET status=$3,remote_version=$4,last_error_category=NULLIF($5,''),
|
|
auth_center_audit_id=COALESCE(NULLIF($6,''),auth_center_audit_id),version=version+1,updated_at=now()
|
|
WHERE id=$1::uuid AND version=$2
|
|
RETURNING `+identityPairingColumns,
|
|
id, expectedVersion, update.Status, update.RemoteVersion, update.LastErrorCategory, update.AuthCenterAuditID,
|
|
))
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return identity.PairingExchange{}, identity.ErrRevisionConflict
|
|
}
|
|
return exchange, err
|
|
}
|
|
|
|
func scanIdentityPairing(row scanner) (identity.PairingExchange, error) {
|
|
var exchange identity.PairingExchange
|
|
var status string
|
|
if err := row.Scan(
|
|
&exchange.ID, &exchange.RevisionID, &exchange.RemoteExchangeID, &exchange.ExchangeTokenRef, &status,
|
|
&exchange.RemoteVersion, &exchange.ExpiresAt, &exchange.Version, &exchange.LastErrorCategory,
|
|
&exchange.AuthCenterAuditID, &exchange.LastTraceID, &exchange.CreatedAt, &exchange.UpdatedAt,
|
|
); err != nil {
|
|
return identity.PairingExchange{}, err
|
|
}
|
|
exchange.Status = identity.PairingStatus(status)
|
|
return exchange, nil
|
|
}
|