Skip to content

Conversation

@aleksandernsilva
Copy link
Contributor

@aleksandernsilva aleksandernsilva commented Nov 25, 2025

Proposed changes (including videos or screenshots)

This pull request adds support for invitation requests to rooms.

  • Added support for invitation requests to rooms based on subscription containing status INVITED.
    • New components introduced: RoomInviteHeader, RoomInviteBody, RoomInvite.
  • Added support for not rendering a toolbox when using RoomLayout
  • Added a new roomReference query key to queryKeys.ts
  • Granted user access to rooms where the user has a subscription pending invitation action.
Screenshot 2025-11-26 at 12 43 22

Issue(s)

FB-65

Steps to test or reproduce

ℹ️ Currently invitation requests are only available for federated rooms.
ℹ️ You'll need two workspaces with federation enabled (I'll refer to them as ws-a and ws-b)

  • Create a room federated room (ws-a)
  • Invite an user from ws-b to the room (ws-a)
  • In ws-b the room invitation should become visible in the sidebar (ws-b)
    Scenario A
  • Accept invitation (ws-b)
  • Room messages should become available (ws-b)
    Scenario B
  • Reject invitation (ws-b)
  • Should be redirected to /home (ws-b)

Further comments

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for room invitation requests, allowing users to accept or reject invitations to federated rooms with a dedicated invitation interface.
  • Tests

    • Added comprehensive test coverage for invitation components and functionality.

✏️ Tip: You can customize this high-level summary in your review settings.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Nov 25, 2025

Looks like this PR is ready to merge! 🎉
If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Nov 25, 2025

🦋 Changeset detected

Latest commit: e4a3790

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 42 packages
Name Type
@rocket.chat/meteor Patch
@rocket.chat/core-typings Patch
@rocket.chat/i18n Patch
@rocket.chat/uikit-playground Patch
@rocket.chat/api-client Patch
@rocket.chat/apps Patch
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/ddp-client Patch
@rocket.chat/freeswitch Patch
@rocket.chat/fuselage-ui-kit Patch
@rocket.chat/gazzodown Patch
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/rest-typings Patch
@rocket.chat/ui-avatar Patch
@rocket.chat/ui-client Patch
@rocket.chat/ui-contexts Patch
@rocket.chat/ui-voip Patch
@rocket.chat/web-ui-registration Patch
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/stream-hub-service Patch
@rocket.chat/federation-matrix Patch
@rocket.chat/license Patch
@rocket.chat/media-calls Patch
@rocket.chat/omnichannel-services Patch
@rocket.chat/pdf-worker Patch
@rocket.chat/presence Patch
rocketchat-services Patch
@rocket.chat/mock-providers Patch
@rocket.chat/network-broker Patch
@rocket.chat/omni-core-ee Patch
@rocket.chat/models Patch
@rocket.chat/ui-video-conf Patch
@rocket.chat/instance-status Patch
@rocket.chat/omni-core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 25, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This pull request introduces invitation request support for federated rooms. It adds client-side UI components for displaying and responding to room invitations (RoomInviteHeader, RoomInviteBody), a hook for handling invitation accept/reject actions, type guards for detecting invite subscriptions, server-side authorization validation, and supporting infrastructure including query keys, i18n strings, and comprehensive test coverage.

Changes

Cohort / File(s) Summary
Query Keys & Utilities
apps/meteor/client/lib/queryKeys.ts, apps/meteor/tests/mocks/utils/createDeferredMockFn.ts
Adds roomReference query key function to roomsQueryKeys for efficient room lookups by reference and type; exports createDeferredPromise utility function for test mocking.
Type Guards & Core Typings
packages/core-typings/src/ISubscription.ts
Introduces isInviteSubscription type guard to detect subscriptions with status 'INVITED'.
Invite Header Components (V1)
apps/meteor/client/views/room/Header/Header.tsx, apps/meteor/client/views/room/Header/RoomInviteHeader.tsx, apps/meteor/client/views/room/Header/RoomInviteHeader.stories.tsx, apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx
Creates RoomInviteHeader component (wraps RoomHeader with hidden toolbox) and integrates into Header with subscription detection; includes stories and tests.
Invite Header Components (V2)
apps/meteor/client/views/room/HeaderV2/Header.tsx, apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.tsx, apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.stories.tsx, apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx
Parallel implementation of RoomInviteHeader for V2 header variant with subscription integration; includes stories and tests.
Room Header Testing
apps/meteor/client/views/room/Header/RoomHeader.spec.tsx, apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx
Adds test suites validating RoomHeader toolbox rendering behavior under various conditions (default, hidden, slotted, custom content).
Invitation UI Body
apps/meteor/client/views/room/body/RoomInviteBody.tsx, apps/meteor/client/views/room/body/RoomInviteBody.stories.tsx, apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx
Creates RoomInviteBody component with Mail icon, inviter info, Accept/Reject buttons, and optional Information link; includes stories with Loading and WithInfoLink variants and comprehensive tests.
Invitation Logic & Main Room View
apps/meteor/client/views/room/RoomInvite.tsx, apps/meteor/client/views/room/Room.tsx
Introduces RoomInvite component composing invitation header and body; integrates into Room.tsx with early-return path for invite subscriptions via useRoomSubscription hook.
Invitation Hook
apps/meteor/client/views/room/hooks/useRoomInvitation.tsx, apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx
Implements useRoomInvitation hook managing accept/reject mutations via /v1/rooms.invite endpoint; includes navigation to /home on reject and query invalidation logic.
Room Lookup Hook
apps/meteor/client/views/room/hooks/useOpenRoom.ts
Refactors queryKey to use new roomsQueryKeys.roomReference helper.
Server Authorization
apps/meteor/server/services/authorization/canAccessRoom.ts
Adds _validateAccessToInvitedRooms validator to allow access for users with invite subscriptions.
Server Configuration
apps/meteor/app/lib/server/functions/createDirectRoom.ts
Adds non-null assertions for creatorUser.username in federated direct room creation.
Internationalization
packages/i18n/src/locales/en.i18n.json
Adds i18n keys: You_have_been_invited_to_have_a_conversation_with, Learn_more_about_Federation, Message_request, unknown.
Changeset
.changeset/chatty-roses-help.md
Patch-level changeset documenting invitation request support feature.

