Skip to content

Add solution for gin challenge-3-validation-errors by yogtanko#1746

Merged
github-actions[bot] merged 2 commits into
RezaSi:mainfrom
yogtanko:package-gin-challenge-3-validation-errors-yogtanko
May 30, 2026
Merged

Add solution for gin challenge-3-validation-errors by yogtanko#1746
github-actions[bot] merged 2 commits into
RezaSi:mainfrom
yogtanko:package-gin-challenge-3-validation-errors-yogtanko

Conversation

@yogtanko
Copy link
Copy Markdown
Contributor

gin challenge-3-validation-errors Solution

Submitted by: @yogtanko
Package: gin
Challenge: challenge-3-validation-errors

Description

This PR contains my solution for gin challenge-3-validation-errors.

Changes

  • Added solution file to packages/gin/challenge-3-validation-errors/submissions/yogtanko/solution.go

Testing

  • Solution passes all test cases
  • Code follows Go best practices

Thank you for reviewing my submission! 🚀

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 30, 2026

Review Change Stack

Walkthrough

Adds a Gin-based HTTP service providing in-memory product and category models, field and cross-field validation, sanitization, endpoints for single/bulk creation and validation checks, a validation-rules endpoint, and server startup on :8080.

Changes

Product & Category API with Validation

Layer / File(s) Summary
Data Types & Validation Contracts
packages/gin/challenge-3-validation-errors/submissions/yogtanko/solution.go
Product, Category, Image, and Inventory types are defined with JSON tags and binding constraints. ValidationError and APIResponse provide structured error and response envelopes.
Validation Helpers & Core Logic
packages/gin/challenge-3-validation-errors/submissions/yogtanko/solution.go
In-memory product/category stores with sync.RWMutex, SKU/slug/currency/warehouse validators, validateProduct for field and cross-field checks, and sanitizeProduct for normalization and inventory computation.
Product Creation
packages/gin/challenge-3-validation-errors/submissions/yogtanko/solution.go
createProduct binds, validates, sanitizes, assigns an ID, and persists a product. createProductsBulk validates items independently, returns per-index results, persists valid items with incrementing IDs, and returns summary counts.
Category & Validation Endpoints
packages/gin/challenge-3-validation-errors/submissions/yogtanko/solution.go
createCategory enforces slug format and case-insensitive name uniqueness under a write lock. validateSKUEndpoint checks SKU format/duplication. validateProductEndpoint validates payloads without saving.
Rules Endpoint & Server Setup
packages/gin/challenge-3-validation-errors/submissions/yogtanko/solution.go
getValidationRules returns supported currencies and warehouse codes. setupRouter wires routes and main starts the Gin server on :8080.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 In a meadow of JSON and code I hop,
I trim the strings and make stray spaces stop,
I validate SKUs and counts with care,
I stamp timestamps and store them there,
Hopping off—products neat, tidy, and top!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a solution file for a specific gin challenge by a named author.
Description check ✅ Passed The description is clearly related to the changeset, explaining the challenge submission, file location, and validation checks performed.
Docstring Coverage ✅ Passed Docstring coverage is 86.67% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 89300fce-03da-4b40-b9a5-3871abb87189

📥 Commits

Reviewing files that changed from the base of the PR and between aa037e3 and fd0f48f.

📒 Files selected for processing (1)
  • packages/gin/challenge-3-validation-errors/submissions/yogtanko/solution.go

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/gin/challenge-3-validation-errors/submissions/yogtanko/solution.go (2)

157-164: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

SKU uniqueness is still not enforced at write time.

validateProduct checks SKU format only, and both create paths append without an atomic uniqueness guard. Concurrent requests can persist duplicate SKUs.

Suggested fix
 func createProduct(c *gin.Context) {
@@
 	sanitizeProduct(&product)
-    mu.Lock()
-    defer mu.Unlock()
+	mu.Lock()
+	for _, existing := range products {
+		if strings.EqualFold(existing.SKU, product.SKU) {
+			mu.Unlock()
+			c.JSON(http.StatusBadRequest, APIResponse{
+				Success: false,
+				Message: "sku already exists",
+			})
+			return
+		}
+	}
 	product.ID = nextProductID
 	nextProductID++
 	products = append(products, product)
+	mu.Unlock()

 	c.JSON(201, APIResponse{
@@
 	for i, product := range inputProducts {
@@
 		} else {
 			sanitizeProduct(&product)
 			mu.Lock()
+			duplicate := false
+			for _, existing := range products {
+				if strings.EqualFold(existing.SKU, product.SKU) {
+					duplicate = true
+					break
+				}
+			}
+			if duplicate {
+				mu.Unlock()
+				results = append(results, BulkResult{
+					Index:   i,
+					Success: false,
+					Errors: []ValidationError{{
+						Field:   "sku",
+						Message: "sku already exists",
+					}},
+				})
+				continue
+			}
 			product.ID = nextProductID
 			nextProductID++
 			products = append(products, product)
 			mu.Unlock()

Also applies to: 251-256, 299-303


118-120: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Category validation is case-sensitive and inconsistent with category creation rules.

isValidCategory uses exact match, while category uniqueness uses strings.EqualFold. This can reject otherwise valid category names by casing alone.

Suggested fix
-	for _, cur := range categories {
-		if cur.Name == categoryName {
+	for _, cur := range categories {
+		if strings.EqualFold(cur.Name, categoryName) {
 			return true
 		}
 	}

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 39ff678e-148d-4b61-a375-63086fa912b0

📥 Commits

Reviewing files that changed from the base of the PR and between fd0f48f and f2091c3.

📒 Files selected for processing (1)
  • packages/gin/challenge-3-validation-errors/submissions/yogtanko/solution.go

@github-actions github-actions Bot merged commit 636b0f2 into RezaSi:main May 30, 2026
6 checks passed
@github-actions
Copy link
Copy Markdown

🎉 Auto-merged!

This PR was automatically merged after 2 days with all checks passing.

Thank you for your contribution, @yogtanko!

📊 Scoreboards and badges will be updated shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant