Skip to content

01a0abd6 - Put the closed Moderators group on /moderate - #243

Open
TaprootFreakAI wants to merge 22 commits into
developfrom
feat/01a0abd6-moderator-inbox
Open

TaprootFreakAI wants to merge 22 commits into
developfrom
feat/01a0abd6-moderator-inbox

Conversation

@TaprootFreakAI

@TaprootFreakAI TaprootFreakAI commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

EN:
Moves the closed Moderators group off /messages onto /moderate.
Confirmed moderators open it from the hub as /moderate/group; the page chrome is its only back control and the composer is text only.
The inbox never lists that thread and does not open it through ?c=.
Release the api first: the app needs GET /conversations/moderator-group.

DE:
Verschiebt die geschlossene Moderatoren-Gruppe von /messages nach /moderate.
Bestätigte Moderatorinnen und Moderatoren öffnen sie vom Hub unter /moderate/group; das einzige Zurück ist die Seitenleiste, der Composer ist reiner Text.
Die Inbox listet den Thread nicht und öffnet ihn auch nicht per ?c=.
Zuerst die API ausrollen: die App braucht GET /conversations/moderator-group.

Details
  • Hub: founders still see Hidden notes and Open proposals only. Confirmed moderators (role === 'moderator') get a further tool linking to /moderate/group. Founders and everyone else see moderate.groupForbidden there and nothing is fetched.
  • Staff room: ModeratorGroupScreen fetches GET /conversations/moderator-group then the thread and reuses InboxScreen as one open thread (showFilter false, showAmount false, heading always moderate.groupLabel). Back to /moderate is ProfileChromeLeft in the page chrome; the card has no back control, matching the one-back inbox.
  • Inbox: moderator_group rows are never listed. ?c= opens only after the list loaded. A listed moderator_group id never opens. For a confirmed moderator an unlisted ?c= first resolves the staff-room id once (neutral loading, not the list); a match never opens and fetchConversation is not called. Other roles and a failed lookup fall through to the api, which rejects accounts that may not read the thread.
  • After the rebase onto inbox unread: a thread can no longer load before the list, so the list-is-null badge fallback and the stale-list read guard were removed with their tests; the badge is refreshed once per opened thread from the loaded list.
  • Api: same-origin proxy GET /conversations/moderator-group; conversationResponseSchema parses { conversation } including unread.
  • Baselines: 20 /moderate/group Linux baselines from CI. The 4 welcome overlay-external-link baselines are the images develop itself renders (develop is red on that test); they are byte-identical to the develop unblocker af507305 - Unblocks develop: refresh the external-link overlay baselines #273.
  • Rollout: the endpoint exists on the api develop branch only. Api release first, app release right after; in between moderators merely do not see the group in the inbox list.

