Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

keeps: fix recent-feed handle lookup — bare $arrayElemAt, prefix in JS

The previous attempt (e4eb5b8b9) reordered the pipeline but kept the
$cond/$concat $addFields shape, and the deployed code still returned
handle=null for every recent entry — including codes the batch endpoint
resolves correctly. Mirror tv.mjs/fetchKidlisp's known-working pattern:
project the bare handle via $arrayElemAt and prepend "@" when mapping
docs to the response.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

+13 -15
+13 -15
system/netlify/functions/store-kidlisp.mjs
··· 670 670 671 671 console.log(`📊 Codes request: limit=${actualLimit}, sort=${sortBy}, handle=${filterHandle || 'all'}${since ? `, since=${since}` : ''}`); 672 672 673 + // Mirror tv.mjs/fetchKidlisp's working pattern: bare $arrayElemAt 674 + // (no $cond/$concat), upstream $match, $sort+$limit before $lookup. 675 + // Earlier $cond/$concat variant returned handle=null for every doc 676 + // even when @handles had a matching entry — empirically reproducible 677 + // against the same data the batch endpoint resolves correctly. 673 678 const handleLookupStages = [ 674 679 { 675 680 $lookup: { ··· 681 686 }, 682 687 { 683 688 $addFields: { 684 - handle: { 685 - $cond: { 686 - if: { $gt: [{ $size: "$handleInfo" }, 0] }, 687 - then: { $concat: ["@", { $arrayElemAt: ["$handleInfo.handle", 0] }] }, 688 - else: null 689 - } 690 - } 689 + handleRaw: { $arrayElemAt: ["$handleInfo.handle", 0] } 691 690 } 692 691 } 693 692 ]; 694 693 695 - // Match/sort/limit before $lookup so the join runs on a small working 696 - // set — the previous order silently dropped handleInfo on large scans. 697 - const pipeline = []; 694 + const pipeline = [ 695 + { $match: { code: { $exists: true } } } 696 + ]; 698 697 699 698 if (since) { 700 699 const sinceDate = new Date(since); ··· 710 709 if (filterHandle) { 711 710 // Filter is on the computed handle, so the lookup has to precede $limit. 712 711 pipeline.push(...handleLookupStages); 713 - pipeline.push({ 714 - $match: { handle: filterHandle.startsWith('@') ? filterHandle : `@${filterHandle}` } 715 - }); 712 + const bareHandle = filterHandle.startsWith('@') ? filterHandle.slice(1) : filterHandle; 713 + pipeline.push({ $match: { handleRaw: bareHandle } }); 716 714 pipeline.push({ $limit: actualLimit }); 717 715 } else { 718 716 pipeline.push({ $limit: actualLimit }); ··· 730 728 kept: 1, 731 729 tezos: 1, 732 730 pendingRebake: 1, 733 - handle: 1 731 + handleRaw: 1 734 732 } 735 733 }); 736 734 ··· 745 743 when: doc.when, 746 744 hits: doc.hits, 747 745 user: doc.user || null, 748 - handle: doc.handle || null 746 + handle: doc.handleRaw ? `@${doc.handleRaw}` : null 749 747 }; 750 748 751 749 const keepRecords = filterKeepRecords(extractKeepRecords(doc), {