Commit Graph
342 Commits
Author SHA1 Message Date
Chris Troutner 63107855a2 Harden recent profile identity with property tests
Add seeded property tests for the new identity join and table view model:
profile-path round trips, display-name fallback, account mapping, table
row shape, DB identity-field independence, missing-store null behavior,
and page-only join with conserved order and pagination.

Cover the account-cell click handler so RecentProfileAccount reaches 100%
unit coverage (CRAP <= 2).

Tests only; no production behavior changed.

By refactorer.
2026-09-20 13:00:03 -07:00
Chris Troutner 9fb092e845 Implement recent profile identity join and Account column
DB: GET /profile/recent joins each profile's display name (names store)
and avatar URL (profilePics store) by address, reporting null when a
record is absent. The join runs on the requested page only and leaves the
profile order and pagination unchanged.

Client: the /profile/recent table gains a leftmost Account column showing
the display name and avatar, both linking to the profile, with a
truncated-address fallback when the name is absent and an identicon
fallback when the avatar is absent. The existing columns are preserved.

Add focused unit tests, acceptance fixtures, and regex step handlers for
both components.

By coder.
2026-09-20 12:46:12 -07:00
Chris Troutner dda94b1a81 Specify recent profile identity for /profile/recent
Add DB Gherkin for GET /profile/recent joining each profile's display
name (names store) and avatar URL (profilePics store), null when absent.
Add client Gherkin for the new leftmost Account column showing the
display name and avatar, linking to the profile, with truncated-address
and identicon fallbacks and the existing columns preserved.

By specifier.
2026-09-20 12:24:19 -07:00
Chris Troutner 761d5268d0 Record feed tabs completion in backlog and briefing
By specifier.
2026-09-20 10:41:13 -07:00
Chris Troutner 2d1755a03d Record feed tabs review and verification
By architect.
2026-09-20 10:40:13 -07:00
Chris Troutner e4bda31256 Review feed tabs: consume controller snapshot, kill mutation survivors
Route the posts view through FeedTabsPage.getState() instead of reaching
into the controller's internal fields, and consolidate the default-mode
unit tests. Add initial-state and unloaded-pagination tests that kill the
four constructor/canLoadMore mutation survivors (22 killed, 0 survived,
0 uncovered).

By architect.
2026-09-20 10:36:45 -07:00
Chris Troutner 4b8b4ed499 Refactor feed tabs: simplify mode loading, add feed-tabs properties
Reduce FeedTabsPage._loadMode complexity below the CRAP threshold by
extracting the mode-to-page lookup and the empty-Following predicate, and
drop the unused getActiveTabLabel helper. Add property tests for default
mode selection, delegation, tab-switch reset, paging, and empty-state
invariants, and share the default-mode unit-test setup. FeedTabsPage
functions are at 100% coverage with CRAP <= 5.

By refactorer.
2026-09-20 10:16:14 -07:00
Chris Troutner d1372dac11 Merge Following feed into the posts page as Recent/Following tabs
The /posts/recent posts page now shows a row of two mode buttons. On
first load it selects Following when the viewer's address follows at
least one account (via GET /follow/following/:addr) and Recent
otherwise, and switching tabs resets the feed to its first page. The
/posts/following route and its navbar item are removed, so the
Following feed is reached only through the Following button. Add the
testable FeedTabsPage controller with unit coverage and the acceptance
handlers for feed-tabs.

Also drop the Feed Tabs - 4 assertion that the global Recent feed hides
a followed author's post: /posts/recent is the global feed, so followed
posts appear in both tabs. Approved by the user.

By coder.
2026-09-20 10:07:06 -07:00
Chris Troutner f3a41de488 Specify merged posts feed with Recent/Following tabs
Add psf-memo-client/specs/feed-tabs.feature specifying the two-tab
posts feed, default-mode selection by follow state, tab switching,
and first-page reset. Record the feature in the backlog.

By specifier.
2026-09-20 09:54:01 -07:00
Chris Troutner b5699b4eed Record following feed cap completion in backlog and briefing
By specifier.
2026-09-20 08:49:16 -07:00
Chris Troutner de3f1c8bb6 Record following feed cap review and verification
By architect.
2026-09-20 08:48:02 -07:00
Chris Troutner b7c20560c2 Review following feed cap: drop dead reply-txid loader
Remove PostQuery.loadReplyTxids after the capped following-feed scan
switched to per-candidate isReply point lookups; it had no callers and
was the only uncovered code in post-query.js (99.4% -> 100%).
Refresh the mutate4javascript and acceptance-mutation manifests via the
tools.