Sequence Diagram

sequenceDiagram
    actor User
    participant Room View as Room View<br/>(Room.tsx)
    participant Subscription as RoomContext<br/>(useRoomSubscription)
    participant Invite UI as RoomInvite<br/>Component
    participant Mutation as Invitation Mutation<br/>(useRoomInvitation)
    participant Server as Server<br/>/v1/rooms.invite
    participant Query as Query Client<br/>(React Query)
    participant Router as Router

    User->>Room View: Load invited room
    Room View->>Subscription: Check subscription status
    Subscription-->>Room View: subscription with status='INVITED'
    
    alt Invite Subscription Detected
        Room View->>Invite UI: Render RoomInvite early return
        Invite UI-->>User: Display inviter info + Accept/Reject
        
        User->>Invite UI: Click Accept/Reject
        Invite UI->>Mutation: Call acceptInvite/rejectInvite
        Mutation->>Server: POST /v1/rooms.invite {action}
        Server-->>Mutation: Success
        Mutation->>Query: Invalidate & refetch room query
        Query-->>Mutation: Resolved
        
        alt Action = 'reject'
            Mutation->>Router: Navigate to /home
            Router-->>User: Redirect
        else Action = 'accept'
            Mutation-->>User: Room ready (normal view)
        end
    else Regular Room
        Room View->>Room View: Continue normal rendering
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

  • RoomInvite flow integration — Verify subscription detection, early-return logic, and correct prop threading through Room.tsx → Header components → RoomInvite
  • Invitation mutation lifecycle — Confirm accept/reject payloads, query invalidation, and navigation behavior (especially reject redirecting to /home)
  • Header V1/V2 consistency — Ensure both Header variants apply subscription check and RoomInviteHeader rendering identically
  • Server authorization validator — Validate that _validateAccessToInvitedRooms correctly identifies invite subscriptions and doesn't bypass existing checks
  • i18n key placement — Confirm all new keys are properly integrated and used in the correct component files

Possibly related PRs

Suggested reviewers

  • ricardogarim
  • sampaiodiego

Poem

🐰 A hop, a skip, a queue so grand,
Invites now flutter through the land!
With headers fresh and bodies bright,
We've woven federation's light.
Accept or reject—the choice is thine,
Rocket.Chat's invitation design! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding pending invitation state to rooms, which aligns with the primary objective of the PR.
Linked Issues check ✅ Passed The PR implements invitation state handling for rooms with new components (RoomInviteHeader, RoomInviteBody, RoomInvite) and acceptance/rejection logic, fulfilling FB-65 requirements for the invited empty state.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing invitation support: new invite components, query keys for room references, authorization validators, type guards, i18n strings, and test coverage. No unrelated modifications detected.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 066cda3 and e4a3790.

