Document why there are more memberships than channels #428

Merged
robbertbos merged 1 commit from mm-archived-memberships into main 2026-09-24 20:19:17 +00:00
Owner

Answers the first question of #400 (why 458 memberships but 420 channels) from the Mattermost server source, at mattermost/mattermost 53211e45b, server/channels/store/sqlstore/channel_store.go:

  • GET /users/me/channel_members (GetMembersForUserWithPagination) returns every membership. The only filter is on channel types that carry no messages, so archived channels and channels of a deleted team are included.
  • GET /users/me/channels (GetChannelsByUser) adds Channels.DeleteAt = 0 and "team not deleted" unless include_deleted=true.
  • The same handler (api4/channel.go, getChannelsForUser) pages internally in steps of 100 and streams the whole list ("the client always needs to get the full data"). That is why it ignores page/per_page, and why it is never truncated.

So the 38 are archived channels or channels of a deleted team. Waggle already gives them no Postvak row: the listing iterates over channels, and the channel-window endpoint reads one as fully read (_UNKNOWN_CHANNEL). That matches Mattermost, which hides archived channels by default. No code change is needed; this PR records the finding in CLAUDE.md's Mattermost gotchas and corrects the _UNKNOWN_CHANNEL comment.

Not addressed, deliberately: the second half of #400, whether muted channels with unread messages should surface in Meelezen. That is a reading-model decision, not something to settle in a patch, so #400 stays open for it.

Docs and a comment only, so no CHANGELOG entry.

