fix(discovery): route param name collision in ClassifySimilarPair

gin panics at startup with:
  ':aid' in new path '/api/v1/admin/discovery/queue/:aid/similar/:bid/classify'
  conflicts with existing wildcard ':id' in existing prefix
  '/api/v1/admin/discovery/queue/:id'

Gin's trie requires identical parameter names at the same prefix position.
All sibling routes use :id; the tiebreak route was registered with :aid,
crashing the server on every deploy since e0b73ac. Prod has been running
the pre-tiebreak image (52f3e4c0) the whole time because every Helm
upgrade crash-looped and rolled back.

Rename :aid to :id in both the route and the handler's c.Param read.
:bid is in a different slot and stays.
This commit is contained in:
2026-04-24 13:06:08 +02:00
parent 24675cf176
commit c69fe4c07d
2 changed files with 3 additions and 3 deletions

View File

@@ -416,11 +416,11 @@ func (h *Handler) EnrichLLM(c *gin.Context) {
}
// ClassifySimilarPair runs the LLM duplicate-tiebreaker on the two queue
// rows identified by URL params :aid and :bid. Synchronous, 15s deadline —
// rows identified by URL params :id and :bid. Synchronous, 15s deadline —
// the call is short (no scraping) so the operator can click and immediately
// see the verdict.
func (h *Handler) ClassifySimilarPair(c *gin.Context) {
aID, err := uuid.Parse(c.Param("aid"))
aID, err := uuid.Parse(c.Param("id"))
if err != nil {
apiErr := apierror.BadRequest("invalid_id", "invalid queue id A")
c.JSON(apiErr.Status, apierror.NewResponse(apiErr))

View File

@@ -27,7 +27,7 @@ func RegisterRoutes(
// Per-row LLM enrichment (MR 3b). Synchronous — operator waits.
admin.POST("/queue/:id/enrich", h.EnrichLLM)
// Per-pair AI similarity tiebreak (MR 4). Synchronous; short call.
admin.POST("/queue/:aid/similar/:bid/classify", h.ClassifySimilarPair)
admin.POST("/queue/:id/similar/:bid/classify", h.ClassifySimilarPair)
// Manual crawl trigger — subject to hourly rate limit.
admin.POST("/crawl-manual", h.Crawl)
// Async crawl status polling.