SPB Git forge

spb/rareindex

Public
54commits 1branches 0releases
7.1 MBsize
maindefault branch
10 days agolast push
TypeScript 61.9% HTML 37.2% SQL 0.7%
1.5 KB · 25 lines typescript
Raw Blame History
1import { and, eq, lt, sql } from 'drizzle-orm';2import { connectors as connectorsTable, listingEvents, listings } from '@rareindex/database';3import { logger, newId } from '@rareindex/shared';4import { db } from './lib/db.ts';56/**7 * Listings not seen for 3× the connector refresh interval (min 3 days) are marked `removed`8 * (§171 change detection). They are kept for history; a later sighting re-opens them (relisted).9 */10export async function expireListings(): Promise<number> {11  const cons = await db().select({ id: connectorsTable.id, refresh: connectorsTable.refreshFrequencyMinutes }).from(connectorsTable);12  let n = 0;13  for (const c of cons) {14    const ttlMs = Math.max(3 * 86_400_000, c.refresh * 60_000 * 3);15    const cutoff = new Date(Date.now() - ttlMs);16    const stale = await db().select({ id: listings.id, price: listings.price, currency: listings.currency }).from(listings).where(and(eq(listings.connectorId, c.id), eq(listings.availability, 'available'), lt(listings.lastSeenAt, cutoff))).limit(5000);17    if (!stale.length) continue;18    await db().update(listings).set({ availability: 'removed', updatedAt: new Date() }).where(sql`${listings.id} in ${stale.map((s) => s.id)}`);19    await db().insert(listingEvents).values(stale.map((s) => ({ id: newId('event'), listingId: s.id, eventType: 'removed', oldPrice: s.price, currency: s.currency, occurredAt: new Date() })));20    n += stale.length;21  }22  if (n) logger.info({ expired: n }, 'listings expired');23  return n;24}25