⛔ Files ignored due to path filters (3)
  • apps/meteor/client/views/room/Header/__snapshots__/RoomInviteHeader.spec.tsx.snap is excluded by !**/*.snap
  • apps/meteor/client/views/room/HeaderV2/__snapshots__/RoomInviteHeader.spec.tsx.snap is excluded by !**/*.snap
  • apps/meteor/client/views/room/body/__snapshots__/RoomInviteBody.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (18)
  • .changeset/chatty-roses-help.md (1 hunks)
  • apps/meteor/app/lib/server/functions/createDirectRoom.ts (1 hunks)
  • apps/meteor/client/lib/queryKeys.ts (1 hunks)
  • apps/meteor/client/views/room/Header/Header.tsx (3 hunks)
  • apps/meteor/client/views/room/Header/RoomHeader.spec.tsx (1 hunks)
  • apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx (1 hunks)
  • apps/meteor/client/views/room/Header/RoomInviteHeader.stories.tsx (1 hunks)
  • apps/meteor/client/views/room/Header/RoomInviteHeader.tsx (1 hunks)
  • apps/meteor/client/views/room/HeaderV2/Header.tsx (2 hunks)
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx (1 hunks)
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx (1 hunks)
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.stories.tsx (1 hunks)
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.tsx (1 hunks)
  • apps/meteor/client/views/room/Room.tsx (3 hunks)
  • apps/meteor/client/views/room/RoomInvite.tsx (1 hunks)
  • apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx (1 hunks)
  • apps/meteor/client/views/room/body/RoomInviteBody.stories.tsx (1 hunks)
  • apps/meteor/client/views/room/body/RoomInviteBody.tsx (1 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@aleksandernsilva aleksandernsilva marked this pull request as ready for review November 26, 2025 15:54
@aleksandernsilva aleksandernsilva requested review from a team as code owners November 26, 2025 15:54
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (9)
apps/meteor/client/views/room/hooks/useOpenRoom.ts (1)

27-27: LGTM: Good refactoring to use centralized query key helper.

Replacing the inline query key construction with roomsQueryKeys.roomReference improves maintainability and ensures consistency across the codebase.

apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx (1)

1-52: Good coverage; consider adding a loading-state interaction test

The suite nicely covers snapshots, a11y, and basic Accept/Reject interactions. Since RoomInviteBody exposes an isLoading prop that changes button behavior, consider adding a test that renders with isLoading set, asserts the buttons are disabled/“loading”, and verifies clicks don’t trigger handlers. This would lock in the async/pending UX.

packages/core-typings/src/ISubscription.ts (1)

10-93: Invite type guard looks correct; consider tightening inviter typing if possible

isInviteSubscription correctly narrows to status: 'INVITED' and is a good fit for the new invite header logic.

If the backend guarantees that invite subscriptions always include a non-empty inviterUsername, you might consider encoding that in the guard:

export const isInviteSubscription = (
  subscription: ISubscription | undefined | null,
): subscription is ISubscription & { status: 'INVITED'; inviterUsername: string } =>
  subscription?.status === 'INVITED' && !!subscription.inviterUsername;

That would let downstream code treat inviterUsername as required whenever the guard passes.

apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx (1)

1-42: Optionally assert toolbox absence for invite scenarios

Snapshots + a11y checks are solid. Given the main behavioral guarantee of RoomInviteHeader is “header without toolbox for invite rooms”, you might add a focused test (e.g., on the primary story) that asserts queryByLabelText('Toolbox_room_actions') returns null. That would more directly pin the invite-specific behavior instead of relying solely on underlying RoomHeader tests.

apps/meteor/client/views/room/HeaderV2/RoomHeader.tsx (1)

17-68: Clarify roomToolbox null semantics in the render condition

The toolbox conditional

{(slots.toolbox || roomToolbox !== null) && (
  ...
    {slots?.toolbox?.content || roomToolbox || <RoomToolbox />}
)}

means the toolbar is rendered whenever slots.toolbox is truthy or roomToolbox is anything except null (including undefined), and only hidden when roomToolbox === null and there’s no slots.toolbox. That matches the current tests but is a bit non-obvious at a glance.

For readability, consider extracting a named boolean, e.g.:

const shouldRenderToolbox = Boolean(slots.toolbox) || roomToolbox !== null;

{shouldRenderToolbox && (
  ...
)}

or documenting via prop naming/typing that “null explicitly disables the toolbox, undefined keeps the default toolbox”.

packages/i18n/src/locales/en.i18n.json (1)

3453-3453: Title casing recommended for the "Message_request" string used in heading context.

The string is rendered within a <StatesTitle> component in RoomInviteBody.tsx (line 19), which displays it as an <h3> heading. While the current sentence casing ("Message request") matches the predominant pattern in this section of the i18n file, title casing ("Message Request") would provide better UI consistency for heading text. The suggestion is valid and worth addressing.

apps/meteor/client/views/room/RoomInvite.tsx (1)

9-9: Use import type for type-only imports.

IRoomWithFederationOriginalName is only used as a type, so it should use a type-only import for consistency and to avoid potential bundling issues.

-import { IRoomWithFederationOriginalName } from './contexts/RoomContext';
+import type { IRoomWithFederationOriginalName } from './contexts/RoomContext';
apps/meteor/client/lib/queryKeys.ts (1)

16-20: Add as const for type consistency with other query keys.

Other key generators in this file use as const to ensure readonly tuple typing. Adding it here maintains consistency and provides better type inference.

 roomReference: (reference: string, type: RoomType, uid?: IUser['_id'], username?: IUser['username']) => [
 	...roomsQueryKeys.all,
 	{ reference, type },
 	{ uid, username },
-],
+] as const,
apps/meteor/client/views/room/body/RoomInviteBody.stories.tsx (1)

4-4: Rename import for clarity: RoomInviteRoomInviteBody.

The import alias is confusing since it doesn't match the component name. This could cause confusion when reading the story file, especially since there's a separate RoomInvite component in the codebase.

-import RoomInvite from './RoomInviteBody';
+import RoomInviteBody from './RoomInviteBody';

Then update line 7:

-	component: RoomInvite,
+	component: RoomInviteBody,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0fe730a and 1258559.

