requireCollectionFullyVisible checks that the collection is visible to the requesting user under FULL-collection-access semantics (BUG-1920 — codex R2 follow-up). This is deliberately STRICTER than handleGetCollection's inline visibleCollectionIDs + isCollectionVisible check: VisibleCollectionIDs (w
(w http.ResponseWriter, r *http.Request, workspaceID string, coll *models.Collection)
| 1953 | // Writes a 404 and returns false if not visible; callers should invoke this |
| 1954 | // immediately after resolving a collection by slug/ID. |
| 1955 | func (s *Server) requireCollectionFullyVisible(w http.ResponseWriter, r *http.Request, workspaceID string, coll *models.Collection) bool { |
| 1956 | visibleIDs, err := s.visibleCollectionIDs(r, workspaceID) |
| 1957 | if err != nil { |
| 1958 | writeInternalError(w, err) |
| 1959 | return false |
| 1960 | } |
| 1961 | if visibleIDs != nil { |
| 1962 | // Restricted (non-nil visibleIDs): narrow to full-access |
| 1963 | // collections only when the caller's restricted visibility |
| 1964 | // includes any item-level grants, so an item-grant-only |
| 1965 | // collection can't qualify for collection-wide operations. |
| 1966 | fullCollIDs, grantedItemIDs, gErr := s.guestResourceFilter(r, workspaceID) |
| 1967 | if gErr != nil { |
| 1968 | writeInternalError(w, gErr) |
| 1969 | return false |
| 1970 | } |
| 1971 | if len(grantedItemIDs) > 0 { |
| 1972 | visibleIDs = fullCollIDs |
| 1973 | } |
| 1974 | } |
| 1975 | if !isCollectionVisible(coll.ID, visibleIDs) { |
| 1976 | writeError(w, http.StatusNotFound, "not_found", "Collection not found") |
| 1977 | return false |
| 1978 | } |
| 1979 | return true |
| 1980 | } |
| 1981 | |
| 1982 | // requireItemVisible checks that the item's collection is visible to the |
| 1983 | // requesting user. For guests with item-level grants, also verifies that the |
no test coverage detected