From ae3bef4cc4b5505c5aa32d08944db99246b16bf5 Mon Sep 17 00:00:00 2001 From: Devin Zuczek Date: Wed, 5 Aug 2026 15:30:50 -0400 Subject: [PATCH] real featured inventions --- apps/api/src/inventions-db.ts | 10 +++++++--- apps/api/src/routes/avatar.ts | 9 +++++---- apps/api/src/test/integration/api.test.ts | 15 +++++++++++---- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/apps/api/src/inventions-db.ts b/apps/api/src/inventions-db.ts index 98a9876..d3d1d3d 100644 --- a/apps/api/src/inventions-db.ts +++ b/apps/api/src/inventions-db.ts @@ -377,8 +377,13 @@ export async function getTopInventions( /** * The featured feed — published inventions flagged `IsFeatured`, newest first. * Selected on the indexed `is_featured` column rather than by parsing every public - * invention. Nothing sets that flag yet, so this falls back to the top feed rather - * than handing the client an empty shelf; once inventions are curated it serves them. + * invention. + * + * Curated means curated: when nothing is flagged this serves an EMPTY list rather than + * standing in the top feed. It used to fall back, from when no invention could be + * featured at all, but a fallback makes the shelf lie — the client labels these as + * hand-picked, and a feed that silently becomes "top today" hides the fact that nobody + * has picked anything. */ export async function getFeaturedInventions( db: D1Database, @@ -386,7 +391,6 @@ export async function getFeaturedInventions( take: number ): Promise { const featured = await publicInventions(db, true) - if (featured.length === 0) return getTopInventions(db, skip, take) return featured .sort((a, b) => b.CreatedAt.localeCompare(a.CreatedAt) || b.InventionId - a.InventionId) .slice(skip, skip + take) diff --git a/apps/api/src/routes/avatar.ts b/apps/api/src/routes/avatar.ts index e43f24a..e037468 100644 --- a/apps/api/src/routes/avatar.ts +++ b/apps/api/src/routes/avatar.ts @@ -643,16 +643,17 @@ export const avatarRoutes = new Hono({ strict: false }) } ) - // The featured invention feed — curated (`IsFeatured`) inventions, falling back - // to the top feed while nothing is curated. Bare array, like toptoday. + // The featured invention feed — the curated (`IsFeatured`) inventions and nothing + // else, newest first. Empty until someone flags one. Bare array, like toptoday. .get( '/api/inventions/v1/featured', describeRoute({ tags: ['Inventions'], summary: 'The featured feed', description: - 'Curated (`IsFeatured`) inventions, falling back to the top feed while nothing is ' + - 'curated — so this is never empty just because no one has picked favourites.', + 'Curated (`IsFeatured`) inventions, newest first — published and non-hidden only. ' + + 'Serves an empty list while nothing is flagged rather than standing in the top ' + + 'feed: the client presents these as hand-picked, so a fallback would be a lie.', parameters: pageParams(50), responses: { 200: json(InventionDto.array(), 'The featured inventions') }, }), diff --git a/apps/api/src/test/integration/api.test.ts b/apps/api/src/test/integration/api.test.ts index 004354f..6278279 100644 --- a/apps/api/src/test/integration/api.test.ts +++ b/apps/api/src/test/integration/api.test.ts @@ -1138,12 +1138,14 @@ describe('public endpoints', () => { const ids = async (res: Response): Promise => ((await res.json()) as SavedInvention[]).map((i) => i.InventionId) - // Nothing is flagged IsFeatured yet → featured falls back to the top feed. + // Nothing is flagged IsFeatured yet, so featured is EMPTY — it does not stand in the + // top feed, which by now has published inventions in it. const beforeTop = await ids(await exports.default.fetch(`${ORIGIN}/api/inventions/v1/toptoday`)) + expect(beforeTop.length).toBeGreaterThan(0) const beforeFeatured = await ids( await exports.default.fetch(`${ORIGIN}/api/inventions/v1/featured`) ) - expect(beforeFeatured).toEqual(beforeTop) + expect(beforeFeatured).toEqual([]) const feedInvention = ( id: number, @@ -1187,13 +1189,18 @@ describe('public endpoints', () => { expect(top).not.toContain(204) expect(top).not.toContain(205) - // Featured: only the flagged, visible inventions — newest first. + // Featured: only the flagged, visible inventions — newest first. 201 is published but + // unflagged, so it stays out however popular it is. const featured = await ids(await exports.default.fetch(`${ORIGIN}/api/inventions/v1/featured`)) expect(featured).toEqual([203, 202]) - // skip/take paginate the top feed. + // skip/take paginate both feeds. const page = await exports.default.fetch(`${ORIGIN}/api/inventions/v1/toptoday?skip=1&take=1`) expect(await ids(page)).toEqual([203]) + const featuredPage = await exports.default.fetch( + `${ORIGIN}/api/inventions/v1/featured?skip=1&take=1` + ) + expect(await ids(featuredPage)).toEqual([202]) }) test('POST /api/sanitize/v1 echoes the value; isPure reports true', async () => {