package main import ( "context" "log" ) func (s *Server) reconcile(ctx context.Context, runID int64, rep *User, dept string) error { reps, err := s.store.RepsFor(rep.ChapterID, dept) if err != nil { return err } if len(reps) == 0 { // Shouldn't happen: the webhook fired for a rep in this department. log.Printf("run %d: no reps found for chapter %d dept %q", runID, rep.ChapterID, dept) return nil } if len(reps) > 1 { log.Printf("WARNING: run %d: %d reps for chapter %d dept %q; assigning all to %d (fill-only mode)", runID, len(reps), rep.ChapterID, dept, reps[0]) } agent := reps[0] members, err := s.store.EligibleMembers(rep.ChapterID, dept) if err != nil { return err } // loop assigned, skipped, failed := 0, 0, 0 for _, m := range members { select { case <-ctx.Done(): log.Printf("run %d: cancelled after %d assigned, %d skipped", runID, assigned, skipped) return ctx.Err() default: } existing, err := client.ActiveAgent(ctx, m) if err != nil { log.Printf("run %d: checking agent for %d failed: %v", runID, m, err) failed++ continue } if existing != 0 { // Fill-only: never displace an existing agent. skipped++ if err := s.store.LogSkip(runID, m, existing, agent); err != nil { log.Printf("run %d: logging skip for %d failed: %v", runID, m, err) } continue } if err := client.AssignAgent(ctx, m, agent); err != nil { log.Printf("run %d: assigning %d to %d failed: %v", runID, m, agent, err) failed++ continue } assigned++ if err := s.store.SetProgress(runID, m); err != nil { log.Printf("run %d: recording progress failed: %v", runID, err) } } if assigned == 0 && skipped > 0 { log.Printf("WARNING: run %d: assigned nobody; all %d members already have agents", runID, skipped) } log.Printf("run %d: %d assigned, %d skipped, dept %q chapter %d", runID, assigned, skipped, dept, rep.ChapterID) return nil }