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
46 changes: 40 additions & 6 deletions backend/handlers/assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (h *AssetHandler) CreateAsset(c *gin.Context) {
c.JSON(http.StatusCreated, asset)
}

// ListAssets returns all assets
// ListAssets returns all assets with pagination
func (h *AssetHandler) ListAssets(c *gin.Context) {
cacheKey := "kor:asset:list:page1"

Expand All @@ -98,23 +98,57 @@ func (h *AssetHandler) ListAssets(c *gin.Context) {
}

var assets []models.Asset
var total int64
page, limit := utils.GetPaginationParams(c)

if err := h.db.Find(&assets).Error; err != nil {
if err := utils.Paginate(h.db, page, limit, &total, &assets); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch assets"})
return
}

// Save to Redis
if h.redisClient != nil {
if jsonData, err := json.Marshal(assets); err == nil {
paginationRes := utils.Pagination{
Limit: limit,
Page: page,
Total: total,
Data: assets,
}

// Save to Redis (simplified: only cache page 1 default view for now to match upstream)
if h.redisClient != nil && page == 1 {
if jsonData, err := json.Marshal(paginationRes); err == nil {
ctx := context.Background()
if err := h.redisClient.Set(ctx, cacheKey, jsonData, 5*time.Minute).Err(); err != nil {
log.Printf("Warning: failed to cache list: %v", err)
}
}
}

c.JSON(http.StatusOK, assets)
c.JSON(http.StatusOK, paginationRes)
}

// ListTransactions returns all transactions with pagination
func (h *AssetHandler) ListTransactions(c *gin.Context) {
var transactions []models.Transaction
var total int64
page, limit := utils.GetPaginationParams(c)

// Build query (allow filtering by asset_id if provided)
query := h.db.Model(&models.Transaction{}).Order("created_at desc")
if assetID := c.Query("asset_id"); assetID != "" {
query = query.Where("asset_id = ?", assetID)
}

if err := utils.Paginate(query, page, limit, &total, &transactions); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch transactions"})
return
}

c.JSON(http.StatusOK, utils.Pagination{
Limit: limit,
Page: page,
Total: total,
Data: transactions,
})
}

// GetAsset returns a specific asset
Expand Down
1 change: 1 addition & 0 deletions backend/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func main() {
// Marketplace routes
v1.POST("/marketplace/list", assetHandler.ListAssetForSale)
v1.POST("/marketplace/transfer", assetHandler.TransferAsset)
v1.GET("/transactions", assetHandler.ListTransactions)

// Webhook routes
webhookHandler := handlers.NewWebhookHandler(db)
Expand Down
46 changes: 46 additions & 0 deletions backend/utils/pagination.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package utils

import (
"strconv"

"github.com/gin-gonic/gin"
"gorm.io/gorm"
)

// Pagination represents the pagination parameters and metadata
type Pagination struct {
Limit int `json:"limit"`
Page int `json:"page"`
Total int64 `json:"total"`
Data interface{} `json:"data"`
}

// GetPaginationParams extracts page and limit from query parameters
func GetPaginationParams(c *gin.Context) (int, int) {
limitStr := c.DefaultQuery("limit", "10")
pageStr := c.DefaultQuery("page", "1")

limit, _ := strconv.Atoi(limitStr)
if limit <= 0 || limit > 100 {
limit = 10
}

page, _ := strconv.Atoi(pageStr)
if page <= 0 {
page = 1
}

return page, limit
}

// Paginate applies pagination to a GORM query
func Paginate(db *gorm.DB, page, limit int, total *int64, value interface{}) error {
// Get total count
if err := db.Count(total).Error; err != nil {
return err
}

// Apply offset and limit
offset := (page - 1) * limit
return db.Offset(offset).Limit(limit).Find(value).Error
}
Loading