See the best posts from any Bluesky account
0
fork

Configure Feed

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

Switch ?after=YYYY-MM-DD to ?days=N for time window filter

The original ?after=<absolute-date> form bookmarked as a permalink to a
fixed date range that drifts backward over time — bookmarking "Last
month" today gives you "the last 60 days" a month from now, which is
the opposite of what users expect. ?days=N is computed at query time
relative to the current wall clock, so a bookmark of ?days=30 always
means "the most recent 30 days." Future ranges (last week, last year)
become dropdown additions with no code changes.

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

+15 -12
+15 -12
docs/superpowers/specs/2026-04-11-skystar-bluesky-design.md
··· 257 257 a dictionary lookup; tens of thousands of distinct authors is well within 258 258 the LowCardinality sweet spot. 259 259 260 - The `idx_created` minmax skip index lets the optional `?after=` filter 260 + The `idx_created` minmax skip index lets the optional `?days=` filter 261 261 prune granules without putting a microsecond timestamp in the sort key 262 262 (which would destroy the sparse primary index). 263 263 ··· 339 339 AND e.post_author_did = s.post_author_did 340 340 WHERE s.post_author_did = ? 341 341 AND s.is_deleted = 0 342 - AND (? IS NULL OR s.post_created_at >= ?) -- ?after= filter 342 + AND (? IS NULL OR s.post_created_at >= now() - INTERVAL ? DAY) -- ?days= filter 343 343 GROUP BY s.post_uri, s.post_text, s.post_created_at, 344 344 s.snapshot_likes, s.snapshot_reposts, s.snapshot_taken_at 345 345 ORDER BY {likes|reposts} DESC, s.post_created_at DESC ··· 539 539 540 540 ### Flow 3 — Read (web process, every subsequent visit) 541 541 542 - `GET /profile/:handle/likes?after=2026-03-11` 542 + `GET /profile/:handle/likes?days=30` 543 543 544 544 1. `SELECT did, handle, deleted_at FROM users WHERE handle = ?` 545 545 2. If `deleted_at IS NOT NULL`, render 410 Gone. 546 546 3. If the URL handle differs from the canonical handle for that DID 547 547 (handle change since last visit), 301 to the canonical URL. 548 - 4. Run the top-25 ClickHouse query (per §5) with the `?after=` filter and 548 + 4. Run the top-25 ClickHouse query (per §5) with the `?days=` filter and 549 549 the kind from the path segment (`/likes` or `/reposts`). 550 550 5. Render the Edge template with the 25 cards. 551 551 6. `Cache-Control: public, max-age=60` — top posts of all time don't change ··· 590 590 591 591 ### Query parameters 592 592 593 - - `?after=YYYY-MM-DD` — filter to posts created on or after the given UTC 594 - date. Omitted parameter means "all time". The UI dropdown computes the 595 - date when generating the link, so a "Last month" link is a permalink to 596 - that exact range. 593 + - `?days=N` — filter to posts created within the last `N` days, computed 594 + at query time relative to the current wall clock. `N` is a positive 595 + integer, validated against a sanity cap (3650). Omitted parameter means 596 + "all time". This shape was chosen so that bookmarking a "Last month" 597 + page yields a permalink that always means "the most recent 30 days," 598 + not a fixed date range that drifts backward over time. 597 599 598 - The UI dropdown still shows friendly labels ("All time", "Last month"). 600 + The UI dropdown shows friendly labels ("All time", "Last month") and emits 601 + the corresponding `?days=` value (or omits it for all time). 599 602 600 603 --- 601 604 ··· 615 618 - Two controls: 616 619 - **Kind toggle:** "Most liked" / "Most reposted" — implemented as links 617 620 between `/profile/:handle/likes` and `/profile/:handle/reposts`. 618 - - **Lens dropdown:** "All time" / "Last month" — sets the `?after=` 621 + - **Lens dropdown:** "All time" / "Last month" — sets the `?days=` 619 622 parameter. 620 623 - 25 post cards in ranked order. Each card shows: like count, repost count, 621 624 post text (with line breaks preserved), date, "view on Bluesky" link. ··· 701 704 ### Unit tests (Japa) 702 705 703 706 - `packages/clickhouse/queries.ts` — top-25 query builder, fixtures seeded 704 - into a real ClickHouse. Tests cover: all-time and `?after=` ordering, 707 + into a real ClickHouse. Tests cover: all-time and `?days=` ordering, 705 708 per-post watermark math, ties broken by `post_created_at`, posts with 706 709 zero engagement excluded, tombstoned posts excluded. 707 710 - `packages/atproto/parse.ts` — pure functions for AT-URI parsing, ··· 716 719 embeds, parses the embedded post's author DID, ignores other embed 717 720 types, and only emits `kind='quote'` engagement rows for tracked 718 721 embedded authors. 719 - - Date parsing for `?after=`. 722 + - Integer parsing for `?days=`. 720 723 721 724 ### Integration tests (Japa with real services) 722 725