diff --git a/.gitignore b/.gitignore index 7fbecd2..3eda301 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,7 @@ node_modules .output .env dist + +.pnpm-store +devData +backend/app/api/app \ No newline at end of file diff --git a/backend/app/api/handlers/assetIds/redirect.go b/backend/app/api/handlers/assetIds/redirect.go new file mode 100644 index 0000000..41d8991 --- /dev/null +++ b/backend/app/api/handlers/assetIds/redirect.go @@ -0,0 +1,45 @@ +package assetIds + +import ( + "net/http" + "strconv" + "strings" + + "github.com/rs/zerolog/log" + + "github.com/go-chi/chi/v5" + "github.com/hay-kot/homebox/backend/internal/data/repo" + "github.com/hay-kot/homebox/backend/pkgs/server" +) + +func HandleAssetRedirect(repos *repo.AllRepos) server.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) error { + // Get the asset ID from the URL + assetIdParam := chi.URLParam(r, "id") + assetIdParam = strings.ReplaceAll(assetIdParam, "-", "") // Remove dashes + // Convert the asset ID to an int64 + assetId, err := strconv.ParseInt(assetIdParam, 10, 64) + if err != nil { + return err + } + + // Get the asset from the database + itemIds, err := repos.Items.GetIDsByAssetID(r.Context(), repo.AssetID(assetId)); + if err != nil { + return err + } + // check if we got more than one item + if len(itemIds) > 1 { + log.Err(err).Msg("More than one item found for asset ID") + return server.Respond(w, http.StatusInternalServerError, "More than one item found for asset ID") + } + // check if we got any items + if len(itemIds) == 0 { + log.Err(err).Msg("No items found for asset ID") + return server.Respond(w, http.StatusNotFound, "No items found for asset ID") + } + + http.Redirect(w, r, "/item/" + itemIds[0].String(), http.StatusSeeOther) + return nil + } +} \ No newline at end of file diff --git a/backend/app/api/routes.go b/backend/app/api/routes.go index 61e13d4..74a9e75 100644 --- a/backend/app/api/routes.go +++ b/backend/app/api/routes.go @@ -10,6 +10,7 @@ import ( "path" "path/filepath" + "github.com/hay-kot/homebox/backend/app/api/handlers/assetIds" "github.com/hay-kot/homebox/backend/app/api/handlers/debughandlers" v1 "github.com/hay-kot/homebox/backend/app/api/handlers/v1" _ "github.com/hay-kot/homebox/backend/app/api/static/docs" @@ -123,6 +124,8 @@ func (a *app) mountRoutes(repos *repo.AllRepos) { a.mwAuthToken, a.mwRoles(RoleModeOr, authroles.RoleUser.String(), authroles.RoleAttachments.String()), ) + a.server.Get("/a/{id}", assetIds.HandleAssetRedirect(a.repos)) + a.server.NotFound(notFoundHandler()) } diff --git a/backend/internal/data/repo/repo_items.go b/backend/internal/data/repo/repo_items.go index d8a3904..69535c0 100644 --- a/backend/internal/data/repo/repo_items.go +++ b/backend/internal/data/repo/repo_items.go @@ -283,6 +283,10 @@ func (e *ItemsRepository) GetOneByGroup(ctx context.Context, gid, id uuid.UUID) return e.getOne(ctx, item.ID(id), item.HasGroupWith(group.ID(gid))) } +func (e *ItemsRepository) GetIDsByAssetID(ctx context.Context, assetID AssetID) ([]uuid.UUID, error) { + return e.db.Item.Query().Where(item.AssetID(int(assetID))).Order(ent.Desc(item.FieldCreatedAt)).IDs(ctx) +} + // QueryByGroup returns a list of items that belong to a specific group based on the provided query. func (e *ItemsRepository) QueryByGroup(ctx context.Context, gid uuid.UUID, q ItemQuery) (PaginationResult[ItemSummary], error) { qb := e.db.Item.Query().Where( diff --git a/backend/internal/data/repo/repo_items_test.go b/backend/internal/data/repo/repo_items_test.go index 4b958b0..faacc18 100644 --- a/backend/internal/data/repo/repo_items_test.go +++ b/backend/internal/data/repo/repo_items_test.go @@ -107,6 +107,36 @@ func TestItemsRepository_GetAll(t *testing.T) { } } +func TestItemsRepository_GetIDsByAssetID(t *testing.T) { + useItems(t, 4) + + items, err := tRepos.Items.GetIDsByAssetID(context.Background(), 0) + + assert.NoError(t, err) + assert.Equal(t, 4, len(items), "Two items are returned when there are many with the same asset Id") + + item1 := useItems(t, 1)[0] + + item1Update := ItemUpdate{ + ID: item1.ID, + AssetID: 1, + Name: "note-important", + Description: "This is a note", + LocationID: item1.Location.ID, + } + + _, err = tRepos.Items.UpdateByGroup(context.Background(), tGroup.ID, item1Update) + + assert.NoError(t, err) + + items, err = tRepos.Items.GetIDsByAssetID(context.Background(), 1) + + assert.NoError(t, err) + assert.Equal(t, 1, len(items), "One item is returned when there is only one with the same asset Id") + assert.Equal(t, item1.ID, items[0], "The item returned is the one with the same asset Id") +} + + func TestItemsRepository_Create(t *testing.T) { location, err := tRepos.Locations.Create(context.Background(), tGroup.ID, locationFactory()) assert.NoError(t, err)