feat: Add storage hierarchy API and frontend integration
This commit is contained in:
parent
005b04e380
commit
29ec555090
6 changed files with 264 additions and 10 deletions
31
api/api.go
Normal file
31
api/api.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
|
||||
db "github.com/your-username/your-repo/database/sqlite/generated"
|
||||
)
|
||||
|
||||
// API holds all API handlers
|
||||
type API struct {
|
||||
Storage *StorageHandler
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// New creates a new API instance
|
||||
func New(dbQueries *db.Queries, logger *zap.Logger) *API {
|
||||
return &API{
|
||||
Storage: NewStorageHandler(dbQueries, logger),
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterRoutes registers all API routes
|
||||
func (a *API) RegisterRoutes(e *echo.Echo, middleware echo.MiddlewareFunc) {
|
||||
// Create API group with middleware
|
||||
api := e.Group("/api/v1", middleware)
|
||||
|
||||
// Register routes for each handler
|
||||
a.Storage.RegisterRoutes(api)
|
||||
}
|
193
api/storage.go
Normal file
193
api/storage.go
Normal file
|
@ -0,0 +1,193 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
|
||||
db "github.com/your-username/your-repo/database/sqlite/generated"
|
||||
)
|
||||
|
||||
type StorageHandler struct {
|
||||
db *db.Queries
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewStorageHandler(db *db.Queries, logger *zap.Logger) *StorageHandler {
|
||||
return &StorageHandler{
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// GetStorageSpaces returns all storage spaces
|
||||
func (h *StorageHandler) GetStorageSpaces(c echo.Context) error {
|
||||
ctx := context.Background()
|
||||
|
||||
storageSpaces, err := h.db.GetAllStorageSpaces(ctx)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to fetch storage spaces", zap.Error(err))
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{
|
||||
"error": "Failed to fetch storage spaces",
|
||||
})
|
||||
}
|
||||
|
||||
// Convert to a format suitable for the frontend
|
||||
result := make([]map[string]interface{}, len(storageSpaces))
|
||||
for i, space := range storageSpaces {
|
||||
result[i] = map[string]interface{}{
|
||||
"id": space.ID,
|
||||
"parent": space.Parent,
|
||||
"location": space.Location,
|
||||
}
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, result)
|
||||
}
|
||||
|
||||
// GetObjectsInStorage returns all objects in a specific storage space
|
||||
func (h *StorageHandler) GetObjectsInStorage(c echo.Context) error {
|
||||
ctx := context.Background()
|
||||
|
||||
// Parse storage ID from URL
|
||||
storageIDStr := c.Param("id")
|
||||
storageID, err := strconv.ParseInt(storageIDStr, 10, 64)
|
||||
if err != nil {
|
||||
h.logger.Warn("Invalid storage ID", zap.String("id", storageIDStr))
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{
|
||||
"error": "Invalid storage ID",
|
||||
})
|
||||
}
|
||||
|
||||
// Check if storage exists
|
||||
_, err = h.db.GetStorageSpaceByID(ctx, storageID)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return c.JSON(http.StatusNotFound, map[string]string{
|
||||
"error": "Storage space not found",
|
||||
})
|
||||
}
|
||||
h.logger.Error("Failed to fetch storage space", zap.Error(err))
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{
|
||||
"error": "Failed to fetch storage space",
|
||||
})
|
||||
}
|
||||
|
||||
// Get objects in this storage
|
||||
objects, err := h.db.GetObjectsByStorageID(ctx, storageID)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to fetch objects in storage", zap.Error(err))
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{
|
||||
"error": "Failed to fetch objects in storage",
|
||||
})
|
||||
}
|
||||
|
||||
// Convert to a format suitable for the frontend
|
||||
result := make([]map[string]interface{}, len(objects))
|
||||
for i, obj := range objects {
|
||||
result[i] = map[string]interface{}{
|
||||
"id": obj.ID,
|
||||
"name": obj.Name,
|
||||
"storagespaceId": obj.StoragespaceID,
|
||||
"description": obj.Description.String,
|
||||
"serialnumber": obj.Serialnumber.String,
|
||||
}
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, result)
|
||||
}
|
||||
|
||||
// GetStorageHierarchyObjects returns all objects in a storage hierarchy
|
||||
func (h *StorageHandler) GetStorageHierarchyObjects(c echo.Context) error {
|
||||
ctx := context.Background()
|
||||
|
||||
// Parse root storage ID from URL
|
||||
rootStorageIDStr := c.Param("id")
|
||||
rootStorageID, err := strconv.ParseInt(rootStorageIDStr, 10, 64)
|
||||
if err != nil {
|
||||
h.logger.Warn("Invalid storage ID", zap.String("id", rootStorageIDStr))
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{
|
||||
"error": "Invalid storage ID",
|
||||
})
|
||||
}
|
||||
|
||||
// Check if root storage exists
|
||||
_, err = h.db.GetStorageSpaceByID(ctx, rootStorageID)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return c.JSON(http.StatusNotFound, map[string]string{
|
||||
"error": "Storage space not found",
|
||||
})
|
||||
}
|
||||
h.logger.Error("Failed to fetch storage space", zap.Error(err))
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{
|
||||
"error": "Failed to fetch storage space",
|
||||
})
|
||||
}
|
||||
|
||||
// Get all storage spaces to build the hierarchy
|
||||
allStorageSpaces, err := h.db.GetAllStorageSpaces(ctx)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to fetch all storage spaces", zap.Error(err))
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{
|
||||
"error": "Failed to fetch storage hierarchy",
|
||||
})
|
||||
}
|
||||
|
||||
// Build a list of all storage IDs in the hierarchy
|
||||
storageIDs := []int64{rootStorageID}
|
||||
storageIDs = append(storageIDs, h.getChildStorageIDs(allStorageSpaces, rootStorageID)...)
|
||||
|
||||
// Get objects for all storage spaces in the hierarchy
|
||||
var allObjects []map[string]interface{}
|
||||
|
||||
for _, storageID := range storageIDs {
|
||||
// Get objects in this storage
|
||||
objects, err := h.db.GetObjectsByStorageID(ctx, storageID)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to fetch objects in storage",
|
||||
zap.Int64("storageID", storageID),
|
||||
zap.Error(err))
|
||||
continue // Skip this storage if there's an error
|
||||
}
|
||||
|
||||
// Convert to a format suitable for the frontend
|
||||
for _, obj := range objects {
|
||||
allObjects = append(allObjects, map[string]interface{}{
|
||||
"id": obj.ID,
|
||||
"name": obj.Name,
|
||||
"storagespaceId": obj.StoragespaceID,
|
||||
"description": obj.Description.String,
|
||||
"serialnumber": obj.Serialnumber.String,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, allObjects)
|
||||
}
|
||||
|
||||
// Helper function to recursively get all child storage IDs
|
||||
func (h *StorageHandler) getChildStorageIDs(spaces []db.Storagespace, parentID int64) []int64 {
|
||||
var childIDs []int64
|
||||
|
||||
for _, space := range spaces {
|
||||
if space.Parent.Valid && space.Parent.Int64 == parentID {
|
||||
childIDs = append(childIDs, space.ID)
|
||||
// Recursively get children of this child
|
||||
childIDs = append(childIDs, h.getChildStorageIDs(spaces, space.ID)...)
|
||||
}
|
||||
}
|
||||
|
||||
return childIDs
|
||||
}
|
||||
|
||||
// RegisterRoutes registers all storage-related routes
|
||||
func (h *StorageHandler) RegisterRoutes(g *echo.Group) {
|
||||
g.GET("/storageSpaces", h.GetStorageSpaces)
|
||||
g.GET("/storageSpaces/:id/objects", h.GetObjectsInStorage)
|
||||
g.GET("/storageSpaces/:id/hierarchy/objects", h.GetStorageHierarchyObjects)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue