posts/mutations_upsert_author.go

56 lines
1.3 KiB
Go

package main
import (
"fmt"
"strings"
)
// UpsertAuthor — create or update an author. Used for the bootstrap path
// (registering `hermes`, `cos-dispatcher`, `scott` at startup) and for the
// agent onboarding flow.
type UpsertAuthor struct {
ID string
AuthorKind string // "human" | "agent" | "system"
DisplayName string
AvatarURL string
}
func (m *UpsertAuthor) Kind() string { return "upsert_author" }
func (m *UpsertAuthor) AffectedAuthors() []string {
return []string{m.ID}
}
func (m *UpsertAuthor) Validate(s *Store) error {
if strings.TrimSpace(m.ID) == "" {
return &ValidationError{Field: "id", Message: "required"}
}
switch m.AuthorKind {
case "human", "agent", "system":
default:
return &ValidationError{Field: "kind", Message: fmt.Sprintf("must be one of human/agent/system, got %q", m.AuthorKind)}
}
if strings.TrimSpace(m.DisplayName) == "" {
return &ValidationError{Field: "display_name", Message: "required"}
}
return nil
}
func (m *UpsertAuthor) Apply(s *Store, lock LockRegion) error {
now := s.Now()
a := &Author{
ID: m.ID,
Kind: m.AuthorKind,
DisplayName: m.DisplayName,
AvatarURL: m.AvatarURL,
CreatedAt: now,
UpdatedAt: now,
}
s.mu.Lock()
defer s.mu.Unlock()
if existing, ok := s.authors[m.ID]; ok {
a.CreatedAt = existing.CreatedAt
}
s.authors[m.ID] = a
return nil
}