From 5cdc785b49f9a8507206343239f590f9d4116101 Mon Sep 17 00:00:00 2001 From: kolaente Date: Wed, 10 Jun 2026 09:30:42 +0200 Subject: [PATCH] fix(api/v2): return ErrProjectDoesNotExist for unknown project identifiers --- pkg/models/project.go | 14 ++++++++++++++ pkg/routes/api/v2/tasks.go | 7 +------ pkg/webtests/huma_task_test.go | 3 ++- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/pkg/models/project.go b/pkg/models/project.go index 022f673a5..23fc9f6ca 100644 --- a/pkg/models/project.go +++ b/pkg/models/project.go @@ -448,6 +448,20 @@ func GetProjectSimpleByID(s *xorm.Session, projectID int64) (project *Project, e return } +// GetProjectSimpleByIdentifier gets a project by its textual identifier (e.g. "PROJ"). +// Identifiers are stored uppercase, so the lookup normalizes the input. +func GetProjectSimpleByIdentifier(s *xorm.Session, identifier string) (project *Project, err error) { + project, exists, err := getProjectSimple(s, builder.Eq{"identifier": strings.ToUpper(identifier)}) + if err != nil { + return nil, err + } + if !exists { + return nil, ErrProjectDoesNotExist{} + } + + return +} + func getProjectSimple(s *xorm.Session, cond builder.Cond) (project *Project, exists bool, err error) { project = &Project{} exists, err = s. diff --git a/pkg/routes/api/v2/tasks.go b/pkg/routes/api/v2/tasks.go index 0c0f2d54c..49fa21910 100644 --- a/pkg/routes/api/v2/tasks.go +++ b/pkg/routes/api/v2/tasks.go @@ -19,7 +19,6 @@ package apiv2 import ( "context" "strconv" - "strings" "code.vikunja.io/api/pkg/db" "code.vikunja.io/api/pkg/models" @@ -218,13 +217,9 @@ func resolveProjectIdentifier(raw string) (int64, error) { } s := db.NewSession() defer s.Close() - project := &models.Project{} - has, err := s.Where("identifier = ?", strings.ToUpper(raw)).Get(project) + project, err := models.GetProjectSimpleByIdentifier(s, raw) if err != nil { return 0, translateDomainError(err) } - if !has { - return 0, huma.Error404NotFound("Project not found") - } return project.ID, nil } diff --git a/pkg/webtests/huma_task_test.go b/pkg/webtests/huma_task_test.go index 17583822e..8c919e382 100644 --- a/pkg/webtests/huma_task_test.go +++ b/pkg/webtests/huma_task_test.go @@ -204,9 +204,10 @@ func TestHumaTask_ReadByIndex(t *testing.T) { require.Equal(t, http.StatusOK, rec.Code, "body: %s", rec.Body.String()) assert.Contains(t, rec.Body.String(), `"id":1`) }) - t.Run("Unknown identifier returns 404", func(t *testing.T) { + t.Run("Unknown identifier returns ErrProjectDoesNotExist", func(t *testing.T) { rec := get("does-not-exist", "1") assert.Equal(t, http.StatusNotFound, rec.Code, "body: %s", rec.Body.String()) + assert.Contains(t, rec.Body.String(), fmt.Sprintf(`"code":%d`, models.ErrCodeProjectDoesNotExist)) }) t.Run("Nonexistent index returns 404", func(t *testing.T) { rec := get("1", "99999")