You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(api): return accurate contacts total for server pagination
Extend the contact repository/service/handler so GET /v1/contacts returns
a top-level total count for the same user/query filter, independent of
skip/limit, enabling true server-side pagination.
- add ContactRepository.Count reusing a shared scopedContactQuery helper
so Index and Count filters can never drift; Count ignores limit/offset
- add ContactService.Count and handler responseOKWithTotal; Index returns total
- add Total to responses.ContactsResponse and regenerate Swagger
- sanitize parsed CSV rows before validation so CSV and JSON accept the
same phone/email formats; drop the now-redundant re-sanitize on upload
- assert Scan error behaviour instead of the unexported stacktrace type
- tests for count filter parity, total propagation, and CSV sanitization
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy file name to clipboardExpand all lines: api/docs/docs.go
+8-2Lines changed: 8 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -249,7 +249,7 @@ const docTemplate = `{
249
249
"ApiKeyAuth": []
250
250
}
251
251
],
252
-
"description": "Returns the paginated list of contacts for the authenticated user.",
252
+
"description": "Returns the paginated list of contacts for the authenticated user. The top-level \"total\" field is the number of contacts matching the query filter, independent of skip/limit, so clients can drive server-side pagination.",
253
253
"consumes": [
254
254
"application/json"
255
255
],
@@ -5257,7 +5257,8 @@ const docTemplate = `{
5257
5257
"required": [
5258
5258
"data",
5259
5259
"message",
5260
-
"status"
5260
+
"status",
5261
+
"total"
5261
5262
],
5262
5263
"properties": {
5263
5264
"data": {
@@ -5273,6 +5274,11 @@ const docTemplate = `{
5273
5274
"status": {
5274
5275
"type": "string",
5275
5276
"example": "success"
5277
+
},
5278
+
"total": {
5279
+
"description": "Total is the number of contacts matching the request filter for the\nuser, independent of the pagination skip/limit applied to Data.",
Copy file name to clipboardExpand all lines: api/docs/swagger.json
+8-2Lines changed: 8 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -246,7 +246,7 @@
246
246
"ApiKeyAuth": []
247
247
}
248
248
],
249
-
"description": "Returns the paginated list of contacts for the authenticated user.",
249
+
"description": "Returns the paginated list of contacts for the authenticated user. The top-level \"total\" field is the number of contacts matching the query filter, independent of skip/limit, so clients can drive server-side pagination.",
250
250
"consumes": [
251
251
"application/json"
252
252
],
@@ -5254,7 +5254,8 @@
5254
5254
"required": [
5255
5255
"data",
5256
5256
"message",
5257
-
"status"
5257
+
"status",
5258
+
"total"
5258
5259
],
5259
5260
"properties": {
5260
5261
"data": {
@@ -5270,6 +5271,11 @@
5270
5271
"status": {
5271
5272
"type": "string",
5272
5273
"example": "success"
5274
+
},
5275
+
"total": {
5276
+
"description": "Total is the number of contacts matching the request filter for the\nuser, independent of the pagination skip/limit applied to Data.",
// Index lists contacts for the authenticated user.
51
51
// @Summary List contacts
52
-
// @Description Returns the paginated list of contacts for the authenticated user.
52
+
// @Description Returns the paginated list of contacts for the authenticated user. The top-level "total" field is the number of contacts matching the query filter, independent of skip/limit, so clients can drive server-side pagination.
return0, repository.tracer.WrapErrorSpan(span, stacktrace.Propagatef(err, "cannot count contacts for user [%s] with query [%s]", userID, params.Query))
0 commit comments