Answers the first question of #400 (why 458 memberships but 420 channels) from the Mattermost server source, at `mattermost/mattermost` `53211e45b`, `server/channels/store/sqlstore/channel_store.go`: - `GET /users/me/channel_members` (`GetMembersForUserWithPagination`) returns every membership. The only filter is on channel types that carry no messages, so archived channels and channels of a deleted team are included. - `GET /users/me/channels` (`GetChannelsByUser`) adds `Channels.DeleteAt = 0` and "team not deleted" unless `include_deleted=true`. - The same handler (`api4/channel.go`, `getChannelsForUser`) pages internally in steps of 100 and streams the whole list ("the client always needs to get the full data"). That is why it ignores `page`/`per_page`, and why it is never truncated. So the 38 are archived channels or channels of a deleted team. Waggle already gives them no Postvak row: the listing iterates over channels, and the channel-window endpoint reads one as fully read (`_UNKNOWN_CHANNEL`). That matches Mattermost, which hides archived channels by default. No code change is needed; this PR records the finding in CLAUDE.md's Mattermost gotchas and corrects the `_UNKNOWN_CHANNEL` comment. Not addressed, deliberately: the second half of #400, whether muted channels with unread messages should surface in Meelezen. That is a reading-model decision, not something to settle in a patch, so #400 stays open for it. Docs and a comment only, so no CHANGELOG entry.
Document why there are more memberships than channels
All checks were successful
security-scan / SBOM (trivy) (pull_request) Successful in 16s
CI / release-scripts (pull_request) Successful in 19s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 27s
security-scan / JS SCA (npm audit) (pull_request) Successful in 33s
security-scan / Python SAST (bandit) (pull_request) Successful in 42s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 1m1s
test-build / build (frontend) (pull_request) Successful in 1m46s
test-build / build (backend) (pull_request) Successful in 1m52s
test-build / build (pull_request) Successful in 0s
CI / pre-commit (pull_request) Successful in 2m4s
CI / e2e (pull_request) Successful in 6m58s
CI / frontend-test (pull_request) Successful in 5m49s
CI / backend-test (pull_request) Successful in 21m22s
07067e147c
/users/me/channel_members returns every membership, including archived
channels and channels of a deleted team; /users/me/channels leaves both
out unless include_deleted=true, and streams its full list, so it is
never truncated. Measured on a real account the surplus was 38 rows;
they are those channels, and getting no Postvak row is right for them.
Verified against mattermost/mattermost at 53211e45b.
robbertbos scheduled this pull request to auto merge when all checks succeed 2026-09-24 05:46:48 +00:00
robbertbos force-pushed mm-archived-memberships from 07067e147c
All checks were successful
security-scan / SBOM (trivy) (pull_request) Successful in 16s
CI / release-scripts (pull_request) Successful in 19s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 27s
security-scan / JS SCA (npm audit) (pull_request) Successful in 33s
security-scan / Python SAST (bandit) (pull_request) Successful in 42s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 1m1s
test-build / build (frontend) (pull_request) Successful in 1m46s
test-build / build (backend) (pull_request) Successful in 1m52s
test-build / build (pull_request) Successful in 0s
CI / pre-commit (pull_request) Successful in 2m4s
CI / e2e (pull_request) Successful in 6m58s
CI / frontend-test (pull_request) Successful in 5m49s
CI / backend-test (pull_request) Successful in 21m22s
to 949cf4f0dc
Some checks failed
CI / pre-commit (pull_request) Successful in 2m0s
CI / frontend-test (pull_request) Successful in 5m32s
CI / e2e (pull_request) Failing after 28m9s
CI / backend-test (pull_request) Failing after 35m37s
CI / release-scripts (pull_request) Successful in 15s
security-scan / JS SCA (npm audit) (pull_request) Successful in 25s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 23s
security-scan / Python SAST (bandit) (pull_request) Successful in 32s
security-scan / SBOM (trivy) (pull_request) Successful in 14s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 53s
test-build / build (frontend) (pull_request) Successful in 1m35s
test-build / build (backend) (pull_request) Successful in 1m45s
test-build / build (pull_request) Successful in 0s
2026-09-24 05:46:53 +00:00
Compare
robbertbos force-pushed mm-archived-memberships from 949cf4f0dc
Some checks failed
CI / pre-commit (pull_request) Successful in 2m0s
CI / frontend-test (pull_request) Successful in 5m32s
CI / e2e (pull_request) Failing after 28m9s
CI / backend-test (pull_request) Failing after 35m37s
CI / release-scripts (pull_request) Successful in 15s
security-scan / JS SCA (npm audit) (pull_request) Successful in 25s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 23s
security-scan / Python SAST (bandit) (pull_request) Successful in 32s
security-scan / SBOM (trivy) (pull_request) Successful in 14s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 53s
test-build / build (frontend) (pull_request) Successful in 1m35s
test-build / build (backend) (pull_request) Successful in 1m45s
test-build / build (pull_request) Successful in 0s
to e8290504cb
Some checks failed
CI / release-scripts (pull_request) Failing after 14s
security-scan / SBOM (trivy) (pull_request) Successful in 16s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 22s
security-scan / JS SCA (npm audit) (pull_request) Successful in 24s
security-scan / Python SAST (bandit) (pull_request) Successful in 34s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 47s
CI / frontend-test (pull_request) Successful in 1m14s
CI / pre-commit (pull_request) Successful in 1m25s
test-build / build (backend) (pull_request) Successful in 1m19s
test-build / build (frontend) (pull_request) Successful in 1m14s
test-build / build (pull_request) Successful in 0s
CI / backend-test (pull_request) Successful in 5m35s
CI / e2e (pull_request) Successful in 6m42s
2026-09-24 20:03:15 +00:00
Compare
robbertbos force-pushed mm-archived-memberships from e8290504cb
Some checks failed
CI / release-scripts (pull_request) Failing after 14s
security-scan / SBOM (trivy) (pull_request) Successful in 16s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 22s
security-scan / JS SCA (npm audit) (pull_request) Successful in 24s
security-scan / Python SAST (bandit) (pull_request) Successful in 34s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 47s
CI / frontend-test (pull_request) Successful in 1m14s
CI / pre-commit (pull_request) Successful in 1m25s
test-build / build (backend) (pull_request) Successful in 1m19s
test-build / build (frontend) (pull_request) Successful in 1m14s
test-build / build (pull_request) Successful in 0s
CI / backend-test (pull_request) Successful in 5m35s
CI / e2e (pull_request) Successful in 6m42s
to 9c1ca9db9f
All checks were successful
CI / e2e (push) Successful in 5m16s
CI / release-scripts (pull_request) Successful in 20s
security-scan / SBOM (trivy) (pull_request) Successful in 14s
security-scan / Python SAST (bandit) (pull_request) Successful in 30s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 22s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 49s
CI / pre-commit (pull_request) Successful in 1m24s
CI / frontend-test (pull_request) Successful in 1m25s
test-build / build (frontend) (pull_request) Successful in 1m16s
test-build / build (backend) (pull_request) Successful in 1m23s
test-build / build (pull_request) Successful in 0s
security-scan / JS SCA (npm audit) (pull_request) Successful in 2m21s
CI / backend-test (pull_request) Successful in 4m15s
CI / e2e (pull_request) Successful in 6m8s
tag-release / release (push) Successful in 6s
publish-and-stage / decide (push) Successful in 7s
CI / release-scripts (push) Successful in 10s
security-scan / SBOM (trivy) (push) Successful in 11s
security-scan / JS SCA (npm audit) (push) Successful in 17s
security-scan / Filesystem scan (trivy fs) (push) Successful in 18s
security-scan / Python SAST (bandit) (push) Successful in 22s
security-scan / Python SCA (pip-audit) (push) Successful in 40s
CI / pre-commit (push) Successful in 1m0s
CI / frontend-test (push) Successful in 1m2s
publish-and-stage / build (frontend) (push) Successful in 1m13s
publish-and-stage / build (backend) (push) Successful in 1m17s
publish-and-stage / build (push) Successful in 0s
publish-and-stage / deploy-staging (push) Successful in 1m20s
CI / backend-test (push) Successful in 2m55s
2026-09-24 20:13:07 +00:00
Compare
robbertbos deleted branch mm-archived-memberships 2026-09-24 20:19:17 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
robbertbos/waggle!428
No description provided.