By architect.
2026-09-20 08:44:25 -07:00
Chris Troutner 5653ecef9d Refactor following feed cap: share acceptance seeding, add cap properties
Extract putPost/putFollowEdge seeding helpers in the psf-memo-db acceptance
handlers and route the following-feed capped/mixed fixtures and the
many-top-level-posts fixture through them, removing repeated store/key writes.

Add property tests for the capped total, newest-first page conservation, and
the bounded eligible scan, plus unit coverage for the remaining PostQuery
constructor guards and static key helpers (post-query.js statements 94.5% ->
99.4%).

CRAP stays at or below 6, src/adapters/post-query.js remains at 40 mutation
sites with its manifest intact, and the DRY tool reports no duplicates in the
changed source file.

By refactorer.
2026-09-20 08:32:43 -07:00
Chris Troutner db216949ec Implement following feed capped scan
By coder.
2026-09-20 08:19:27 -07:00
Chris Troutner 2ce0a62af9 Specify following feed capped scan
By specifier.
2026-09-20 08:13:19 -07:00
Chris Troutner 6462977b87 Record mute broadcast result completion in backlog and briefing
By specifier.
2026-09-18 15:35:39 -07:00
Chris Troutner eaaed8e5ea Record mute broadcast result review and verification
Add the architect review summary and the machine-readable client verification
record (unit, property, acceptance, lint, build) pinned to review commit
a7d9ca6299.

By architect.
2026-09-18 15:34:11 -07:00
Chris Troutner a7d9ca6299 Review mute broadcast result: drop dead modal reset, pin error getter
Remove the unobservable showMuteResultModal reset in
ProfilePage._broadcastMute: the flag is set true unconditionally after the
awaited broadcast, so no observer can read the reset value. Add unit coverage
for getMuteResultError's empty-string contract when there is no result and
when a failure carries no message. Record the tool-written mutation and
acceptance-mutation manifests.

Mutation: 31 killed, 0 survived, 0 uncovered (profile-page.js). CRAP <= 4.
DRY clean. Soft Gherkin: 5 intrinsic case-equivalents.

By architect.
2026-09-18 15:31:41 -07:00
Chris Troutner 722c486ef6 Refactor mute broadcast result: share result handlers, add property tests
Deduplicate the like/mute acceptance broadcast-result assertion handlers and
the follow/unfollow/mute/unmute prefix handlers behind shared helpers, and
extract the broadcast explorer transaction link into one component used by
both result components. Add property tests for the mute result component and
the profile page mute result state machine (explorer URL composition, error vs
success markup, determinism, outcome mirroring, failure state preservation,
and dismiss).

CRAP stays at or below 6, every changed source module stays below 100 mutation
sites, and mutation manifests are left intact for differential runs.

By refactorer.
2026-09-18 15:07:09 -07:00
Chris Troutner 24d7f0f82c Implement mute broadcast result
Show a mute/unmute broadcast result modal on the profile page: success
message, transaction id, and block explorer link on success; the broadcast
error on failure. The modal stays open until dismissed, dismissing only
closes it, and a failed broadcast leaves the button in its previous state.

By coder.
2026-09-18 14:57:37 -07:00
Chris Troutner c0e18d8169 Add mute broadcast result specification
By specifier.
2026-09-18 14:52:23 -07:00
Chris Troutner 8eab46dba2 Improving notifications 2026-09-18 13:36:12 -07:00
Chris Troutner ea679795a6 Removing authors name from post, redundent 2026-09-18 13:23:48 -07:00
Chris Troutner e0882678fd Record notification-entry-display completion in backlog and briefing
By specifier.
2026-09-18 12:47:41 -07:00
Chris Troutner a1e4a4f95f Record notification entry display review and verification
Add the client verification record (git_sha bbbf4adcd7, result pass) and the
architect review summary for the notification-entry-display task.

By architect.
2026-09-18 12:46:39 -07:00
Chris Troutner bbbf4adcd7 Review notification entry display: wire SPA profile links, cover renderer
Wire the existing onProfileClick seam in the Notifications page so the actor
avatar and display name navigate through the SPA router instead of a full-page
reload (which 404s on the BrowserRouter/GH Pages deployment). Add a component
unit test so the renderer's mutation sites are covered, and a fresh-state
controller test to kill the constructor's empty=false mutant.

Refresh the tool-written mutation manifests for the changed modules and the
soft Gherkin mutation manifest for the feature.

