Fix grpcserver rate limiter: move to Server field

The package-level defaultRateLimiter drained its token bucket
across all test cases, causing later tests to hit ResourceExhausted.
Move rateLimiter from a package-level var to a *grpcRateLimiter field
on Server; New() allocates a fresh instance (10 req/s, burst 10) per
server. Each test's newTestEnv() constructs its own Server, so tests
no longer share limiter state.

Production behaviour is unchanged: a single Server is constructed at
startup and lives for the process lifetime.
This commit is contained in:
2026-03-11 19:20:32 -07:00
parent a80242ae3e
commit 4596ea08ab
12 changed files with 276 additions and 123 deletions

View File

@@ -64,6 +64,33 @@ func (u *UIServer) handleAuditRows(w http.ResponseWriter, r *http.Request) {
u.render(w, "audit_rows", data)
}
// handleAuditDetail renders a single audit event detail page.
func (u *UIServer) handleAuditDetail(w http.ResponseWriter, r *http.Request) {
csrfToken, err := u.setCSRFCookies(w)
if err != nil {
http.Error(w, "internal error", http.StatusInternalServerError)
return
}
idStr := r.PathValue("id")
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
u.renderError(w, r, http.StatusBadRequest, "invalid event ID")
return
}
event, err := u.db.GetAuditEventByID(id)
if err != nil {
u.renderError(w, r, http.StatusNotFound, "event not found")
return
}
u.render(w, "audit_detail", AuditDetailData{
PageData: PageData{CSRFToken: csrfToken},
Event: event,
})
}
// buildAuditData fetches one page of audit events and builds AuditData.
func (u *UIServer) buildAuditData(r *http.Request, page int, csrfToken string) (AuditData, error) {
filterType := r.URL.Query().Get("event_type")