package dashboard import ( "sort" "inbox/internal/domain/message" "inbox/internal/domain/role" "inbox/internal/domain/workflow" ) func latestRunForRole(items []workflow.Run, roleName string) *workflow.Run { var selected *workflow.Run for _, item := range items { if item.RoleName != roleName { continue } if selected == nil || item.StartedAt > selected.StartedAt || (item.StartedAt == selected.StartedAt && item.ID > selected.ID) { runCopy := item selected = &runCopy } } return selected } func latestInboundMessage(items []message.Record, roleName string) message.Record { var selected message.Record for _, item := range items { if !messageTargetsRole(item.ToExpr, roleName) { continue } if item.CreatedAt > selected.CreatedAt || (item.CreatedAt == selected.CreatedAt && item.ID > selected.ID) { selected = item } } return selected } func latestOutboundMessage(items []message.Record, roleName string) message.Record { var selected message.Record for _, item := range items { if item.FromRoleName != roleName { continue } if item.CreatedAt > selected.CreatedAt || (item.CreatedAt == selected.CreatedAt && item.ID > selected.ID) { selected = item } } return selected } func latestMessageForRole(items []message.Record, roleName string) message.Record { inbound := latestInboundMessage(items, roleName) outbound := latestOutboundMessage(items, roleName) if outbound.CreatedAt > inbound.CreatedAt || (outbound.CreatedAt == inbound.CreatedAt && outbound.ID > inbound.ID) { return outbound } return inbound } func runningRolesForRuns(items []workflow.Run) []string { seen := make(map[string]struct{}) out := make([]string, 0) for _, item := range items { if item.Status != workflow.RunStatusRunning { continue } if _, ok := seen[item.RoleName]; ok { continue } seen[item.RoleName] = struct{}{} out = append(out, item.RoleName) } sort.Strings(out) return out } func pendingRolesForTopic(items map[string]int, roles []role.Definition) []string { if len(items) == 0 { return []string{} } valid := make(map[string]bool) for _, item := range roles { if item.IsEnabled || item.ExecutorKind == role.ExecutorKindHuman { valid[item.Name] = true } } out := make([]string, 0, len(items)) for roleName, count := range items { if count <= 0 || !valid[roleName] { continue } out = append(out, roleName) } sort.Strings(out) return out }