package web import ( "net/http" "strconv" "sourcecraft.dev/bigbes/sr-ht-spec/service" ) // inboxData is the review-queue page: the open proposals waiting on the owner, // and the digest of what auto-merged without stopping for review. type inboxData struct { Open []proposalRow Digest []proposalRow } // proposalRow is one proposal as a listing line: enough to decide whether to // open it, and the link that does. type proposalRow struct { Href string ID int Space string Title string Agent string Approval string } // handleInbox renders the review queue: every open proposal on the instance, // plus the digest of recently policy-merged content. It is the backstop the // design describes — the link an agent hands you is the normal way in, and this // catches the work no link reached. func (s *Server) handleInbox(w http.ResponseWriter, r *http.Request) { if !mayRead(r) { s.loginRedirect(w, r) return } open, err := s.reader.Inbox(r.Context()) if err != nil { s.fail(w, r, err) return } digest, err := s.reader.Digest(r.Context()) if err != nil { s.fail(w, r, err) return } vd := s.chrome(r) vd.Title = "Review queue" vd.Data = inboxData{ Open: proposalRows(open), Digest: proposalRows(digest), } s.render(w, http.StatusOK, "inbox", vd) } // proposalRows turns service proposals into listing rows, building each one's // link from its space and id — the same stable /~owner/space/p/ shape the // write plane hands back. func proposalRows(ps []service.Proposal) []proposalRow { rows := make([]proposalRow, 0, len(ps)) for _, p := range ps { rows = append(rows, proposalRow{ Href: proposalHref(p), ID: p.ID, Space: p.Space.String(), Title: p.Title, Agent: p.Agent, Approval: string(p.Approval), }) } return rows } // proposalHref is the review-page link for a proposal: the same path the // proposal URL uses, minus the origin, so it works as a relative link in the UI. func proposalHref(p service.Proposal) string { return "/" + p.Space.String() + "/p/" + strconv.Itoa(p.ID) }