56db37a463
web/handlers/bloom.go: GET /bloom/{stashID} renders BloomRecord
(AccruedGrain, RateBasisPoints as %, LastAccrualBlock) + the 4.5%
target rate read from x/bloom/types.TargetBloomRateBasisPoints (D-073
code-constant source-of-truth, NOT hardcoded) + the 4.0%-5.0% band
(Min/MaxBloomRateBasisPoints) + Mission Lock note. Store extensions:
GetBloomRecord/ListBloomRecords. Seed: holder-alia at target rate (450
bps), holder-bryn at 420 bps (within band). bloom_test.go: D-073
target-rate source-of-truth regression guard (asserts TargetBloomRate-
BasisPoints=450, Min=400, Max=500 from code constants; would fail if
hardcoded), G-026 error lexicon check, highest-risk screen for banned-
term drift (uses "Bloom"/"real production"/"accrual" labels only).
Coverage: store 98.1%, handlers 89.2%.
---ci---
project: oy
phase: 5
milestone: v0.6
status: execute
---/ci---
51 lines
1.7 KiB
Go
51 lines
1.7 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
bloomtypes "github.com/oy/openyield/x/bloom/types"
|
|
)
|
|
|
|
// registerBloom wires the Bloom accrual route (REQ-044).
|
|
func (s *Server) registerBloom(mux *http.ServeMux) {
|
|
mux.HandleFunc("GET /bloom/{stashID}", s.handleBloom)
|
|
}
|
|
|
|
// bloomViewData is the template data for the Bloom accrual view.
|
|
type bloomViewData struct {
|
|
StashID string
|
|
Found bool
|
|
Record bloomtypes.BloomRecord
|
|
RatePct float64 // RateBasisPoints as a percentage (450 -> 4.5)
|
|
TargetRatePct float64 // TargetBloomRateBasisPoints as %
|
|
MinRatePct float64
|
|
MaxRatePct float64
|
|
AccrualPeriod int64
|
|
MissionLockNote string
|
|
}
|
|
|
|
// handleBloom renders the Bloom accrual view (REQ-044): per-Stash BloomRecord
|
|
// (AccruedGrain, RateBasisPoints as %, LastAccrualBlock) + the 4.5% target rate
|
|
// (read from x/bloom/types.TargetBloomRateBasisPoints — D-073 code-constant
|
|
// source-of-truth, NOT hardcoded). Bloom is conceptually close to a banned
|
|
// financial term; labels use "Bloom"/"real production"/"accrual" only.
|
|
func (s *Server) handleBloom(w http.ResponseWriter, r *http.Request) {
|
|
stashID := r.PathValue("stashID")
|
|
rec, ok := s.Store.GetBloomRecord(stashID)
|
|
if !ok {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
s.render(w, "bloom.html", bloomViewData{
|
|
StashID: stashID,
|
|
Found: true,
|
|
Record: rec,
|
|
RatePct: float64(rec.RateBasisPoints) / 100,
|
|
TargetRatePct: float64(bloomtypes.TargetBloomRateBasisPoints) / 100,
|
|
MinRatePct: float64(bloomtypes.MinBloomRateBasisPoints) / 100,
|
|
MaxRatePct: float64(bloomtypes.MaxBloomRateBasisPoints) / 100,
|
|
AccrualPeriod: bloomtypes.AccrualPeriodBlocks,
|
|
MissionLockNote: bloomtypes.MissionLockBloom,
|
|
})
|
|
}
|