multica/server/internal/util/pgx.go
Jiayuan Zhang 5a3a72c411 feat(server): add task service layer and daemon REST protocol
- Extract TaskService (server/internal/service/task.go) for task lifecycle:
  enqueue with context snapshot, claim, start, complete, fail, progress
- Add daemon protocol endpoints under /api/daemon/:
  register, heartbeat, claim task, start/progress/complete/fail task
- Task ↔ Issue status sync: running→in_progress, completed→in_review, failed→blocked
- Agent status auto-management: reconcile idle/working based on running tasks
- Enforce max_concurrent_tasks on task claiming (FOR UPDATE SKIP LOCKED)
- Add UpdateIssueStatus query (fixes bug where UpdateIssue nulls assignee)
- Extract shared pgx utils to server/internal/util/ to avoid circular imports
- Migration 003: add context JSONB to agent_task_queue, daemon unique constraint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 18:34:51 +08:00

76 lines
1.2 KiB
Go

package util
import (
"encoding/hex"
"time"
"github.com/jackc/pgx/v5/pgtype"
)
func ParseUUID(s string) pgtype.UUID {
var u pgtype.UUID
_ = u.Scan(s)
return u
}
func UUIDToString(u pgtype.UUID) string {
if !u.Valid {
return ""
}
b := u.Bytes
dst := make([]byte, 36)
hex.Encode(dst[0:8], b[0:4])
dst[8] = '-'
hex.Encode(dst[9:13], b[4:6])
dst[13] = '-'
hex.Encode(dst[14:18], b[6:8])
dst[18] = '-'
hex.Encode(dst[19:23], b[8:10])
dst[23] = '-'
hex.Encode(dst[24:36], b[10:16])
return string(dst)
}
func TextToPtr(t pgtype.Text) *string {
if !t.Valid {
return nil
}
return &t.String
}
func PtrToText(s *string) pgtype.Text {
if s == nil {
return pgtype.Text{}
}
return pgtype.Text{String: *s, Valid: true}
}
func StrToText(s string) pgtype.Text {
if s == "" {
return pgtype.Text{}
}
return pgtype.Text{String: s, Valid: true}
}
func TimestampToString(t pgtype.Timestamptz) string {
if !t.Valid {
return ""
}
return t.Time.Format(time.RFC3339)
}
func TimestampToPtr(t pgtype.Timestamptz) *string {
if !t.Valid {
return nil
}
s := t.Time.Format(time.RFC3339)
return &s
}
func UUIDToPtr(u pgtype.UUID) *string {
if !u.Valid {
return nil
}
s := UUIDToString(u)
return &s
}