By architect.
2026-09-18 12:43:39 -07:00
Chris Troutner 7dfc315840 Refactor notification entry display: share acceptance assertions, add property tests
Deduplicate the notification-entry acceptance step handlers behind shared
entry-assert helpers and collapse the repeated ready-state guards in the
notifications view. Add property tests for the entry view model (profile link
round trip, name fallback, view-model derivation, message mapping) and for
notifications page profile resolution, entry derivation, and actor lookup.

CRAP stays at or below 6 and every changed source module stays below 100
mutation sites; mutation manifests are left intact for differential runs.

By refactorer.
2026-09-18 12:30:53 -07:00
Chris Troutner 521d434524 Implement notification entry display
Name each Notifications entry with the actor's Memo display name and
avatar resolved client-side, link both to the actor's profile, show the
full address as plain text, and add a View Post link for like and reply
notifications that opens the referenced post thread. Fall back to the
truncated address and an identicon when a profile is missing or its
lookup fails.

By coder.
2026-09-18 12:20:52 -07:00
Chris Troutner f4d94999b5 Add notification entry display specification
By specifier.
2026-09-18 12:09:04 -07:00
Chris Troutner 889366042f Record notifications-query-performance completion in backlog
By specifier.
2026-09-18 10:56:30 -07:00
Chris Troutner a1eb548688 Record notifications-query-performance review and verification
By architect.
2026-09-18 10:52:07 -07:00
Chris Troutner c9728cc301 Review notifications query performance: harden defaults, refresh mutation manifests
Add unit coverage for the notification height/seen defaults, the seen
sort tie-break, the missing-status cutoff, and the config flags; refresh
the language mutation manifests and the soft Gherkin acceptance mutation
manifests for the three affected feature files.

By architect.
2026-09-18 10:46:29 -07:00
Chris Troutner 45a7b34fad Refactor notifications query: cut CRAP, share test double, add membership property
Reduce the notifications-query collector cyclomatic complexity below the CRAP
threshold by extracting prefix-range, txid-fallback, height-selection, and
actor-suppression helpers, and by sharing one per-post index scan between the
like and reply collectors. Reuse the shared FakeDb in the unit and property
suites instead of two local LevelDB doubles, cover every not-found branch, and
add a property test asserting returned notifications map to exactly one
generated interaction.

By refactorer.
2026-09-18 10:19:26 -07:00
Chris Troutner f45d63cd70 Implement notifications query performance
Bound GET /posts/notifications/:addr to the viewer's activity in a
configurable block window (NOTIFICATION_BLOCK_WINDOW, default 25000):
read the viewer's posts from addrPostHeights, prefix-scan postLikes and
postChildren for those posts only, and read follows from the new
followeeHeights index. The global likes, postChildren, and follows stores
are no longer full-scanned, and pagination.total counts only in-window
notifications.

Add the indexer write of a followeeHeights entry on every follow and
unfollow, the DB followee-index backfill utility and CLI, the
followeeheight /level route, the notification window config, unit,
property, and acceptance coverage, and developer docs.

By coder.
2026-09-18 09:57:42 -07:00
Chris Troutner 22928d764a Spec notifications query performance
Bound GET /posts/notifications/:addr to the viewer's activity in a
configurable block window instead of full-scanning likes, postChildren,
and follows. Adds the followeeHeights index spec, its backfill spec, and
the notifications-query-performance spec.

By specifier.
2026-09-18 09:28:25 -07:00
Chris Troutner f4e40a9dcd Fixing errors in client 2026-09-18 08:52:19 -07:00
Chris Troutner 4c6d20fefc Widening topics table 2026-09-18 08:27:18 -07:00
Chris Troutner 42af1f7d96 Record topics-table-layout completion in backlog and briefing
By specifier.
2026-09-18 07:48:14 -07:00
Chris Troutner 1e58b5b8b1 Record topics-table-layout review and verification
- Add the client verification record pinned to the review commit d1f0f76 and
  the architect review summary.

By architect.
2026-09-18 07:47:45 -07:00
Chris Troutner d1f0f76cca Review topics table layout: refresh mutation manifests
- No production or test changes were required: buildTopicsTable passes
  language mutation 2/2, dry4javascript reports no candidates, CRAP is 1.0 at
  100% coverage, and soft Gherkin mutation kills all 16 mutations.
- Commit the tool-written mutate4javascript manifest and the gherkin-mutator
  stamp/manifest only.

By architect.
2026-09-18 07:44:43 -07:00
Chris Troutner ec753a9c88 Add property tests for the topics table view model
- Add client property tests for buildTopicsTable: one row per topic in input
  order, four-cell alignment with the header order, link percent-encoding
  round trips, and post/follower count conservation over random topic lists
  that also omit count/last-seen fields.