⛔ Files ignored due to path filters (3)
  • apps/meteor/client/views/room/Header/__snapshots__/RoomInviteHeader.spec.tsx.snap is excluded by !**/*.snap
  • apps/meteor/client/views/room/HeaderV2/__snapshots__/RoomInviteHeader.spec.tsx.snap is excluded by !**/*.snap
  • apps/meteor/client/views/room/body/__snapshots__/RoomInviteBody.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (27)
  • .changeset/chatty-roses-help.md (1 hunks)
  • apps/meteor/client/lib/queryKeys.ts (1 hunks)
  • apps/meteor/client/views/room/Header/Header.tsx (3 hunks)
  • apps/meteor/client/views/room/Header/RoomHeader.spec.tsx (1 hunks)
  • apps/meteor/client/views/room/Header/RoomHeader.tsx (2 hunks)
  • apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx (1 hunks)
  • apps/meteor/client/views/room/Header/RoomInviteHeader.stories.tsx (1 hunks)
  • apps/meteor/client/views/room/Header/RoomInviteHeader.tsx (1 hunks)
  • apps/meteor/client/views/room/HeaderV2/Header.tsx (2 hunks)
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx (1 hunks)
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.tsx (2 hunks)
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx (1 hunks)
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.stories.tsx (1 hunks)
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.tsx (1 hunks)
  • apps/meteor/client/views/room/Room.tsx (3 hunks)
  • apps/meteor/client/views/room/RoomHeader.tsx (1 hunks)
  • apps/meteor/client/views/room/RoomInvite.tsx (1 hunks)
  • apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx (1 hunks)
  • apps/meteor/client/views/room/body/RoomInviteBody.stories.tsx (1 hunks)
  • apps/meteor/client/views/room/body/RoomInviteBody.tsx (1 hunks)
  • apps/meteor/client/views/room/hooks/useOpenRoom.ts (1 hunks)
  • apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx (1 hunks)
  • apps/meteor/client/views/room/hooks/useRoomInvitation.tsx (1 hunks)
  • apps/meteor/server/services/authorization/canAccessRoom.ts (2 hunks)
  • apps/meteor/tests/mocks/utils/createDeferredMockFn.ts (1 hunks)
  • packages/core-typings/src/ISubscription.ts (1 hunks)
  • packages/i18n/src/locales/en.i18n.json (3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx
  • packages/core-typings/src/ISubscription.ts
  • apps/meteor/client/views/room/Header/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.tsx
  • apps/meteor/client/views/room/body/RoomInviteBody.tsx
  • apps/meteor/client/views/room/Header/RoomHeader.tsx
  • apps/meteor/client/views/room/Header/RoomInviteHeader.tsx
  • apps/meteor/server/services/authorization/canAccessRoom.ts
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.stories.tsx
  • apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx
  • apps/meteor/client/views/room/hooks/useOpenRoom.ts
  • apps/meteor/client/lib/queryKeys.ts
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx
  • apps/meteor/client/views/room/hooks/useRoomInvitation.tsx
  • apps/meteor/client/views/room/RoomHeader.tsx
  • apps/meteor/client/views/room/RoomInvite.tsx
  • apps/meteor/client/views/room/body/RoomInviteBody.stories.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.tsx
  • apps/meteor/client/views/room/Header/RoomInviteHeader.stories.tsx
  • apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx
  • apps/meteor/client/views/room/Room.tsx
  • apps/meteor/tests/mocks/utils/createDeferredMockFn.ts
  • apps/meteor/client/views/room/Header/Header.tsx
  • apps/meteor/client/views/room/HeaderV2/Header.tsx
🧠 Learnings (20)
📓 Common learnings
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37377
File: apps/meteor/ee/server/hooks/federation/index.ts:86-88
Timestamp: 2025-11-04T16:49:19.107Z
Learning: In Rocket.Chat's federation system (apps/meteor/ee/server/hooks/federation/), permission checks follow two distinct patterns: (1) User-initiated federation actions (creating rooms, adding users to federated rooms, joining from invites) should throw MeteorError to inform users they lack 'access-federation' permission. (2) Remote server-initiated federation events should silently skip/ignore when users lack permission. The beforeAddUserToRoom hook only executes for local user-initiated actions, so throwing an error there is correct. Remote federation events are handled separately by the federation Matrix package with silent skipping logic.
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (`test`, `page`, `expect`) for consistency in test files

Applied to files:

  • apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx
  • apps/meteor/client/views/room/Header/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx
  • apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Prefer web-first assertions (`toBeVisible`, `toHaveText`, etc.) in Playwright tests

Applied to files:

  • apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx
  • apps/meteor/client/views/room/Header/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx
  • apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `expect` matchers for assertions (`toEqual`, `toContain`, `toBeTruthy`, `toHaveLength`, etc.) instead of `assert` statements in Playwright tests

Applied to files:

  • apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx
  • apps/meteor/client/views/room/Header/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx
  • apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file

Applied to files:

  • apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx
  • apps/meteor/client/views/room/Header/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx
  • apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,spec.ts} : Follow Page Object Model pattern consistently in Playwright tests

Applied to files:

  • apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx
  • apps/meteor/client/views/room/Header/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx
  • apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Maintain test isolation between test cases in Playwright tests

