package controllers import ( "fotbal-club/internal/models" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // ExampleUsageController demonstrates how to use the new utility controllers type ExampleUsageController struct { DB *gorm.DB } // NewExampleUsageController creates a new ExampleUsageController instance func NewExampleUsageController(db *gorm.DB) *ExampleUsageController { return &ExampleUsageController{DB: db} } // ===== EXAMPLE 1: Simple List with Pagination ===== // GET /api/v1/articles?page=1&page_size=20 func (euc *ExampleUsageController) ListArticlesWithPagination(c *gin.Context) { query := euc.DB.Model(&models.Article{}).Where("published = ?", true) var articles []models.Article meta, err := Paginator.Paginate(c, query, &articles) if err != nil { Respond.InternalError(c, "Failed to retrieve articles") return } Respond.SuccessWithMeta(c, articles, meta, "Articles retrieved successfully") } // ===== EXAMPLE 2: List with Search, Sort, and Pagination ===== // GET /api/v1/articles?search=football&sort=created_at:desc&page=1&page_size=20 func (euc *ExampleUsageController) ListArticlesWithFilters(c *gin.Context) { query := QueryParser.BuildQueryChain(c, euc.DB.Model(&models.Article{})). WithSearch("title", "content"). WithSort("created_at", "desc"). Build() var articles []models.Article meta, err := Paginator.PaginateWithPreload(c, query, &articles, "Author", "Category") if err != nil { Respond.InternalError(c, "Failed to retrieve articles") return } Respond.SuccessWithMeta(c, articles, meta, "Articles retrieved successfully") } // ===== EXAMPLE 3: Create with Validation ===== func (euc *ExampleUsageController) CreateArticleWithValidation(c *gin.Context) { var req struct { Title string `json:"title" validate:"required,min=3,max=200"` Content string `json:"content" validate:"required,min=10"` Slug string `json:"slug" validate:"omitempty,slug"` } if err := c.ShouldBindJSON(&req); err != nil { Respond.BadRequest(c, "Invalid JSON: "+err.Error()) return } // Validate using our helper if !Validator.ValidateAndRespond(c, req) { return // Response already sent } // Sanitize inputs req.Title = Validator.SanitizeString(req.Title) req.Slug = Validator.SanitizeSlug(req.Slug) article := models.Article{ Title: req.Title, Content: req.Content, Slug: req.Slug, } if err := euc.DB.Create(&article).Error; err != nil { Respond.InternalError(c, "Failed to create article") return } // Log the creation if AuditLogger != nil { _ = AuditLogger.LogCreate(c, "Article", article.ID, "Article created: "+article.Title) } Respond.Created(c, article, "Article created successfully") } // ===== EXAMPLE 4: Update with Audit Logging ===== func (euc *ExampleUsageController) UpdateArticleWithAudit(c *gin.Context) { id := c.Param("id") var article models.Article if err := euc.DB.First(&article, id).Error; err != nil { if err == gorm.ErrRecordNotFound { Respond.NotFound(c, "Article not found") return } Respond.InternalError(c, "Failed to retrieve article") return } // Store old values for audit oldTitle := article.Title oldPublished := article.Published var req struct { Title string `json:"title" validate:"omitempty,min=3,max=200"` Published *bool `json:"published"` } if err := c.ShouldBindJSON(&req); err != nil { Respond.BadRequest(c, "Invalid JSON: "+err.Error()) return } if !Validator.ValidateAndRespond(c, req) { return } // Apply updates if req.Title != "" { article.Title = Validator.SanitizeString(req.Title) } if req.Published != nil { article.Published = *req.Published } if err := euc.DB.Save(&article).Error; err != nil { Respond.InternalError(c, "Failed to update article") return } // Log the update with changes if AuditLogger != nil { before := map[string]interface{}{ "title": oldTitle, "published": oldPublished, } after := map[string]interface{}{ "title": article.Title, "published": article.Published, } _ = AuditLogger.LogUpdate(c, "Article", article.ID, "Article updated", before, after) } Respond.Success(c, article, "Article updated successfully") } // ===== EXAMPLE 5: Batch Delete ===== // POST /api/v1/articles/batch-delete // Body: {"ids": [1, 2, 3]} func (euc *ExampleUsageController) BatchDeleteArticles(c *gin.Context) { if BatchOps == nil { BatchOps = NewBatchOperationsController(euc.DB) } BatchOps.BatchDelete(c, &models.Article{}, "articles") } // ===== EXAMPLE 6: Advanced Filtering ===== // GET /api/v1/articles?published=true&category_ids=1,2,3&from=2024-01-01&to=2024-12-31 func (euc *ExampleUsageController) ListArticlesAdvanced(c *gin.Context) { query := QueryParser.BuildQueryChain(c, euc.DB.Model(&models.Article{})). WithSearch("title", "content"). WithSort("created_at", "desc"). WithBoolFilter("published", "published"). WithBoolFilter("featured", "featured"). WithIDsFilter("category_ids", "category_id"). WithDateRange("created_at"). Build() var articles []models.Article meta, err := Paginator.PaginateWithPreload(c, query, &articles, "Author", "Category") if err != nil { Respond.InternalError(c, "Failed to retrieve articles") return } Respond.SuccessWithMeta(c, articles, meta, "Articles retrieved successfully") } // ===== EXAMPLE 7: Batch Publish/Unpublish ===== // POST /api/v1/articles/batch-publish // Body: {"ids": [1, 2, 3]} func (euc *ExampleUsageController) BatchPublishArticles(c *gin.Context) { if BatchOps == nil { BatchOps = NewBatchOperationsController(euc.DB) } BatchOps.BatchPublish(c, &models.Article{}, "articles", true) } func (euc *ExampleUsageController) BatchUnpublishArticles(c *gin.Context) { if BatchOps == nil { BatchOps = NewBatchOperationsController(euc.DB) } BatchOps.BatchPublish(c, &models.Article{}, "articles", false) } // ===== EXAMPLE 8: Get Entity with Standard Response ===== func (euc *ExampleUsageController) GetArticle(c *gin.Context) { id := c.Param("id") var article models.Article if err := euc.DB.Preload("Author").Preload("Category").First(&article, id).Error; err != nil { if err == gorm.ErrRecordNotFound { Respond.NotFound(c, "Article not found") return } Respond.InternalError(c, "Failed to retrieve article") return } Respond.Success(c, article, "Article retrieved successfully") } // ===== EXAMPLE 9: Delete with Audit ===== func (euc *ExampleUsageController) DeleteArticleWithAudit(c *gin.Context) { id := c.Param("id") var article models.Article if err := euc.DB.First(&article, id).Error; err != nil { if err == gorm.ErrRecordNotFound { Respond.NotFound(c, "Article not found") return } Respond.InternalError(c, "Failed to retrieve article") return } title := article.Title articleID := article.ID if err := euc.DB.Delete(&article).Error; err != nil { Respond.InternalError(c, "Failed to delete article") return } // Log the deletion if AuditLogger != nil { _ = AuditLogger.LogDelete(c, "Article", articleID, "Article deleted: "+title) } Respond.NoContent(c) } // ===== EXAMPLE 10: Complex Query with Multiple Filters ===== func (euc *ExampleUsageController) SearchArticlesComplex(c *gin.Context) { // Start with base query query := euc.DB.Model(&models.Article{}) // Get search term searchTerm := QueryParser.GetSearchQuery(c) if searchTerm != "" { query = QueryParser.ApplySearch(query, searchTerm, "title", "content", "seo_description") } // Apply boolean filters if published := QueryParser.GetBoolQuery(c, "published"); published != nil { query = query.Where("published = ?", *published) } if featured := QueryParser.GetBoolQuery(c, "featured"); featured != nil { query = query.Where("featured = ?", *featured) } // Apply category filter if categoryID := c.Query("category_id"); categoryID != "" { query = query.Where("category_id = ?", categoryID) } // Apply date range from, to := QueryParser.GetDateRange(c) if from != "" { query = query.Where("created_at >= ?", from) } if to != "" { query = query.Where("created_at <= ?", to) } // Apply sorting query = QueryParser.ApplySortFromContext(c, query, "created_at", "desc") // Execute with pagination var articles []models.Article meta, err := Paginator.PaginateWithPreload(c, query, &articles, "Author", "Category") if err != nil { Respond.InternalError(c, "Failed to search articles") return } Respond.SuccessWithMeta(c, articles, meta, "Search completed successfully") }