Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions backend-go/internal/controller/lost.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import (
"fmt"
"net/http"
"os"
"sort"
"strconv"
"time"

"github.com/LambdaIITH/Dashboard/backend/config"
lost "github.com/LambdaIITH/Dashboard/backend/internal/db"
Expand Down Expand Up @@ -133,6 +135,83 @@ func GetAllItemsHandler(c *gin.Context) {
c.JSON(http.StatusOK, response)
}

/*
GetCombinedAllItemsHandler fetches all the lost and found items and returns them as a JSON response ordered by creation time.
*/
func GetCombinedAllItemsHandler(c *gin.Context) {

maxLimit := 100
if limitStr := c.Query("max_limit"); limitStr != "" {
if limit, err := strconv.Atoi(limitStr); err == nil {
maxLimit = limit
Comment on lines +144 to +146

Copilot AI Jan 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing input validation for max_limit parameter. If a user provides a negative value or zero, the code will accept it and could produce unexpected results. Consider adding validation to ensure max_limit is positive, and potentially also adding an upper bound to prevent resource exhaustion from extremely large values.

Suggested change
if limitStr := c.Query("max_limit"); limitStr != "" {
if limit, err := strconv.Atoi(limitStr); err == nil {
maxLimit = limit
const maxAllowedLimit = 1000
if limitStr := c.Query("max_limit"); limitStr != "" {
if limit, err := strconv.Atoi(limitStr); err == nil {
if limit > 0 {
if limit > maxAllowedLimit {
maxLimit = maxAllowedLimit
} else {
maxLimit = limit
}
}

Copilot uses AI. Check for mistakes.
}
}

//Step 1: Fetching lost items AND found items
lostItems, err := lost.GetAllLostItems(c)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to fetch items"})

return
}


foundItems, err := lost.GetAllFoundItems(c)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to fetch items"})
return
}



//Step 2: Initialize response slice
response := make([]map[string]any, 0, len(lostItems)+len(foundItems))

for _, item := range lostItems {
images := item.Images
if images == nil {
images = []string{}
}

itemData := map[string]any{
"id": item.ID,
"name": item.ItemName,
"images": images,
"created_at": item.CreatedAt,
"type": "lost",
}
response = append(response, itemData)
}
for _, item := range foundItems {
images := item.Images
if images == nil {
images = []string{}
}

itemData := map[string]any{
"id": item.ID,
"name": item.ItemName,
"images": images,
"created_at": item.CreatedAt,
"type": "found",
}
response = append(response, itemData)
}

sort.Slice(response, func(i, j int) bool {
t1 := response[i]["created_at"].(time.Time)
t2 := response[j]["created_at"].(time.Time)
return t1.After(t2) // newest first
})

if len(response) > maxLimit {
response = response[:maxLimit]
}

// Step 4: Return the response
c.JSON(http.StatusOK, response)
}

/*
GetItemByIdHandler fetches a particular lost item by its ID and returns it as a JSON response.
*/
Expand Down
6 changes: 6 additions & 0 deletions backend-go/internal/router/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ func SetupRoutes(router *gin.Engine) {
foundGroup.GET("/search", controller.SearchFoundItemHandler)
}

//Group routes for lost-found items
lostFoundGroup := router.Group("/lost_found")
{
lostFoundGroup.GET("/", controller.GetCombinedAllItemsHandler) //optional parameter max_limit
}

//Group routes for timetable/calendar
timetableGroup := router.Group("/schedule")
{
Expand Down