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:
co-authored by
Claude Sonnet 5
parent
b087b7eb58
commit
4d7b0e13ef
+52
-99
@@ -1101,16 +1101,11 @@ func setupRouter(cfg *config.Config, local *localdb.LocalDB, connMgr *db.Connect
|
||||
|
||||
config, err := configService.UpdateNoAuth(uuid, &req)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, services.ErrConfigNotFound):
|
||||
respondError(c, http.StatusNotFound, "resource not found", err)
|
||||
case errors.Is(err, services.ErrProjectNotFound):
|
||||
respondError(c, http.StatusNotFound, "resource not found", err)
|
||||
case errors.Is(err, services.ErrProjectForbidden):
|
||||
respondError(c, http.StatusForbidden, "access denied", err)
|
||||
default:
|
||||
respondError(c, http.StatusInternalServerError, "internal server error", err)
|
||||
}
|
||||
respondByErrCase(c, err,
|
||||
errCase{services.ErrConfigNotFound, http.StatusNotFound, "resource not found"},
|
||||
errCase{services.ErrProjectNotFound, http.StatusNotFound, "resource not found"},
|
||||
errCase{services.ErrProjectForbidden, http.StatusForbidden, "access denied"},
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1217,16 +1212,11 @@ func setupRouter(cfg *config.Config, local *localdb.LocalDB, connMgr *db.Connect
|
||||
}
|
||||
updated, err := configService.SetProjectNoAuth(uuid, req.ProjectUUID)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, services.ErrConfigNotFound):
|
||||
respondError(c, http.StatusNotFound, "resource not found", err)
|
||||
case errors.Is(err, services.ErrProjectNotFound):
|
||||
respondError(c, http.StatusNotFound, "resource not found", err)
|
||||
case errors.Is(err, services.ErrProjectForbidden):
|
||||
respondError(c, http.StatusForbidden, "access denied", err)
|
||||
default:
|
||||
respondError(c, http.StatusInternalServerError, "internal server error", err)
|
||||
}
|
||||
respondByErrCase(c, err,
|
||||
errCase{services.ErrConfigNotFound, http.StatusNotFound, "resource not found"},
|
||||
errCase{services.ErrProjectNotFound, http.StatusNotFound, "resource not found"},
|
||||
errCase{services.ErrProjectForbidden, http.StatusForbidden, "access denied"},
|
||||
)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, updated)
|
||||
@@ -1354,12 +1344,9 @@ func setupRouter(cfg *config.Config, local *localdb.LocalDB, connMgr *db.Connect
|
||||
}
|
||||
config, err := configService.UpdateRentalNoAuth(c.Param("uuid"), &req)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, services.ErrConfigNotFound):
|
||||
respondError(c, http.StatusNotFound, "resource not found", err)
|
||||
default:
|
||||
respondError(c, http.StatusInternalServerError, "internal server error", err)
|
||||
}
|
||||
respondByErrCase(c, err,
|
||||
errCase{services.ErrConfigNotFound, http.StatusNotFound, "resource not found"},
|
||||
)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, config)
|
||||
@@ -1373,12 +1360,9 @@ func setupRouter(cfg *config.Config, local *localdb.LocalDB, connMgr *db.Connect
|
||||
}
|
||||
result, err := rentalService.Calculate(c.Param("uuid"), &req)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, services.ErrConfigNotFound):
|
||||
respondError(c, http.StatusNotFound, "resource not found", err)
|
||||
default:
|
||||
respondError(c, http.StatusInternalServerError, "internal server error", err)
|
||||
}
|
||||
respondByErrCase(c, err,
|
||||
errCase{services.ErrConfigNotFound, http.StatusNotFound, "resource not found"},
|
||||
)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, result)
|
||||
@@ -1627,16 +1611,12 @@ func setupRouter(cfg *config.Config, local *localdb.LocalDB, connMgr *db.Connect
|
||||
}
|
||||
project, err := projectService.Create(dbUsername, &req)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, services.ErrReservedMainVariant),
|
||||
errors.Is(err, services.ErrProjectCodeInvalidChars),
|
||||
errors.Is(err, services.ErrProjectVariantInvalidChars):
|
||||
respondError(c, http.StatusBadRequest, "invalid request", err)
|
||||
case errors.Is(err, services.ErrProjectCodeExists):
|
||||
respondError(c, http.StatusConflict, "conflict detected", err)
|
||||
default:
|
||||
respondError(c, http.StatusInternalServerError, "internal server error", err)
|
||||
}
|
||||
respondByErrCase(c, err,
|
||||
errCase{services.ErrReservedMainVariant, http.StatusBadRequest, "invalid request"},
|
||||
errCase{services.ErrProjectCodeInvalidChars, http.StatusBadRequest, "invalid request"},
|
||||
errCase{services.ErrProjectVariantInvalidChars, http.StatusBadRequest, "invalid request"},
|
||||
errCase{services.ErrProjectCodeExists, http.StatusConflict, "conflict detected"},
|
||||
)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusCreated, project)
|
||||
@@ -1645,14 +1625,10 @@ func setupRouter(cfg *config.Config, local *localdb.LocalDB, connMgr *db.Connect
|
||||
projects.GET("/:uuid", func(c *gin.Context) {
|
||||
project, err := projectService.GetByUUID(c.Param("uuid"), dbUsername)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, services.ErrProjectNotFound):
|
||||
respondError(c, http.StatusNotFound, "resource not found", err)
|
||||
case errors.Is(err, services.ErrProjectForbidden):
|
||||
respondError(c, http.StatusForbidden, "access denied", err)
|
||||
default:
|
||||
respondError(c, http.StatusInternalServerError, "internal server error", err)
|
||||
}
|
||||
respondByErrCase(c, err,
|
||||
errCase{services.ErrProjectNotFound, http.StatusNotFound, "resource not found"},
|
||||
errCase{services.ErrProjectForbidden, http.StatusForbidden, "access denied"},
|
||||
)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, project)
|
||||
@@ -1666,21 +1642,15 @@ func setupRouter(cfg *config.Config, local *localdb.LocalDB, connMgr *db.Connect
|
||||
}
|
||||
project, err := projectService.Update(c.Param("uuid"), dbUsername, &req)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, services.ErrReservedMainVariant),
|
||||
errors.Is(err, services.ErrCannotRenameMainVariant),
|
||||
errors.Is(err, services.ErrProjectCodeInvalidChars),
|
||||
errors.Is(err, services.ErrProjectVariantInvalidChars):
|
||||
respondError(c, http.StatusBadRequest, "invalid request", err)
|
||||
case errors.Is(err, services.ErrProjectCodeExists):
|
||||
respondError(c, http.StatusConflict, "conflict detected", err)
|
||||
case errors.Is(err, services.ErrProjectNotFound):
|
||||
respondError(c, http.StatusNotFound, "resource not found", err)
|
||||
case errors.Is(err, services.ErrProjectForbidden):
|
||||
respondError(c, http.StatusForbidden, "access denied", err)
|
||||
default:
|
||||
respondError(c, http.StatusInternalServerError, "internal server error", err)
|
||||
}
|
||||
respondByErrCase(c, err,
|
||||
errCase{services.ErrReservedMainVariant, http.StatusBadRequest, "invalid request"},
|
||||
errCase{services.ErrCannotRenameMainVariant, http.StatusBadRequest, "invalid request"},
|
||||
errCase{services.ErrProjectCodeInvalidChars, http.StatusBadRequest, "invalid request"},
|
||||
errCase{services.ErrProjectVariantInvalidChars, http.StatusBadRequest, "invalid request"},
|
||||
errCase{services.ErrProjectCodeExists, http.StatusConflict, "conflict detected"},
|
||||
errCase{services.ErrProjectNotFound, http.StatusNotFound, "resource not found"},
|
||||
errCase{services.ErrProjectForbidden, http.StatusForbidden, "access denied"},
|
||||
)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, project)
|
||||
@@ -1688,14 +1658,10 @@ func setupRouter(cfg *config.Config, local *localdb.LocalDB, connMgr *db.Connect
|
||||
|
||||
projects.POST("/:uuid/archive", func(c *gin.Context) {
|
||||
if err := projectService.Archive(c.Param("uuid"), dbUsername); err != nil {
|
||||
switch {
|
||||
case errors.Is(err, services.ErrProjectNotFound):
|
||||
respondError(c, http.StatusNotFound, "resource not found", err)
|
||||
case errors.Is(err, services.ErrProjectForbidden):
|
||||
respondError(c, http.StatusForbidden, "access denied", err)
|
||||
default:
|
||||
respondError(c, http.StatusInternalServerError, "internal server error", err)
|
||||
}
|
||||
respondByErrCase(c, err,
|
||||
errCase{services.ErrProjectNotFound, http.StatusNotFound, "resource not found"},
|
||||
errCase{services.ErrProjectForbidden, http.StatusForbidden, "access denied"},
|
||||
)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"message": "project archived"})
|
||||
@@ -1703,14 +1669,10 @@ func setupRouter(cfg *config.Config, local *localdb.LocalDB, connMgr *db.Connect
|
||||
|
||||
projects.POST("/:uuid/reactivate", func(c *gin.Context) {
|
||||
if err := projectService.Reactivate(c.Param("uuid"), dbUsername); err != nil {
|
||||
switch {
|
||||
case errors.Is(err, services.ErrProjectNotFound):
|
||||
respondError(c, http.StatusNotFound, "resource not found", err)
|
||||
case errors.Is(err, services.ErrProjectForbidden):
|
||||
respondError(c, http.StatusForbidden, "access denied", err)
|
||||
default:
|
||||
respondError(c, http.StatusInternalServerError, "internal server error", err)
|
||||
}
|
||||
respondByErrCase(c, err,
|
||||
errCase{services.ErrProjectNotFound, http.StatusNotFound, "resource not found"},
|
||||
errCase{services.ErrProjectForbidden, http.StatusForbidden, "access denied"},
|
||||
)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"message": "project reactivated"})
|
||||
@@ -1718,16 +1680,11 @@ func setupRouter(cfg *config.Config, local *localdb.LocalDB, connMgr *db.Connect
|
||||
|
||||
projects.DELETE("/:uuid", func(c *gin.Context) {
|
||||
if err := projectService.DeleteVariant(c.Param("uuid"), dbUsername); err != nil {
|
||||
switch {
|
||||
case errors.Is(err, services.ErrCannotDeleteMainVariant):
|
||||
respondError(c, http.StatusBadRequest, "invalid request", err)
|
||||
case errors.Is(err, services.ErrProjectNotFound):
|
||||
respondError(c, http.StatusNotFound, "resource not found", err)
|
||||
case errors.Is(err, services.ErrProjectForbidden):
|
||||
respondError(c, http.StatusForbidden, "access denied", err)
|
||||
default:
|
||||
respondError(c, http.StatusInternalServerError, "internal server error", err)
|
||||
}
|
||||
respondByErrCase(c, err,
|
||||
errCase{services.ErrCannotDeleteMainVariant, http.StatusBadRequest, "invalid request"},
|
||||
errCase{services.ErrProjectNotFound, http.StatusNotFound, "resource not found"},
|
||||
errCase{services.ErrProjectForbidden, http.StatusForbidden, "access denied"},
|
||||
)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"message": "variant deleted"})
|
||||
@@ -1744,14 +1701,10 @@ func setupRouter(cfg *config.Config, local *localdb.LocalDB, connMgr *db.Connect
|
||||
|
||||
result, err := projectService.ListConfigurations(c.Param("uuid"), dbUsername, status)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, services.ErrProjectNotFound):
|
||||
respondError(c, http.StatusNotFound, "resource not found", err)
|
||||
case errors.Is(err, services.ErrProjectForbidden):
|
||||
respondError(c, http.StatusForbidden, "access denied", err)
|
||||
default:
|
||||
respondError(c, http.StatusInternalServerError, "internal server error", err)
|
||||
}
|
||||
respondByErrCase(c, err,
|
||||
errCase{services.ErrProjectNotFound, http.StatusNotFound, "resource not found"},
|
||||
errCase{services.ErrProjectForbidden, http.StatusForbidden, "access denied"},
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user