package handlers import ( "net/http" breadtypes "github.com/oy/openyield/x/bread/types" stashtypes "github.com/oy/openyield/x/stash/types" ) // registerStash wires the Stash dashboard route (REQ-041) into the mux. func (s *Server) registerStash(mux *http.ServeMux) { mux.HandleFunc("GET /stash/{holderID}", s.handleStashDashboard) } // stashViewData is the template data for the Stash dashboard. It carries the // real x/*/types structs plus the Bread-scale conversion (computed from the // x/bread/types code constants per D-073) and the maturity progress. type stashViewData struct { Stash stashtypes.Stash Activity stashtypes.StashActivity Found bool BreadScale []breadtypes.BreadScale BalanceBread int64 MaturityPct int Mature bool ThresholdDays uint32 MaxGapDays uint32 } // handleStashDashboard renders the Stash dashboard (REQ-041): balance in Grain // + Bread-scale conversion (using x/bread/types.BreadScaleAll() + GrainsPerBread // per D-073 — code constants, NOT docs) + 90-day maturity progress bar // (StashActivity.IsMature, MaturityThresholdDays=90). func (s *Server) handleStashDashboard(w http.ResponseWriter, r *http.Request) { holderID := r.PathValue("holderID") stash, ok := s.Store.GetStash(holderID) if !ok { http.NotFound(w, r) return } activity, _ := s.Store.GetStashActivity(stash.StashID) // D-073: Bread-scale conversion from x/bread/types code constants. scale := breadtypes.BreadScaleAll() balanceBread := stash.BalanceGrain / breadtypes.GrainsPerBread // Maturity progress: ActiveDays / MaturityThresholdDays, capped at 100%. threshold := uint32(stashtypes.MaturityThresholdDays) pct := int(float64(activity.ActiveDays) / float64(threshold) * 100) if pct > 100 { pct = 100 } if pct < 0 { pct = 0 } s.render(w, "stash.html", stashViewData{ Stash: stash, Activity: activity, Found: true, BreadScale: scale, BalanceBread: balanceBread, MaturityPct: pct, Mature: activity.IsMature(), ThresholdDays: threshold, MaxGapDays: stashtypes.MaxGapForMaturity, }) }