package handlers import ( "net/http" standingtypes "github.com/oy/openyield/x/standing/types" ) // registerStanding wires the Standing + Freeholder signals route (REQ-043). func (s *Server) registerStanding(mux *http.ServeMux) { mux.HandleFunc("GET /standing/{reachID}", s.handleStanding) } // standingViewData is the template data for the Standing screen. type standingViewData struct { ReachID string Found bool Score float64 Bucket standingtypes.StandingBucket Ratings []standingtypes.Rating Vouches []standingtypes.Vouch Slashes []standingtypes.Slash Signals standingtypes.FreeholderSignals Eligible bool MinScore float64 MinCats int } // handleStanding renders the Standing + Freeholder signals progress (REQ-043). // Computed from mock Ratings/Vouches/Slashes using the locked x/standing/types // constants + GetStandingBucket/ComputeDiversityBonus/GetVoucherWeight; the // 4-signal progress via FreeholderSignals.IsFreeholderEligible(). func (s *Server) handleStanding(w http.ResponseWriter, r *http.Request) { id := r.PathValue("reachID") _, ok := s.Store.GetReach(id) if !ok { http.NotFound(w, r) return } score, bucket := s.Store.ComputeStandingScore(id) ratings := s.Store.ListRatings(id) vouches := s.Store.ListVouches(id) slashes := s.Store.ListSlashes(id) signals := s.Store.ComputeFreeholderSignals(id) s.render(w, "standing.html", standingViewData{ ReachID: id, Found: true, Score: score, Bucket: bucket, Ratings: ratings, Vouches: vouches, Slashes: slashes, Signals: signals, Eligible: signals.IsFreeholderEligible(), MinScore: standingtypes.FreeholderMinStandingScore, MinCats: standingtypes.FreeholderMinCategories, }) }