0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-12 05:02:14 +08:00
discourse/db
Régis Hanol d68be7b5f6
FEATURE: Exclude small actions from topic counters and unread tracking (#40481)
Small action posts (closing, opening, pinning, archiving, category
changes, auto-close, etc. — post_type 3) no longer count toward a
topic's counters or unread tracking. They still occupy a post_number so
the post stream stays gapless, but they contribute to nothing: not
highest_post_number, highest_staff_post_number, posts_count,
last_posted_at, last_post_user_id, word_count or bumped_at, and they
never mark a topic unread or publish unread updates — for regular users
and staff alike. Previously this exclusion only applied to private
messages.

Because small actions advanced highest_post_number, a topic whose only
new post was a small action (say an auto-close at the end of a thread)
was treated as unread: the nav "Unread (N)" badge counted it while
/unread did not list it — the "Unread (N) but /unread is empty" phantom
reported in https://meta.discourse.org/t/-/403986. More broadly, routine
administrivia such as bulk closes and auto-close timers should not
notify watchers or inflate reply counts
(https://meta.discourse.org/t/-/404058).

How it works:

- Topic.next_post_number assigns small actions a post_number but
advances no counter (whispers bump only the staff counter; small actions
bump neither).
- Topic.reset_highest / reset_all_highest! exclude them via two shared
SQL fragments — public_post_types_sql (no whispers, no small actions)
and staff_post_types_sql (no small actions) — collapsing the old
regular-vs-PM branches into one.
- PostCreator skips last_posted_at / last_post_user_id / word_count /
bumped_at and the user post count for small actions; PostDestroyer's
last-post lookup skips them too.
- TopicTrackingState / PrivateMessageTopicTrackingState#publish_unread
and the PostUpdateTopicTrackingState job return early for small actions.
- Category time-based post counts, UserStat#calc_topic_reply_count! and
the import.rake topic backfill exclude them as well.
- A post-deploy migration recomputes the affected counters for existing
topics and clamps any topic_users.last_read_post_number left pointing
past the new highest (whisperers to highest_staff_post_number, everyone
else to highest_post_number) so nobody is stuck with phantom read state.

Keeping the unread count and the /unread list filtering on the same
column is a separate, complementary fix that ships on its own. This
supersedes the earlier proof-of-concept PRs #40290 and #39093.
2026-06-08 08:03:55 +02:00
..
fixtures DEV: Persist dashboard configuration in table and *not* on closure of the dialog (#40546) 2026-06-04 10:53:59 +08:00
migrate DEV: Persist dashboard configuration in table and *not* on closure of the dialog (#40546) 2026-06-04 10:53:59 +08:00
post_migrate FEATURE: Exclude small actions from topic counters and unread tracking (#40481) 2026-06-08 08:03:55 +02:00
api_test_seeds.rb
structure.sql FEATURE: Exclude small actions from topic counters and unread tracking (#40481) 2026-06-08 08:03:55 +02:00