diff --git a/psf-memo-db/specs/thread-query-performance.feature b/psf-memo-db/specs/thread-query-performance.feature new file mode 100644 index 0000000..9f5a374 --- /dev/null +++ b/psf-memo-db/specs/thread-query-performance.feature @@ -0,0 +1,27 @@ +# Scenarios: Thread query performance - 1 +# +# GET /posts/:txid/thread currently does work proportional to the whole +# database, not to the requested thread: +# - get-post-thread.js calls buildLikeCountMap(), which iterates every +# postLikes entry and loads one post per like just to compute counts. +# - get-post-thread.js loadChildTxids() iterates every postChildren entry +# for each node in the thread instead of prefix-scanning that node's +# parent key. +# This feature pins the endpoint to bounded, per-thread reads. Thread shape, +# reply ordering, and per-node likeCount remain specified by like-counts.feature. +Feature: Thread query performance + + Background: + Given a psf-memo-db instance with posts, postHeights, addrPostHeights, postChildren, likes, and postLikes stores + Given the fixture "posts-with-likes" is loaded into the posts and likes stores + + Scenario Outline: Thread query performance - 1 GET /posts/:txid/thread performs work bounded by the thread + When the client requests the thread for + Then the post with txid has likeCount + And the postChildren store was read at most entries + And no more than posts are loaded by txid + + Examples: + | txid | likeCount | max_entries | limit | + | post-200-a | 2 | 1 | 2 | + | post-200-b | 1 | 0 | 1 | diff --git a/specs/feature-backlog.md b/specs/feature-backlog.md index c79bb8f..f5f6504 100644 --- a/specs/feature-backlog.md +++ b/specs/feature-backlog.md @@ -157,16 +157,36 @@ Reference: https://memo.sv/protocol (Wayback snapshot 2025-12-15) --- -## Next up: account avatar display — DONE (2026-09-05) +## Next up: Thread query performance (psf-memo-db) + +`GET /posts/:txid/thread` is slow because `get-post-thread.js` does work +proportional to the whole database instead of the requested thread. Two +independent parts, one feature spec: + +- **Part A — like counts scoped to the thread.** `execute()` calls + `buildLikeCountMap()`, which iterates every `postLikes` entry and loads one + post per like. Build the thread first, then count likes for the thread's + txids via the existing `countLikesForTxids`. +- **Part B — child loading uses the parent index.** `loadChildTxids()` + iterates every `postChildren` entry once per thread node. Prefix-scan + `parentTxid:childTxid` (as `countRepliesForTxids` already does) instead. + +Spec: `psf-memo-db/specs/thread-query-performance.feature`. Affected +component: D (`psf-memo-db`). No client, indexer, or protocol changes. + +Thread shape, reply ordering, and per-node `likeCount` remain specified by +`psf-memo-db/specs/like-counts.feature` (scenario 3). `buildLikeCountMap` +still has unit/property coverage; the coder should update it if the method is +removed. + +--- + +## Previous: account avatar display — DONE (2026-09-05) The `/account` page now renders the avatar image when an avatar URL is set (pure `AvatarImage` component + `AccountPage` display helpers). Merged to `master` at `5afaa64`. -Next feature: TBD — current direction is front-end improvements to -`psf-memo-client` (UI/UX polish, accessibility, performance, responsiveness, -state handling, error surfacing). - ## Notes for future cycles - Broadcast result (txid) is returned immediately; the action appears in the