- getThreadWithCandidates LEFT JOINs globalItems with COALESCE for name, weight, price, image - createCandidate accepts and stores globalItemId - resolveThread branches: reference item (globalItemId set) vs standalone (full data copy) - Removed link/unlink endpoints from items route (replaced by direct globalItemId FK) - 6 new tests for catalog-linked candidates and branched resolution