@TaprootFreakAI
TaprootFreakAI marked this pull request as ready for review September 16, 2026 22:42
@TaprootFreakAI
TaprootFreakAI marked this pull request as draft September 17, 2026 08:07
@TaprootFreakAI
TaprootFreakAI force-pushed the feat/01a0abd6-moderator-inbox branch 2 times, most recently from 7881bd7 to cfa156b Compare September 17, 2026 09:16
@TaprootFreakAI
TaprootFreakAI marked this pull request as ready for review September 17, 2026 17:43
@TaprootFreakAI
TaprootFreakAI marked this pull request as draft September 17, 2026 18:37
@TaprootFreakAI TaprootFreakAI changed the title 01a0abd6 - Pin the closed Moderators thread in the inbox 01a0abd6 - Put the closed Moderators group on /moderate Sep 17, 2026
@TaprootFreakAI
TaprootFreakAI force-pushed the feat/01a0abd6-moderator-inbox branch 3 times, most recently from 73761a8 to 2c308db Compare September 17, 2026 22:37
After rebasing onto develop the inbox card has no back control and every
conversation carries `unread`. The staff room follows both: `/moderate/group`
gets its only back control in the page chrome (`ProfileChromeLeft` to
`/moderate`), `InboxScreen` loses `backLabel`, and the group screen drops its
in-card back link. `?c=` still opens only after the inbox list loaded, so the
list-is-null badge fallback and the stale-list read guard can no longer run
and are removed with their three tests. Moderator-group fixtures and the
wrapper schema test carry `unread`; three thread-fetch assertions wait for
the effect instead of reading it in the same tick.
@TaprootFreakAI
TaprootFreakAI force-pushed the feat/01a0abd6-moderator-inbox branch from fe4a593 to 08551fc Compare September 18, 2026 19:02
The staff room reused the inbox card with an Amount field that could not be
typed into; `InboxScreen` gains `showAmount` and the group screen turns it
off. Its heading now always comes from `moderate.groupLabel` instead of the
api row name, and non-moderators read `moderate.groupForbidden` because
founders are not admitted there. On `/messages` the moderator lookup runs
once per opened id and shows neutral loading instead of the list while it
runs. `conversationOneSchema` becomes `conversationResponseSchema` like the
other envelope schemas, and the handbook names every caller of
`fetchModeratorGroup` and the exact `?c=` guard.
The 20 `/moderate/group` baselines follow the chrome-only back, the text-only
composer, and the new forbidden copy. The four `welcome overlay-external-link`
baselines are the images develop itself renders since Gift moved to replies
(byte-identical to the ones in the develop unblocker), so this branch is green
on its own.
Rows now count as loaded only for the session that fetched them, so a
session change waits for the new list before any thread fetch and the badge
is never computed from another session's rows. The `/moderate/group`
forbidden variant needle follows the new copy, so the e2e gate checks this
screen again instead of matching the hub's text. TSDoc of `InboxLoader`,
`InboxScreen` and `ModeratorGroupScreen` and a `/moderate/group` recipe in
docs/ui.md describe the lookup, `showAmount` and the catalog heading.
The session can only change through passkey login, where neither the inbox
nor the staff room is mounted, and through hydration, which refuses to swap
one token for another (`current.session !== null && current.session !==
token`). A token-to-token change on a mounted `InboxLoader` is therefore not
reachable, so the `listSession` gate guarded a state the app cannot enter and
left the composer callbacks and the staff room inconsistent with it. The
loader logic is back to the reviewed one; the needle, TSDoc, docs/ui.md
recipe and the falsifiable neutral-loading test stay.
@TaprootFreakAI

Copy link
Copy Markdown
Collaborator Author

EN:
Ready after 6 review passes.
Moves the closed Moderators group from the inbox to /moderate/group, with the page chrome as its only back control.

DE:
Bereit nach 6 Review-Durchläufen.
Verschiebt die geschlossene Moderatoren-Gruppe aus dem Posteingang nach /moderate/group, mit der Seitenleiste als einzigem Zurück.

Details

Head 878fa4f5, rebased onto develop a71d717c (after #255 inbox unread, #237, #259, #264, #266 one-back inbox). Three passes ran on the earlier stand, three on the rebased one.

Rebase reconciliation

Fixed during review

  • Pass 4: the staff room showed an Amount field that could not be typed into → InboxScreen.showAmount, off for the staff room. Forbidden copy said "founders and moderators" although founders are not admitted → moderate.groupForbidden in all four locales. Loaded heading now always comes from moderate.groupLabel. On /messages the moderator lookup runs once per opened id and shows neutral loading instead of the list. conversationOneSchemaconversationResponseSchema. Handbook: every caller of fetchModeratorGroup, the exact ?c= guard, the /moderate/group actions and calls.
  • Pass 5: the /moderate/group forbidden variant needle still matched the hub's copy, so the e2e gate did not check this screen → fixed. TSDoc of InboxLoader, InboxScreen, ModeratorGroupScreen; /moderate/group recipe in docs/ui.md; neutral-loading test seeded with a Direct row so its list assertion can fail.
  • Pass 6: 0 findings on both dimensions.

Decided, not changed

  • When the staff-room lookup fails for a moderator opening an unlisted ?c=, the inbox falls through and opens the thread. Deliberate and tested; not an ACL matter because the api admits moderators to that thread; documented in the InboxLoader handbook entry.
  • A session-bound inbox list was added in pass 5 and removed again: the session only changes through passkey login (neither component is mounted there) and hydration, which refuses to swap one token for another, so a token-to-token change on a mounted tree is not reachable.

Baselines

Verification at the head

  • CI: all six jobs green (checks, E2E behavior, four Visual projects).
  • Full local chain at the exact commit: typecheck, lint, handbook/e2e/screenshot checks, 2726 tests with 100% coverage, build.

Rollout note

  • The app calls GET /conversations/moderator-group, which exists on the api develop branch only. Release the api first and the app right after it; until the app is live, moderators merely do not see the group in the inbox list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant