package domain import ( "sync" "time" ) // RegisteredParty represents a party registered with the router type RegisteredParty struct { PartyID string Role string // persistent, delegate, temporary Version string RegisteredAt time.Time LastSeen time.Time } // PartyRegistry manages registered parties type PartyRegistry struct { parties map[string]*RegisteredParty mu sync.RWMutex } // NewPartyRegistry creates a new party registry func NewPartyRegistry() *PartyRegistry { return &PartyRegistry{ parties: make(map[string]*RegisteredParty), } } // Register registers a party func (r *PartyRegistry) Register(partyID, role, version string) *RegisteredParty { r.mu.Lock() defer r.mu.Unlock() now := time.Now() party := &RegisteredParty{ PartyID: partyID, Role: role, Version: version, RegisteredAt: now, LastSeen: now, } r.parties[partyID] = party return party } // Get retrieves a registered party func (r *PartyRegistry) Get(partyID string) (*RegisteredParty, bool) { r.mu.RLock() defer r.mu.RUnlock() party, exists := r.parties[partyID] return party, exists } // GetAll returns all registered parties func (r *PartyRegistry) GetAll() []*RegisteredParty { r.mu.RLock() defer r.mu.RUnlock() parties := make([]*RegisteredParty, 0, len(r.parties)) for _, party := range r.parties { parties = append(parties, party) } return parties } // UpdateLastSeen updates the last seen timestamp func (r *PartyRegistry) UpdateLastSeen(partyID string) { r.mu.Lock() defer r.mu.Unlock() if party, exists := r.parties[partyID]; exists { party.LastSeen = time.Now() } } // Unregister removes a party from the registry func (r *PartyRegistry) Unregister(partyID string) { r.mu.Lock() defer r.mu.Unlock() delete(r.parties, partyID) } // Count returns the number of registered parties func (r *PartyRegistry) Count() int { r.mu.RLock() defer r.mu.RUnlock() return len(r.parties) }