package handlers // repo_lookup.go — shared helper used by all handlers that resolve // {owner}/{repo} URL params to a repository row. // // The owner segment can be either a user username (user-owned repo) or a // workspace handle (workspace-owned repo). This tries user-namespace first, // then workspace-namespace, so the lookup is always unambiguous. import ( "net/http" "github.com/go-chi/chi/v5" "xorm.io/xorm" "github.com/forgeo/forgebucket/internal/models" ) // resolveRepoID resolves /{owner}/{repo} to a repository ID. // It tries user namespace first, then workspace namespace. // Returns (repoID, true) on success or writes a 404 and returns (0, false). func resolveRepoID(db *xorm.Engine, w http.ResponseWriter, r *http.Request) (int64, bool) { repo, ok := resolveRepo(db, w, r) if !ok { return 0, false } return repo.ID, true } // resolveRepo is the full repo lookup returning the Repository struct. func resolveRepo(db *xorm.Engine, w http.ResponseWriter, r *http.Request) (*models.Repository, bool) { ownerName := chi.URLParam(r, "owner") repoName := chi.URLParam(r, "repo") // 1. Try user namespace. var u models.User if found, _ := db.Where("username = ?", ownerName).Get(&u); found { var repo models.Repository if found2, _ := db.Where("owner_id = ? AND name = ?", u.ID, repoName).Get(&repo); found2 { return &repo, true } } // 2. Try workspace namespace. var ws models.Workspace if found, _ := db.Where("handle = ?", ownerName).Get(&ws); found { var repo models.Repository if found2, _ := db.Where("workspace_id = ? AND name = ?", ws.ID, repoName).Get(&repo); found2 { return &repo, true } } jsonError(w, "repository not found", http.StatusNotFound) return nil, false }