- No production change: the coder's view model already scans at CRAP 1.0
  with zero dry4javascript candidates and only 2 mutation sites. The JSX
  Topics component stays a thin, tool-excluded shell over the testable model.

Verification: client 447 unit / 94 property / 34 acceptance + lint + build;
indexer 113 unit / 12 property / 7 acceptance + lint; db 392 unit / 57
property / 16 acceptance + lint.

By refactorer.
2026-09-18 07:42:52 -07:00
Chris Troutner ac4d9ea7f7 Render topics page as a table
Replace the topics page flex list with a react-bootstrap Table driven by a
testable topics-table view model: a labeled header row, aligned cells for
name, relative time, post count, and follower count, feed links on each row,
and a horizontal-scroll wrapper for narrow screens.

By coder.
2026-09-18 07:36:16 -07:00
Chris Troutner 41af8f955e Spec topics table layout
Require the topics page to render a react-bootstrap Table with aligned
columns, a header row, linked rows, and horizontal scroll on narrow screens.

By specifier.
2026-09-18 07:31:13 -07:00
Chris Troutner 17d2afff48 Record topic-metadata completion in backlog and briefing
By specifier.
2026-09-18 06:36:58 -07:00
Chris Troutner af54b0ebe7 Record topic-metadata review and verification
- Add the canonical per-component verification records (indexer, db, client)
  pinned to the review commit 3f05488, and the architect review summary.

By architect.
2026-09-18 06:35:33 -07:00
Chris Troutner 3f05488da0 Review topic metadata: harden default-value coverage
- Add DB unit tests covering a summary missing postCount, a post missing
  blockHeight in listTopics/getTopicPostTxids ordering, listTopics' default
  limit/offset, and topicRecencyKey's missing-height fallback. These kill the
  remaining language-mutation survivors in the changed DB sources.
- Refresh the mutate4javascript manifests for the changed sources and commit
  the gherkin-mutator manifests/stamps written into the three topic-metadata
  features.
- No production behavior changes; the review adds tests and tool-written
  metadata only.

By architect.
2026-09-18 06:29:01 -07:00
Chris Troutner dd11964174 Refactor topic metadata: cut CRAP, share test doubles, harden property tests
- Replace the ternary follower delta in recordTopicFollow with
  Number(isActive) - Number(wasActive), dropping its cyclomatic complexity
  from 8 to 6 (CRAP 8.0 -> 6.0). No behavior change.
- Extend the indexer topic property test to conserve lastSeen (newest post
  time) and followerCount (each address's final active follow state)
  alongside postCount/lastHeight, with varying post seen times.
- Extend the DB backfill and topic-query property tests to conserve lastSeen
  and followerCount; generated follows now include unfollows.
- Add a client topic-metadata property test covering relativeTime bucket
  classification, pluralization, monotonicity, and getLastSeenLabel
  consistency, and cover ensureTopicRoom's existing-summary path plus
  recordTopicFollow's legacy-follower-count fallback.
- Share one in-memory DB double per component (indexer test/support/
  memory-db.js, DB test/support/level-double.js) and table-drive the
  parallel topic-follow/topic-message/topic-query cases, clearing every
  dry4javascript candidate in the changed files.

Verification: indexer 113 unit / 12 property / 7 acceptance; db 387 unit /
57 property / 16 acceptance; client 441 unit / 90 property / 33 acceptance
+ build; lint clean. CRAP max 6.0; mutation scans under 100 sites/file.

By refactorer.
2026-09-18 06:02:13 -07:00
Chris Troutner 8da0f09f46 Implement topic metadata columns
Add lastSeen and followerCount to topicSummaries across the indexer, DB,
and client. The indexer now tracks the newest post seen time, updates
follower counts idempotently on follow/unfollow, and preserves post
metadata. The DB exposes lastSeen and followerCount from GET /topics and
rebuilds both from the rooms store in the backfill. The client renders the
four-column topics page with relative-time labels.

By coder.
2026-09-18 05:46:58 -07:00
Chris Troutner a599b34e38 Spec topic metadata columns
Define four-column topics page behavior across client, indexer, and DB:
topic name, time since most recent post, post count, and follower count.

By specifier.
2026-09-18 05:38:41 -07:00
Chris Troutner 6ef2e3589e Skip empty room names in topic index backfill
A historical rooms record with an empty room name made the backfill call
put('') and abort with "key cannot be an empty String". Skip records with no
room name so the one-time backfill can complete; such rooms have no listing
entry to write.

By specifier.
2026-09-17 12:44:57 -07:00