Applied to files:

  • apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx
  • apps/meteor/client/views/room/Header/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx
  • apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `test.step()` for complex test scenarios to improve organization in Playwright tests

Applied to files:

  • apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx
  • apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx
  • apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : All test files must be created in `apps/meteor/tests/e2e/` directory

Applied to files:

  • apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx
  • apps/meteor/client/views/room/Header/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx
  • apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/page-objects/**/*.ts : Utilize existing page objects pattern from `apps/meteor/tests/e2e/page-objects/`

Applied to files:

  • apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx
  • apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to **/*.spec.ts : Use descriptive test names that clearly communicate expected behavior in Playwright tests

Applied to files:

  • apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx
  • apps/meteor/client/views/room/Header/RoomHeader.spec.tsx
📚 Learning: 2025-10-06T20:32:23.658Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37152
File: packages/apps-engine/tests/test-data/utilities.ts:557-573
Timestamp: 2025-10-06T20:32:23.658Z
Learning: In packages/apps-engine/tests/test-data/utilities.ts, the field name `isSubscripbedViaBundle` in the `IMarketplaceSubscriptionInfo` type should not be flagged as a typo, as it may match the upstream API's field name.

Applied to files:

  • packages/core-typings/src/ISubscription.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • apps/meteor/client/views/room/Header/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx
  • apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure clean state for each test execution in Playwright tests

Applied to files:

  • apps/meteor/client/views/room/Header/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx
  • apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx
📚 Learning: 2025-10-28T16:53:42.761Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.

Applied to files:

  • apps/meteor/client/views/room/body/RoomInviteBody.tsx
  • apps/meteor/server/services/authorization/canAccessRoom.ts
  • apps/meteor/client/views/room/hooks/useOpenRoom.ts
  • apps/meteor/client/lib/queryKeys.ts
  • apps/meteor/client/views/room/hooks/useRoomInvitation.tsx
  • apps/meteor/client/views/room/RoomInvite.tsx
  • apps/meteor/client/views/room/Room.tsx
  • apps/meteor/client/views/room/Header/Header.tsx
  • .changeset/chatty-roses-help.md
  • apps/meteor/client/views/room/HeaderV2/Header.tsx
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.

Applied to files:

  • apps/meteor/server/services/authorization/canAccessRoom.ts
  • apps/meteor/client/views/room/hooks/useOpenRoom.ts
  • apps/meteor/client/lib/queryKeys.ts
  • apps/meteor/client/views/room/Room.tsx
  • apps/meteor/client/views/room/Header/Header.tsx
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.

Applied to files:

  • apps/meteor/server/services/authorization/canAccessRoom.ts
  • apps/meteor/client/views/room/hooks/useOpenRoom.ts
  • apps/meteor/client/lib/queryKeys.ts
  • apps/meteor/client/views/room/Room.tsx
  • apps/meteor/client/views/room/Header/Header.tsx
📚 Learning: 2025-11-04T16:49:19.107Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37377
File: apps/meteor/ee/server/hooks/federation/index.ts:86-88
Timestamp: 2025-11-04T16:49:19.107Z
Learning: In Rocket.Chat's federation system (apps/meteor/ee/server/hooks/federation/), permission checks follow two distinct patterns: (1) User-initiated federation actions (creating rooms, adding users to federated rooms, joining from invites) should throw MeteorError to inform users they lack 'access-federation' permission. (2) Remote server-initiated federation events should silently skip/ignore when users lack permission. The beforeAddUserToRoom hook only executes for local user-initiated actions, so throwing an error there is correct. Remote federation events are handled separately by the federation Matrix package with silent skipping logic.

Applied to files:

  • apps/meteor/server/services/authorization/canAccessRoom.ts
  • apps/meteor/client/views/room/hooks/useRoomInvitation.tsx
  • .changeset/chatty-roses-help.md
📚 Learning: 2025-11-19T12:32:29.696Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37547
File: packages/i18n/src/locales/en.i18n.json:634-634
Timestamp: 2025-11-19T12:32:29.696Z
Learning: Repo: RocketChat/Rocket.Chat
Context: i18n workflow
Learning: In this repository, new translation keys should be added to packages/i18n/src/locales/en.i18n.json only; other locale files are populated via the external translation pipeline and/or fall back to English. Do not request adding the same key to all locale files in future reviews.

Applied to files:

  • .changeset/chatty-roses-help.md
  • packages/i18n/src/locales/en.i18n.json
📚 Learning: 2025-11-19T18:20:07.720Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37419
File: packages/i18n/src/locales/en.i18n.json:918-921
Timestamp: 2025-11-19T18:20:07.720Z
Learning: Repo: RocketChat/Rocket.Chat — i18n/formatting
Learning: This repository uses a custom message formatting parser in UI blocks/messages; do not assume standard Markdown rules. For keys like Call_ended_bold, Call_not_answered_bold, Call_failed_bold, and Call_transferred_bold in packages/i18n/src/locales/en.i18n.json, retain the existing single-asterisk emphasis unless maintainers request otherwise.

Applied to files:

  • .changeset/chatty-roses-help.md
  • packages/i18n/src/locales/en.i18n.json
🧬 Code graph analysis (15)
apps/meteor/client/views/room/body/RoomInviteBody.spec.tsx (2)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/lib/appLayout.tsx (1)
  • render (26-28)
apps/meteor/client/views/room/body/RoomInviteBody.tsx (1)
packages/livechat/src/components/Button/index.tsx (1)
  • Button (34-99)
apps/meteor/server/services/authorization/canAccessRoom.ts (1)
packages/core-typings/src/ISubscription.ts (1)
  • isInviteSubscription (89-93)
apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx (3)
apps/meteor/tests/mocks/data.ts (1)
  • createFakeRoom (46-61)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/lib/appLayout.tsx (1)
  • render (26-28)
apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.stories.tsx (1)
apps/meteor/tests/mocks/data.ts (1)
  • createFakeRoom (46-61)
apps/meteor/client/lib/queryKeys.ts (2)
packages/core-typings/src/IRoom.ts (1)
  • IRoom (21-95)
packages/core-typings/src/IUser.ts (1)
  • IUser (186-255)
apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.spec.tsx (2)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/lib/appLayout.tsx (1)
  • render (26-28)
apps/meteor/client/views/room/hooks/useRoomInvitation.tsx (4)
apps/meteor/client/startup/iframeCommands.ts (1)
  • user (80-89)
packages/ui-contexts/src/index.ts (2)
  • useUser (80-80)
  • useRouter (60-60)
apps/meteor/client/hooks/useEndpointMutation.ts (1)
  • useEndpointMutation (23-43)
apps/meteor/client/lib/queryKeys.ts (1)
  • roomsQueryKeys (13-28)
apps/meteor/client/views/room/RoomHeader.tsx (2)
packages/core-typings/src/IRoom.ts (1)
  • IRoom (21-95)
packages/core-typings/src/ISubscription.ts (1)
  • ISubscription (11-79)
apps/meteor/client/views/room/RoomInvite.tsx (3)
packages/core-typings/src/ISubscription.ts (1)
  • ISubscription (11-79)
apps/meteor/client/views/room/hooks/useRoomInvitation.tsx (1)
  • useRoomInvitation (8-36)
ee/packages/federation-matrix/src/api/_matrix/invite.ts (1)
  • acceptInvite (136-172)
apps/meteor/client/views/room/Header/RoomInviteHeader.stories.tsx (1)
apps/meteor/tests/mocks/data.ts (1)
  • createFakeRoom (46-61)
apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx (2)
packages/mock-providers/src/index.ts (1)
  • mockAppRoot (3-3)
apps/meteor/client/lib/appLayout.tsx (1)
  • render (26-28)
apps/meteor/client/views/room/Room.tsx (2)
apps/meteor/client/views/room/contexts/RoomToolboxContext.ts (1)
  • useRoomToolbox (47-47)
packages/core-typings/src/ISubscription.ts (1)
  • isInviteSubscription (89-93)
apps/meteor/client/views/room/Header/Header.tsx (1)
packages/core-typings/src/ISubscription.ts (2)
  • ISubscription (11-79)
  • isInviteSubscription (89-93)
apps/meteor/client/views/room/HeaderV2/Header.tsx (1)
packages/core-typings/src/ISubscription.ts (2)
  • ISubscription (11-79)
  • isInviteSubscription (89-93)
🔇 Additional comments (32)
apps/meteor/tests/mocks/utils/createDeferredMockFn.ts (1)

1-1: Exporting createDeferredPromise as a named utility looks good

Making createDeferredPromise a named export is a safe, non-breaking change that improves reusability in tests while preserving the existing default export for createDeferredMockFn.

.changeset/chatty-roses-help.md (1)

1-7: Changeset structure looks good.

The YAML frontmatter format is correct, and the three packages listed align with the PR scope: @rocket.chat/meteor for new components, @rocket.chat/core-typings for type additions, and @rocket.chat/i18n for translation keys. The patch-level version bump is appropriate for feature additions without breaking changes.

Please verify that all modified packages are captured in this changeset. The PR mentions server-side authorization validation for invite-based room access—confirm whether this involves packages beyond the three listed here (e.g., server-side hooks or authorization packages).

apps/meteor/client/views/room/Header/RoomHeader.tsx (2)

34-34: LGTM: Type change enables conditional toolbox rendering.

The addition of | null to the roomToolbox type enables explicit suppression of the toolbox, which aligns with the invite header flow where no toolbox should be displayed.


68-76: LGTM: Conditional rendering preserves backward compatibility.

The conditional (slots.toolbox || roomToolbox !== null) correctly handles three scenarios:

  • When roomToolbox is undefined (not passed): renders default toolbox for backward compatibility
  • When roomToolbox is explicitly null: suppresses toolbox rendering
  • When roomToolbox is a JSX element: renders the custom toolbox
apps/meteor/client/views/room/hooks/useRoomInvitation.spec.tsx (5)

1-26: LGTM: Clean test setup with proper isolation.

The test setup follows Jest best practices with proper mocking of dependencies and cleanup between tests.


27-33: LGTM: Proper async testing of acceptInvite.

The test correctly validates that acceptInvite triggers the endpoint mutation with the accept action.


35-41: LGTM: Proper testing of rejectInvite action.


43-57: LGTM: Excellent async state testing.

The use of createDeferredPromise enables precise control over the mutation lifecycle, allowing accurate validation of the isPending state transitions.


59-73: LGTM: Comprehensive navigation behavior coverage.

Both navigation scenarios (redirect on reject, no redirect on accept) are properly validated.

apps/meteor/client/views/room/hooks/useRoomInvitation.tsx (3)

1-12: LGTM: Clean hook setup.


13-29: LGTM: Well-structured mutation with proper query management.

The onSuccess handler correctly:

  • Falls back to room.name when federationOriginalName is unavailable
  • Refetches room reference queries for immediate updates
  • Invalidates room queries to trigger re-validation
  • Navigates to /home only when rejecting invitations

31-36: LGTM: Clean API design with convenient methods.

The hook exposes both the underlying mutation state and convenient acceptInvite/rejectInvite methods, providing a good developer experience.

apps/meteor/client/views/room/Header/RoomInviteHeader.tsx (1)

4-6: LGTM: Clean component implementation.

The component correctly wraps RoomHeader with roomToolbox={null} to suppress toolbox rendering for invite scenarios, while properly forwarding both room and slots props.

apps/meteor/server/services/authorization/canAccessRoom.ts (2)

4-4: LGTM: Import added for new validator.


87-96: Remove federation permission check suggestion; validate invite workflow security concerns.

The _validateAccessToInvitedRooms validator grants room access to users with pending invitations (subscription.status === 'INVITED'), allowing them to see room details before accepting or rejecting. This aligns with the stated PR goal of displaying invitations in the UI.

The TODO comment reflecting uncertainty about this approach is valid and should be resolved. However, verify these specific concerns:

  1. Invited users should have read-only access before accepting (to preview room details)
  2. Subscription status correctly transitions through the accept/reject/expiration workflow
  3. Timeout or expiration mechanisms exist for stale invitations
  4. No unintended access grants occur (e.g., to rejected or expired invitations)

The suggestion about federation permission checks in the original review is not applicable here. The canAccessRoom validator is a room access control check, not a federation action. Federation permissions (like 'access-federation') apply to user-initiated federation operations (creating federated rooms, adding users to federated rooms), which are handled separately in federation hooks.

apps/meteor/client/views/room/Header/RoomInviteHeader.spec.tsx (4)

1-10: LGTM: Good use of Storybook integration.

Using composeStories to generate test cases from Storybook stories ensures consistency between documentation and tests.


12-29: LGTM: Appropriate mocking strategy.

The mocks isolate the component under test from its dependencies, ensuring reliable test execution.


31-39: LGTM: Proper snapshot testing with isolation.

The snapshot tests provide regression detection for visual changes, with proper cleanup between tests.


41-46: LGTM: Excellent inclusion of accessibility testing.

Using jest-axe to validate accessibility for each story helps ensure an inclusive user experience.

apps/meteor/client/views/room/HeaderV2/RoomHeader.spec.tsx (1)

1-72: Comprehensive toolbox rendering coverage

The toolbox behavior matrix (default, null override, slot-provided, custom prop, and precedence) aligns well with the new conditional logic in RoomHeader. This should prevent regressions around hiding the toolbox for invite flows while still supporting overrides.

apps/meteor/client/views/room/RoomHeader.tsx (1)

1-25: Feature-flagged header wrapper looks correct

The RoomHeader wrapper cleanly delegates to HeaderV2 vs HeaderV1 based on newNavigation and passes room/subscription consistently. This should make it easy to roll out the new header/invite path safely.

packages/i18n/src/locales/en.i18n.json (2)

3024-3025: LGTM — invite and federation strings added correctly.

Naming matches existing patterns (Learn_more_about_*). No issues.


5410-5410: The standalone "unknown" key appears unused and the line reference is off by one.

The actual "unknown": "unknown" key is at line 5409 (not 5410). Verification shows this key has no direct usages in the codebase—no code calls t("unknown"). However, the casing concern is valid: related keys like "App_status_unknown": "Unknown" (line 518) use capitalized values. If this key is intentionally kept for future use or as a fallback, it should be "Unknown" to maintain consistency with similar status keys. No duplicate "Unknown" key exists. Consider clarifying the key's purpose or removing it if truly orphaned.

apps/meteor/client/views/room/Header/RoomHeader.spec.tsx (1)

1-73: LGTM! Comprehensive test coverage for toolbox rendering logic.

The test suite effectively covers the key scenarios for toolbox rendering: default behavior, hiding when null, slot-based rendering, custom content, and precedence rules. The mocking strategy appropriately isolates the RoomHeader component.

apps/meteor/client/views/room/HeaderV2/RoomInviteHeader.stories.tsx (1)

1-21: LGTM! Story setup is well-structured.

The Storybook configuration follows the established patterns with proper component wrapping, mock data, and type-safe meta definition.

apps/meteor/client/views/room/HeaderV2/Header.tsx (1)

1-47: LGTM! Clean implementation of invite subscription handling.

The conditional branch for invite subscriptions is correctly placed before other room-type checks, ensuring invite states are properly intercepted. The lazy loading pattern is consistent with existing headers.

apps/meteor/client/views/room/Header/Header.tsx (1)

1-66: LGTM! Consistent invite subscription handling with proper slots forwarding.

The implementation correctly adds invite subscription support while maintaining the existing slots pattern used by other headers in this folder. The conditional placement before room-type checks ensures proper invite interception.

apps/meteor/client/views/room/Header/RoomInviteHeader.stories.tsx (1)

1-21: LGTM! Consistent story structure with HeaderV2 variant.

The story configuration properly mirrors the HeaderV2 version, maintaining consistency across header component stories.

apps/meteor/client/views/room/Room.tsx (4)

1-23: LGTM!

The imports are well-organized and align with the new invite subscription handling functionality being introduced.


28-37: LGTM!

The roomLabel computation provides appropriate accessibility context for both direct messages and channels, with correct translation key interpolation.


39-45: LGTM!

The early return for invite subscriptions correctly prevents access to the full chat UI and maintains consistency with the main rendering path in terms of FocusScope wrapping and accessibility attributes. The type guard safely handles undefined/null subscriptions.


52-55: LGTM!

The RoomHeader now receives both room and subscription props, with the aria-label providing proper accessibility context. The subscription can be undefined for users viewing rooms they have access to but aren't subscribed to (e.g., public channels), so ensure RoomHeader handles this case appropriately.

@ricardogarim ricardogarim requested a review from a team as a code owner November 27, 2025 22:39
@ricardogarim ricardogarim force-pushed the feat/invites branch 6 times, most recently from a575a7a to 5a0d940 Compare November 28, 2025 03:10
@aleksandernsilva aleksandernsilva marked this pull request as draft November 28, 2025 16:47
@aleksandernsilva aleksandernsilva force-pushed the feat/room-invite-state branch 2 times, most recently from 9efc603 to 5a4af29 Compare December 2, 2025 19:01
@ggazzo ggazzo force-pushed the feat/invites branch 2 times, most recently from b2cc5c0 to 0d14b19 Compare December 3, 2025 18:49
@aleksandernsilva aleksandernsilva force-pushed the feat/room-invite-state branch 2 times, most recently from 3f2fbe8 to 7c4a439 Compare December 3, 2025 19:11
@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

📦 Docker Image Size Report

📈 Changes

Service Current Baseline Change Percent
sum of all images 1.2GiB 1.2GiB +12MiB
rocketchat 360MiB 349MiB +12MiB
omnichannel-transcript-service 132MiB 132MiB +416B
queue-worker-service 132MiB 132MiB -1019B
ddp-streamer-service 126MiB 126MiB +231B
account-service 113MiB 113MiB +75B
stream-hub-service 111MiB 111MiB -25B
presence-service 111MiB 111MiB -338B
authorization-service 111MiB 111MiB +961B

📊 Historical Trend

---
config:
  theme: "dark"
  xyChart:
    width: 900
    height: 400
---
xychart
  title "Image Size Evolution by Service (Last 30 Days + This PR)"
  x-axis ["11/15 22:28", "11/16 01:28", "11/17 23:50", "11/18 22:53", "11/19 23:02", "11/21 16:49", "11/24 17:34", "11/27 22:32", "11/28 19:05", "12/01 23:01", "12/02 21:57", "12/03 21:00", "12/04 18:17", "12/05 21:56", "12/08 20:15", "12/09 22:17", "12/10 02:17", "12/10 02:22 (PR)"]
  y-axis "Size (GB)" 0 --> 0.5
  line "account-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "authorization-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "ddp-streamer-service" [0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12]
  line "omnichannel-transcript-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
  line "presence-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "queue-worker-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
  line "rocketchat" [0.36, 0.36, 0.35, 0.35, 0.35, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.35]
  line "stream-hub-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
Loading

Statistics (last 17 days):

  • 📊 Average: 1.5GiB
  • ⬇️ Minimum: 1.2GiB
  • ⬆️ Maximum: 1.6GiB
  • 🎯 Current PR: 1.2GiB
ℹ️ About this report

This report compares Docker image sizes from this build against the develop baseline.

  • Tag: pr-37612
  • Baseline: develop
  • Timestamp: 2025-12-10 02:22:37 UTC
  • Historical data points: 17

Updated: Wed, 10 Dec 2025 02:22:37 GMT

@ggazzo ggazzo force-pushed the feat/room-invite-state branch from d25851f to c205233 Compare December 10, 2025 01:50
@ggazzo ggazzo force-pushed the feat/room-invite-state branch from c205233 to e4a3790 Compare December 10, 2025 02:06
@ggazzo ggazzo added the stat: QA assured Means it has been tested and approved by a company insider label Dec 10, 2025
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Dec 10, 2025
@ggazzo ggazzo marked this pull request as ready for review December 10, 2025 02:53
@ggazzo ggazzo merged commit 176d5ea into develop Dec 10, 2025
47 of 50 checks passed
@ggazzo ggazzo deleted the feat/room-invite-state branch December 10, 2025 02:53
@dougfabris dougfabris modified the milestones: 7.14.0, 8.0.0 Jan 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants