refactor: устранить дублирование кода (Go-хендлеры, JS-автокомплит)

Найдено статическим анализом (dupl/jscpd) + проверено вручную:

Go:
- appstate/path.go: ResolveDBPath/ResolveConfigPath → общий resolvePath()
- handlers/respond.go: дженерик BindJSON[T] для bind+422-ошибки
- article/generator.go: buildNetSegment/buildPSUSegment → buildProfileSegment()
- cmd/qfs/main.go (+respond.go): 8 повторяющихся switch{case errors.Is(...)}
  → respondByErrCase(c, err, errCase{...}, ...)

Frontend (index.html):
- 5 идентичных обработчиков клавиатурной навигации автокомплита
  → handleAutocompleteKeyGeneric(event, onSelect)
- 4 функции сборки нового элемента корзины из автокомплита
  → buildNewCartItem()/commitCartChange()

Также: PricingMarkup — единая точка правды для аплифт-коэффициента
в JS (render + export), с cross-reference комментариями к Go-константам
в export.go (defaultSaleMarkup/stockCompetitorMarkupFactor).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-08-10 20:13:27 +03:00
co-authored by Claude Sonnet 5
parent b087b7eb58
commit 4d7b0e13ef
8 changed files with 199 additions and 314 deletions
+12
View File
@@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"io"
"net/http"
"strings"
"github.com/gin-gonic/gin"
@@ -16,6 +17,17 @@ func RespondError(c *gin.Context, status int, fallback string, err error) {
c.JSON(status, gin.H{"error": clientFacingErrorMessage(status, fallback, err)})
}
// BindJSON decodes the request body into T, responding with a 422 and writing
// the error via RespondError on failure. The second return value reports success.
func BindJSON[T any](c *gin.Context) (*T, bool) {
var req T
if err := c.ShouldBindJSON(&req); err != nil {
RespondError(c, http.StatusUnprocessableEntity, "invalid request", err)
return nil, false
}
return &req, true
}
func clientFacingErrorMessage(status int, fallback string, err error) string {
if err == nil {
return fallback