summaryrefslogtreecommitdiff
path: root/apps/web/lib
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-12 00:49:03 -0800
committerFuwn <[email protected]>2026-02-12 00:49:42 -0800
commit2911927a2d9fdd5616c2eda5643143f601068888 (patch)
tree79726e2f2babc4a1da58c30b59d22981fbbdfe26 /apps/web/lib
parentRedump latest Supabase schema (diff)
downloadasa.news-2911927a2d9fdd5616c2eda5643143f601068888.tar.xz
asa.news-2911927a2d9fdd5616c2eda5643143f601068888.zip
fix: prevent read entries from reverting to unread on re-fetch
Root cause: cleanup_stale_entries deleted read-but-unsaved entries from active feeds, then the Go worker re-inserted them with new UUIDs, orphaning the user_entry_states rows and making entries appear unread. - cleanup_stale_entries: skip feeds with active subscribers and preserve entries that have been read (not just saved) - Go parser: normalize GUIDs by trimming whitespace and stripping tracking query parameters from URL-based identifiers - Go writer: preserve original published_at on upsert instead of overwriting, preventing old entries from jumping to timeline top - get_unread_counts: apply same time boundary as get_timeline so ancient re-inserted entries don't inflate counts - Realtime listener: ignore INSERT events for entries older than 48h to suppress misleading "new entries" notifications from re-inserts
Diffstat (limited to 'apps/web/lib')
-rw-r--r--apps/web/lib/hooks/use-realtime-entries.ts14
1 files changed, 13 insertions, 1 deletions
diff --git a/apps/web/lib/hooks/use-realtime-entries.ts b/apps/web/lib/hooks/use-realtime-entries.ts
index 22551f9..63d0eed 100644
--- a/apps/web/lib/hooks/use-realtime-entries.ts
+++ b/apps/web/lib/hooks/use-realtime-entries.ts
@@ -9,6 +9,7 @@ import { useNotificationStore } from "@/lib/stores/notification-store"
import { useUserInterfaceStore } from "@/lib/stores/user-interface-store"
const DEBOUNCE_MILLISECONDS = 3000
+const STALE_ENTRY_THRESHOLD_HOURS = 48
export function useRealtimeEntries() {
const queryClient = useQueryClient()
@@ -66,7 +67,18 @@ export function useRealtimeEntries() {
schema: "public",
table: "entries",
},
- () => {
+ (payload) => {
+ const publishedAt = payload.new?.published_at
+ if (publishedAt) {
+ const entryAge =
+ Date.now() - new Date(publishedAt).getTime()
+ const thresholdMilliseconds =
+ STALE_ENTRY_THRESHOLD_HOURS * 60 * 60 * 1000
+ if (entryAge > thresholdMilliseconds) {
+ return
+ }
+ }
+
pendingCountReference.current++
if (debounceTimerReference.current) {