tangled
alpha
login
or
join now
danabra.mov
/
sidetrail
49
fork
atom
an app to share curated trails
sidetrail.app
atproto
nextjs
react
rsc
49
fork
atom
overview
issues
pulls
pipelines
tweak ranking
danabra.mov
3 months ago
6a5666bb
30889734
+13
-10
1 changed file
expand all
collapse all
unified
split
data
queries.ts
+13
-10
data/queries.ts
···
231
231
// Trails List (Home Page)
232
232
// ============================================================================
233
233
234
234
-
const HALF_LIFE_HOURS = 24;
235
235
-
const DECAY_RATE = Math.log(2) / HALF_LIFE_HOURS; // ≈ 0.0289
234
234
+
const HALF_LIFE_HOURS = 12;
235
235
+
const DECAY_RATE = Math.log(2) / HALF_LIFE_HOURS; // ≈ 0.0578
236
236
const RECENT_ACTIVITY_WINDOW_HOURS = 3;
237
237
+
const GRACE_PERIOD_HOURS = 3; // new trails get exposure
238
238
+
const MIN_ACTIVITY_FOR_RANKING = 5; // need this many to rank in main tier
237
239
238
240
export const loadTrails = cache(async function loadTrails(): Promise<TrailCardData[]> {
239
241
const db = getDb();
···
261
263
AND COALESCE(acc.shadowban, 0) = 0
262
264
GROUP BY t.uri, t.cid, t.author_did, t.rkey, t.record, t.created_at, t.indexed_at
263
265
ORDER BY
264
264
-
-- Tier: trails with activity first (0), then without (1)
265
265
-
CASE WHEN COUNT(a.trail_uri) > 0 THEN 0 ELSE 1 END,
266
266
-
-- Score: (1 + sqrt(recent_activity)) * recency_decay
266
266
+
-- Tier: 0 = grace period (new), 1 = proven (enough activity), 2 = unproven
267
267
CASE
268
268
-
WHEN COUNT(a.trail_uri) > 0
269
269
-
THEN (1 + SQRT(SUM(CASE WHEN EXTRACT(EPOCH FROM (NOW() - a.created_at))/3600 < ${RECENT_ACTIVITY_WINDOW_HOURS}::float THEN 1 ELSE 0 END)))
270
270
-
* EXP(${DECAY_RATE}::float * -1.0 * EXTRACT(EPOCH FROM (NOW() - MAX(a.created_at)))/3600)
271
271
-
ELSE EXP(${DECAY_RATE}::float * -1.0 * EXTRACT(EPOCH FROM (NOW() - t.created_at))/3600)
272
272
-
END DESC
268
268
+
WHEN EXTRACT(EPOCH FROM (NOW() - t.created_at))/3600 < ${GRACE_PERIOD_HOURS}::float THEN 0
269
269
+
WHEN COUNT(a.trail_uri) >= ${MIN_ACTIVITY_FOR_RANKING} THEN 1
270
270
+
ELSE 2
271
271
+
END,
272
272
+
-- Score within tier: (1 + sqrt(recent_activity)) * recency_decay
273
273
+
(1 + SQRT(SUM(CASE WHEN EXTRACT(EPOCH FROM (NOW() - a.created_at))/3600 < ${RECENT_ACTIVITY_WINDOW_HOURS}::float THEN 1 ELSE 0 END)))
274
274
+
* EXP(${DECAY_RATE}::float * -1.0 * EXTRACT(EPOCH FROM (NOW() - GREATEST(t.created_at, COALESCE(MAX(a.created_at), t.created_at))))/3600)
275
275
+
DESC
273
276
LIMIT 100
274
277
`);
275
278