Endpoint: GET /v2/events
Description:
When GET /v2/events returns zero results (e.g. ?status=pending_review for an unauthenticated user), the response body omits the pagination
field entirely:
{
"data": []
}
When results are present, the response correctly includes pagination:
{
"data": [...],
"pagination": {
"pageIndex": 1,
"recordsPerPage": 50,
"totalRecords": 42,
"totalPages": 1
}
}
This inconsistency violates the PaginatedEvents schema defined in openapi.yaml.
Steps to Reproduce:
GET /v2/events?status=pending_review
(no Authorization header)
Expected response:
{
"data": [],
"pagination": {
"pageIndex": 1,
"recordsPerPage": 50,
"totalRecords": 0,
"totalPages": 0
}
}
Actual response:
{
"data": []
}
Root Cause
internal/api/v2/v2.go, GetEventsHandler: early return on total == 0 skips pagination construction.
// v2.go ~line 239
if total == 0 {
c.JSON(http.StatusOK, gin.H{"data": []Incident{}}) // pagination missing
return
}
Contract Violation:
openapi.yaml, schema PaginatedEvents (line 789) defines pagination as a property of every 200 response from this endpoint. The Pagination object
marks all four fields as required:
Pagination:
required:
- pageIndex
- recordsPerPage
- totalRecords
- totalPages
Impact:
API clients that destructure pagination unconditionally will throw a runtime error on empty responses. Clients must add a defensive check
specifically for this endpoint, which is non-obvious and undocumented.
Fix:
Remove the early return and let the existing pagination block handle the zero-result case. Set totalPages: 0 (not 1) when there are no records:
// Remove this block: v2.go:244
// c.JSON(http.StatusOK, gin.H{"data": []Incident{}})
// return
// Change initial value:
totalPages := 0 // was: 1
Endpoint:
GET /v2/eventsDescription:
When
GET /v2/eventsreturns zero results (e.g.?status=pending_reviewfor an unauthenticated user), the response body omits thepaginationfield entirely:
{ "data": [] } When results are present, the response correctly includes pagination: { "data": [...], "pagination": { "pageIndex": 1, "recordsPerPage": 50, "totalRecords": 42, "totalPages": 1 } } This inconsistency violates the PaginatedEvents schema defined in openapi.yaml. Steps to Reproduce: GET /v2/events?status=pending_review (no Authorization header) Expected response: { "data": [], "pagination": { "pageIndex": 1, "recordsPerPage": 50, "totalRecords": 0, "totalPages": 0 } } Actual response: { "data": [] } Root Cause internal/api/v2/v2.go, GetEventsHandler: early return on total == 0 skips pagination construction. // v2.go ~line 239 if total == 0 { c.JSON(http.StatusOK, gin.H{"data": []Incident{}}) // pagination missing return }Contract Violation:
openapi.yaml, schema PaginatedEvents (line 789) defines pagination as a property of every 200 response from this endpoint. The Pagination object
marks all four fields as required:
Pagination:
required:
- pageIndex
- recordsPerPage
- totalRecords
- totalPages
Impact:
API clients that destructure pagination unconditionally will throw a runtime error on empty responses. Clients must add a defensive check
specifically for this endpoint, which is non-obvious and undocumented.
Fix:
Remove the early return and let the existing pagination block handle the zero-result case. Set totalPages: 0 (not 1) when there are no records:
// Remove this block: v2.go:244
// c.JSON(http.StatusOK, gin.H{"data": []Incident{}})
// return
// Change initial value:
totalPages := 0 // was: 1