activity: add filtered count route

separated the search parts of ServerSearchReqDTO into
ServerFilterReqDTO, factored out part of GetActivities that made the
(filtering) query, which is then used in GetFilteredActivityCount with
db.Count.
This commit is contained in:
Harvey Tindall
2025-05-27 18:59:50 +01:00
parent eb619b6544
commit 3c87b78dd9
3 changed files with 51 additions and 15 deletions

View File

@@ -86,21 +86,8 @@ func activitySourceToString(v ActivitySource) string {
return "anon"
}
// @Summary Get the requested set of activities, Paginated, filtered and sorted. Is a POST because of some issues I was having, ideally should be a GET.
// @Produce json
// @Param ServerSearchReqDTO body ServerSearchReqDTO true "search parameters"
// @Success 200 {object} GetActivitiesRespDTO
// @Router /activity [post]
// @Security Bearer
// @tags Activity
func (app *appContext) GetActivities(gc *gin.Context) {
req := ServerSearchReqDTO{}
gc.BindJSON(&req)
if req.SortByField == "" {
req.SortByField = USER_DEFAULT_SORT_FIELD
} else {
req.SortByField = activityDTONameToField(req.SortByField)
}
// generateActivitiesQuery generates a badgerhold query from QueryDTOs and search terms, which can then be searched, counted, or whatever you want.
func (app *appContext) generateActivitiesQuery(req ServerFilterReqDTO) *badgerhold.Query {
var query *badgerhold.Query
if len(req.SearchTerms) != 0 {
@@ -120,6 +107,26 @@ func (app *appContext) GetActivities(gc *gin.Context) {
if query == nil {
query = &badgerhold.Query{}
}
return query
}
// @Summary Get the requested set of activities, Paginated, filtered and sorted. Is a POST because of some issues I was having, ideally should be a GET.
// @Produce json
// @Param ServerSearchReqDTO body ServerSearchReqDTO true "search parameters"
// @Success 200 {object} GetActivitiesRespDTO
// @Router /activity [post]
// @Security Bearer
// @tags Activity
func (app *appContext) GetActivities(gc *gin.Context) {
req := ServerSearchReqDTO{}
gc.BindJSON(&req)
if req.SortByField == "" {
req.SortByField = USER_DEFAULT_SORT_FIELD
} else {
req.SortByField = activityDTONameToField(req.SortByField)
}
query := app.generateActivitiesQuery(req.ServerFilterReqDTO)
query = query.SortBy(req.SortByField)
if !req.Ascending {
@@ -188,3 +195,26 @@ func (app *appContext) GetActivityCount(gc *gin.Context) {
}
gc.JSON(200, resp)
}
// @Summary Returns the total number of activities matching the given filtering. Fails silently.
// @Produce json
// @Param ServerFilterReqDTO body ServerFilterReqDTO true "search parameters"
// @Success 200 {object} PageCountDTO
// @Router /activity/count [post]
// @Security Bearer
// @tags Activity
func (app *appContext) GetFilteredActivityCount(gc *gin.Context) {
resp := PageCountDTO{}
req := ServerFilterReqDTO{}
gc.BindJSON(&req)
query := app.generateActivitiesQuery(req)
var err error
resp.Count, err = app.storage.db.Count(&Activity{}, query)
if err != nil {
// app.err.Printf(lm.FailedDBReadActivities, err)
resp.Count = 0
}
gc.JSON(200, resp)
}

View File

@@ -285,6 +285,7 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
api.POST(p+"/activity", app.GetActivities)
api.DELETE(p+"/activity/:id", app.DeleteActivity)
api.GET(p+"/activity/count", app.GetActivityCount)
api.POST(p+"/activity/count", app.GetFilteredActivityCount)
if userPageEnabled {
user.GET("/details", app.MyDetails)

View File

@@ -499,6 +499,11 @@ func (q *QueryDTO) UnmarshalJSON(data []byte) error {
// ServerSearchReqDTO is a usual PaginatedReqDTO with added fields for searching and filtering.
type ServerSearchReqDTO struct {
PaginatedReqDTO
ServerFilterReqDTO
}
// ServerFilterReqDTO provides search terms and queries to a search or count route.
type ServerFilterReqDTO struct {
SearchTerms []string `json:"searchTerms"`
Queries []QueryDTO `json:"queries"`
}