fix: enable component search and pricing in offline mode
**Problem:** Configurator was broken in offline mode - no component search and no price calculation because /api/components returned empty list. **Solution:** Added local component fallback to ComponentHandler: 1. **ComponentHandler with localDB** (component.go) - Added localDB parameter to NewComponentHandler - List() now fallbacks to local_components when offline - Converts LocalComponent to ComponentView format - Preserves prices from local cache 2. **Updated initialization** (main.go) - Pass localDB to NewComponentHandler **Impact:** - ✅ Component search works offline - ✅ Prices load from local_components table - ✅ Configuration creation fully functional offline - ✅ Price calculation works with cached prices **Testing:** - Verified /api/components returns local components - Verified current_price field populated from cache - Search, filtering, and pagination work correctly Fixes critical Phase 2.5 offline mode issue. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -364,7 +364,7 @@ func setupRouter(cfg *config.Config, local *localdb.LocalDB, connMgr *db.Connect
|
|||||||
configService := services.NewLocalConfigurationService(local, syncService, quoteService, isOnline)
|
configService := services.NewLocalConfigurationService(local, syncService, quoteService, isOnline)
|
||||||
|
|
||||||
// Handlers
|
// Handlers
|
||||||
componentHandler := handlers.NewComponentHandler(componentService)
|
componentHandler := handlers.NewComponentHandler(componentService, local)
|
||||||
quoteHandler := handlers.NewQuoteHandler(quoteService)
|
quoteHandler := handlers.NewQuoteHandler(quoteService)
|
||||||
exportHandler := handlers.NewExportHandler(exportService, configService, componentService)
|
exportHandler := handlers.NewExportHandler(exportService, configService, componentService)
|
||||||
pricingHandler := handlers.NewPricingHandler(mariaDB, pricingService, alertService, componentRepo, priceRepo, statsRepo)
|
pricingHandler := handlers.NewPricingHandler(mariaDB, pricingService, alertService, componentRepo, priceRepo, statsRepo)
|
||||||
|
|||||||
@@ -5,16 +5,21 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"git.mchus.pro/mchus/quoteforge/internal/localdb"
|
||||||
"git.mchus.pro/mchus/quoteforge/internal/repository"
|
"git.mchus.pro/mchus/quoteforge/internal/repository"
|
||||||
"git.mchus.pro/mchus/quoteforge/internal/services"
|
"git.mchus.pro/mchus/quoteforge/internal/services"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ComponentHandler struct {
|
type ComponentHandler struct {
|
||||||
componentService *services.ComponentService
|
componentService *services.ComponentService
|
||||||
|
localDB *localdb.LocalDB
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewComponentHandler(componentService *services.ComponentService) *ComponentHandler {
|
func NewComponentHandler(componentService *services.ComponentService, localDB *localdb.LocalDB) *ComponentHandler {
|
||||||
return &ComponentHandler{componentService: componentService}
|
return &ComponentHandler{
|
||||||
|
componentService: componentService,
|
||||||
|
localDB: localDB,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ComponentHandler) List(c *gin.Context) {
|
func (h *ComponentHandler) List(c *gin.Context) {
|
||||||
@@ -34,6 +39,40 @@ func (h *ComponentHandler) List(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If offline mode (empty result), fallback to local components
|
||||||
|
if result.Total == 0 && h.localDB != nil {
|
||||||
|
localFilter := localdb.ComponentFilter{
|
||||||
|
Category: filter.Category,
|
||||||
|
Search: filter.Search,
|
||||||
|
HasPrice: filter.HasPrice,
|
||||||
|
}
|
||||||
|
|
||||||
|
offset := (page - 1) * perPage
|
||||||
|
localComps, total, err := h.localDB.ListComponents(localFilter, offset, perPage)
|
||||||
|
if err == nil && len(localComps) > 0 {
|
||||||
|
// Convert local components to ComponentView format
|
||||||
|
components := make([]services.ComponentView, len(localComps))
|
||||||
|
for i, lc := range localComps {
|
||||||
|
components[i] = services.ComponentView{
|
||||||
|
LotName: lc.LotName,
|
||||||
|
Description: lc.LotDescription,
|
||||||
|
Category: lc.Category,
|
||||||
|
CategoryName: lc.Category, // No translation in local mode
|
||||||
|
Model: lc.Model,
|
||||||
|
CurrentPrice: lc.CurrentPrice,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, &services.ComponentListResult{
|
||||||
|
Components: components,
|
||||||
|
Total: total,
|
||||||
|
Page: page,
|
||||||
|
PerPage: perPage,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, result)
|
c.JSON(http.StatusOK, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user