Skip to content

chore: Add OpenAPI support for the Rocket.Chat dm/im APIs endpoints#39340

Closed
ahmed-n-abdeltwab wants to merge 9 commits intoRocketChat:developfrom
ahmed-n-abdeltwab:chore/openapi-dm
Closed

chore: Add OpenAPI support for the Rocket.Chat dm/im APIs endpoints#39340
ahmed-n-abdeltwab wants to merge 9 commits intoRocketChat:developfrom
ahmed-n-abdeltwab:chore/openapi-dm

Conversation

@ahmed-n-abdeltwab
Copy link
Copy Markdown
Contributor

@ahmed-n-abdeltwab ahmed-n-abdeltwab commented Mar 4, 2026

Description:
This PR integrates OpenAPI support into the Rocket.Chat API, migrate of Rocket.Chat API endpoints to the new OpenAPI pattern. The update includes improved API documentation, enhanced type safety, and response validation using AJV.

Key Changes:

  • Implemented the new pattern and added AJV-based JSON schema validation for API.
  • Uses the ExtractRoutesFromAPI utility from the TypeScript definitions to dynamically derive the routes from the endpoint specifications.
  • Enabled Swagger UI integration for this API.
  • Route Methods Chaining for the endpoints.
  • This does not introduce any breaking changes to the endpoint logic.

Issue Reference:
Relates to #34983, part of the ongoing OpenAPI integration effort.

Testing:

  • Verified that the API response schemas are correctly documented in Swagger UI.
  • All tests passed without any breaking changes

Endpoints:

  • dm.counters/im.counters
  • dm.history/im.history
  • dm.messages/im.messages
  • dm.messages.others/im.messages.others
  • dm.open/im.open
  • dm.setTopic/im.setTopic

Looking forward to your feedback! 🚀

Summary by CodeRabbit

  • New Features

    • OpenAPI support for DM/IM endpoints; DM creation returns the created room ID.
  • Improvements

    • Unified, modernized routing and validation for DM/IM endpoints.
    • Consistent response shapes and permission checks across DM/IM.
    • Pagination and improved filtering for lists (DMs, files, members, history, messages).

- migrating to a modern chained route definition syntax and utilizing shared AJV schemas for validation to enhance API documentation and ensure type safety through response validation.
@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot bot commented Mar 4, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 4, 2026

🦋 Changeset detected

Latest commit: b03afc9

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

This PR includes changesets to release 41 packages
Name Type
@rocket.chat/core-typings Minor
@rocket.chat/rest-typings Minor
@rocket.chat/meteor Minor
@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/fuselage-ui-kit Major
@rocket.chat/gazzodown Major
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/ui-avatar Major
@rocket.chat/ui-client Major
@rocket.chat/ui-contexts Major
@rocket.chat/ui-voip Major
@rocket.chat/web-ui-registration Major
@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/abac 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/models Patch
@rocket.chat/network-broker Patch
@rocket.chat/omni-core-ee Patch
@rocket.chat/mock-providers Patch
@rocket.chat/ui-video-conf Major
@rocket.chat/instance-status Patch
@rocket.chat/omni-core Patch
@rocket.chat/server-fetch 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
Copy Markdown
Contributor

coderabbitai bot commented Mar 4, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Refactors DM/IM server routes to unified API.v1.addRoute handlers with shared AJV validation and pagination; removes multiple request-type exports/validators from rest-typings; adjusts public endpoint typings and expands AJV schema union to include IRoom and IUser.

Changes

Cohort / File(s) Summary
Changeset & Manifest
\.changeset/wicked-bugs-itch.md, manifest
Adds changeset describing OpenAPI/route migration; manifest updated to reflect typing and API changes.
Server API Consolidation
apps/meteor/app/api/server/v1/im.ts
Replaced per-endpoint handlers with centralized API.v1.addRoute registrations for DM/IM endpoints, introduced shared prop types/validators (isXProps), PaginatedRequest/Result usage, and standardized response shapes and permission checks.
rest-typings — removed request schemas
packages/rest-typings/src/v1/dm/DmCreateProps.ts, packages/rest-typings/src/v1/dm/DmFileProps.ts, packages/rest-typings/src/v1/dm/DmHistoryProps.ts, packages/rest-typings/src/v1/dm/DmLeaveProps.ts, packages/rest-typings/src/v1/dm/DmMembersProps.ts, packages/rest-typings/src/v1/dm/DmMessagesProps.ts
Deleted multiple exported request-type definitions, AJV JSON schemas, and compiled runtime validators; public typings and validators for many DM endpoints removed.
rest-typings — index & endpoint surface changes
packages/rest-typings/src/index.ts, packages/rest-typings/src/v1/dm/index.ts, packages/rest-typings/src/v1/dm/dm.ts, packages/rest-typings/src/v1/dm/im.ts
Trimmed top-level re-exports; narrowed ImEndpoints and DmEndpoints to only expose create routes in some files; introduced a local DmCreateProps in im.ts; reduced imported types.
AJV schemas union update
packages/core-typings/src/Ajv.ts
Expanded typia.json.schemas first tuple union to include IRoom and IUser.
Barrel export removal
packages/rest-typings/src/index.ts
Removed re-export of DmHistoryProps from package barrel.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant API as API.v1.addRoute
  participant Auth as Auth/Permissions
  participant Validator as AJV Validator
  participant DB as Database

  Client->>API: HTTP GET/POST /v1/im.* or /v1/dm.*
  API->>Auth: verify auth & permissions
  Auth-->>API: allowed/denied
  API->>Validator: validate request (isDmXProps / PaginatedRequest)
  Validator-->>API: valid/errors
  alt valid & allowed
    API->>DB: query rooms/files/members/messages (paginated)
    DB-->>API: results
    API-->>Client: 200 {payload}
  else invalid or denied
    API-->>Client: 4xx error
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: adding OpenAPI support for dm/im API endpoints, which aligns with the comprehensive refactoring of DM/IM endpoints, schema validation, and type definitions throughout the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

CodeRabbit can generate a title for your PR based on the changes with custom instructions.

Set the reviews.auto_title_instructions setting to generate a title for your PR based on the changes in the PR with custom instructions.

- migrating to a modern chained route definition syntax and utilizing shared AJV schemas for validation to enhance API documentation and ensure type safety through response validation.
- migrating to a modern chained route definition syntax and utilizing shared AJV schemas for validation to enhance API documentation and ensure type safety through response validation.
Copy link
Copy Markdown
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: 5

🧹 Nitpick comments (1)
apps/meteor/app/api/server/v1/im.ts (1)

1384-1397: Response type excludes fields returned by implementation.

The DmEndpoints type for /v1/im.members and /v1/dm.members declares the response with Pick<IUser, '_id' | 'status' | 'name' | 'username' | 'utcOffset'>, but the implementation (lines 457-466) projects additional fields: statusText, federated, and freeSwitchExtension. Consider updating the type to reflect all returned fields for accurate documentation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/im.ts` around lines 1384 - 1397, The declared
response type for DmEndpoints '/v1/im.members' and '/v1/dm.members' is missing
fields actually returned by the implementation (statusText, federated,
freeSwitchExtension); update the response shape to include these fields in the
user pick (or replace the Pick with a properly typed interface) so the
PaginatedResult members array matches the projection used by the implementation
(referencing the DmEndpoints definition and the implementation that projects
statusText, federated, and freeSwitchExtension).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/meteor/app/api/server/v1/im.ts`:
- Around line 189-211: The AJV schema for DmListEveryoneProps
(isDmListEveryoneProps) does not mark "query" as required while the TypeScript
type DmListEveryoneProps declares query: string (required); update the AJV
schema used in isDmListEveryoneProps to include a "required" array containing
"query" (or alternatively change the TypeScript type to make query optional) so
the runtime validation matches the type definition; locate the
isDmListEveryoneProps AJV compile block and add required: ["query"] to the
schema to fix the mismatch.
- Around line 578-596: The JSON schema DmClosePropsSchema requires userId but
the DmCloseProps type and dmCloseAction use this.userId (authenticated user)
instead of reading userId from the request body; update the schema to match the
type and behavior by removing userId from DmClosePropsSchema (remove the userId
property and from required) so only roomId is required, leaving DmCloseProps and
isDmCloseProps unchanged; ensure dmCloseAction continues to read userId from
this.userId.
- Around line 665-676: The AJV schema is missing the required constraint for
roomId which causes dmCountersAction to throw later; update the
isDmCountersProps schema to include required: ['roomId'] so validation fails
with a 400 when roomId is absent, and verify the DmCountersProps type/signature
still matches the schema (adjust types if necessary).
- Around line 153-156: The route registration call to API.v1.addRoute for
['dm.list','im.list'] is missing the validateParams option; update the options
object passed to API.v1.addRoute (the same object that currently contains
authRequired: true) to include validateParams: isDmListProps so the
isDmListProps validator is applied to the dm.list/im.list route.
- Around line 1349-1398: The DmEndpoints type declares endpoints '/v1/im.kick',
'/v1/dm.kick', '/v1/im.leave', and '/v1/dm.leave' but there are no corresponding
route implementations in this file; either remove those four entries from the
DmEndpoints type or add matching route handlers (e.g., addRoute/.post
implementations) implementing the kick and leave logic so the declared
signatures (DmKickProps, DmLeaveProps) are satisfied; locate the DmEndpoints
type and the file's route registration area to either delete the four endpoint
entries or implement POST handlers named for those routes that validate params
and execute the existing DM kick/leave behavior.

---

Nitpick comments:
In `@apps/meteor/app/api/server/v1/im.ts`:
- Around line 1384-1397: The declared response type for DmEndpoints
'/v1/im.members' and '/v1/dm.members' is missing fields actually returned by the
implementation (statusText, federated, freeSwitchExtension); update the response
shape to include these fields in the user pick (or replace the Pick with a
properly typed interface) so the PaginatedResult members array matches the
projection used by the implementation (referencing the DmEndpoints definition
and the implementation that projects statusText, federated, and
freeSwitchExtension).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 019f9781-68a7-442c-9ae9-c9140b945562

📥 Commits

Reviewing files that changed from the base of the PR and between c68ac53 and 4b04790.

📒 Files selected for processing (13)
  • .changeset/wicked-bugs-itch.md
  • apps/meteor/app/api/server/v1/im.ts
  • packages/core-typings/src/Ajv.ts
  • packages/rest-typings/src/index.ts
  • packages/rest-typings/src/v1/dm/DmCreateProps.ts
  • packages/rest-typings/src/v1/dm/DmFileProps.ts
  • packages/rest-typings/src/v1/dm/DmHistoryProps.ts
  • packages/rest-typings/src/v1/dm/DmLeaveProps.ts
  • packages/rest-typings/src/v1/dm/DmMembersProps.ts
  • packages/rest-typings/src/v1/dm/DmMessagesProps.ts
  • packages/rest-typings/src/v1/dm/dm.ts
  • packages/rest-typings/src/v1/dm/im.ts
  • packages/rest-typings/src/v1/dm/index.ts
💤 Files with no reviewable changes (9)
  • packages/rest-typings/src/v1/dm/dm.ts
  • packages/rest-typings/src/index.ts
  • packages/rest-typings/src/v1/dm/DmHistoryProps.ts
  • packages/rest-typings/src/v1/dm/index.ts
  • packages/rest-typings/src/v1/dm/DmCreateProps.ts
  • packages/rest-typings/src/v1/dm/DmMembersProps.ts
  • packages/rest-typings/src/v1/dm/DmFileProps.ts
  • packages/rest-typings/src/v1/dm/DmMessagesProps.ts
  • packages/rest-typings/src/v1/dm/DmLeaveProps.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🧰 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:

  • packages/core-typings/src/Ajv.ts
  • packages/rest-typings/src/v1/dm/im.ts
  • apps/meteor/app/api/server/v1/im.ts
🧠 Learnings (14)
📓 Common learnings
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:09.561Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs for apps/meteor/app/api/server/v1 endpoints, maintainers prefer to avoid any logic changes; style-only cleanups (like removing inline comments) may be deferred to follow-ups to keep scope tight.
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:18.785Z
Learning: In Rocket.Chat PR reviews, maintain strict scope boundaries—when a PR is focused on a specific endpoint (e.g., rooms.favorite), avoid reviewing or suggesting changes to other endpoints that were incidentally refactored (e.g., rooms.invite) unless explicitly requested by maintainers.
📚 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:

  • packages/core-typings/src/Ajv.ts
📚 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:

  • packages/core-typings/src/Ajv.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • packages/core-typings/src/Ajv.ts
  • packages/rest-typings/src/v1/dm/im.ts
  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • packages/core-typings/src/Ajv.ts
  • packages/rest-typings/src/v1/dm/im.ts
  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-24T19:09:09.561Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:09.561Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs for apps/meteor/app/api/server/v1 endpoints, maintainers prefer to avoid any logic changes; style-only cleanups (like removing inline comments) may be deferred to follow-ups to keep scope tight.

Applied to files:

  • .changeset/wicked-bugs-itch.md
  • packages/rest-typings/src/v1/dm/im.ts
📚 Learning: 2026-02-24T19:05:56.710Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 0
File: :0-0
Timestamp: 2026-02-24T19:05:56.710Z
Learning: Rocket.Chat repo context: When a workspace manifest on develop already pins a dependency version (e.g., packages/web-ui-registration → "rocket.chat/ui-contexts": "27.0.1"), a lockfile change in a feature PR that upgrades only that dependency’s resolution is considered a manifest-driven sync and can be kept, preferably as a small "chore: sync yarn.lock with manifests" commit.

Applied to files:

  • .changeset/wicked-bugs-itch.md
📚 Learning: 2026-02-25T20:10:16.987Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38913
File: packages/ddp-client/src/legacy/types/SDKLegacy.ts:34-34
Timestamp: 2026-02-25T20:10:16.987Z
Learning: In the RocketChat/Rocket.Chat monorepo, packages/ddp-client and apps/meteor do not use TypeScript project references. Module augmentations in apps/meteor (e.g., declare module 'rocket.chat/rest-typings') are not visible when compiling packages/ddp-client in isolation, which is why legacy SDK methods that depend on OperationResult types for OpenAPI-migrated endpoints must remain commented out.

Applied to files:

  • .changeset/wicked-bugs-itch.md
  • packages/rest-typings/src/v1/dm/im.ts
  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-03T11:11:48.541Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39230
File: apps/meteor/app/api/server/v1/chat.ts:214-222
Timestamp: 2026-03-03T11:11:48.541Z
Learning: In apps/meteor/server/lib/moderation/reportMessage.ts, the reportMessage function validates that description is not empty or whitespace-only with `if (!description.trim())`. When migrating the chat.reportMessage endpoint to OpenAPI, adding minLength validation to the schema preserves this existing behavior.

Applied to files:

  • .changeset/wicked-bugs-itch.md
📚 Learning: 2026-02-24T19:05:56.710Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 0
File: :0-0
Timestamp: 2026-02-24T19:05:56.710Z
Learning: In Rocket.Chat PRs, keep feature PRs free of unrelated lockfile-only dependency bumps; prefer reverting lockfile drift or isolating such bumps into a separate "chore" commit/PR, and always use yarn install --immutable with the Yarn version pinned in package.json via Corepack.

Applied to files:

  • .changeset/wicked-bugs-itch.md
📚 Learning: 2025-09-16T13:33:49.237Z
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: In Rocket.Chat test files, the im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). It does not accept slug-like constructions such as concatenating usernames together.

Applied to files:

  • packages/rest-typings/src/v1/dm/im.ts
  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-24T19:09:01.522Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:01.522Z
Learning: In Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1, avoid introducing logic changes. Only perform scope-tight changes that preserve behavior; style-only cleanups (e.g., removing inline comments) may be deferred to follow-ups to keep the migration PR focused.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2025-09-16T13:33:49.237Z
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: The im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). Constructing slug-like identifiers like `user2${Users.userE2EE.data.username}` doesn't work for this endpoint.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-23T17:53:06.802Z
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:06.802Z
Learning: During PR reviews that touch endpoint files under apps/meteor/app/api/server/v1, enforce strict scope: if a PR targets a specific endpoint (e.g., rooms.favorite), do not propose changes to unrelated endpoints (e.g., rooms.invite) unless maintainers explicitly request them. Focus feedback on the touched endpoint's behavior, API surface, and related tests; avoid broad cross-endpoint changes in the same PR unless requested.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
🔇 Additional comments (9)
packages/core-typings/src/Ajv.ts (2)

10-12: Good type-only import additions for schema coverage.

Line 10 and Line 12 correctly add IRoom and IUser as type-only imports, keeping runtime output unchanged while enabling stronger schema typing.


18-18: Schema root union update is consistent with OpenAPI migration needs.

Line 18 appropriately extends the generated schema roots with IRoom | IUser, which improves downstream schema availability through the exported schemas entrypoint.

.changeset/wicked-bugs-itch.md (1)

1-7: LGTM!

The changeset correctly documents the minor version bumps for the affected packages. The description accurately reflects the OpenAPI migration scope with chained route definitions and AJV schema validation.

packages/rest-typings/src/v1/dm/im.ts (1)

1-19: LGTM!

The streamlined ImEndpoints interface correctly exposes only the /v1/im.create route with appropriate typing. The local DmCreateProps type definition aligns with the AJV schema in the meteor app implementation. The remaining DM/IM routes are appropriately declared via module augmentation in the meteor app, which is consistent with the OpenAPI migration pattern being established.

apps/meteor/app/api/server/v1/im.ts (5)

1-35: LGTM!

Imports are well-organized and all appear to be utilized throughout the file. The combination of core-typings, rest-typings validators, and ApiClass utilities provides proper type safety for the OpenAPI migration.


70-130: LGTM!

The DmCreateProps type and AJV schema are well-aligned, correctly handling both single username and comma-separated usernames variants. The route registration for both dm.create and im.create follows the established aliasing pattern.


243-294: LGTM!

The DmFileProps schema correctly uses oneOf to enforce the requirement of either roomId or username. The nullable properties accommodate query parameter behavior appropriately.


1321-1337: LGTM!

The chained route definitions follow a clean, consistent pattern. Each endpoint is properly registered with its corresponding props configuration and action handler, with both dm.* and im.* variants for aliasing.


1400-1403: LGTM!

The module augmentation correctly extends the @rocket.chat/rest-typings Endpoints interface with the combined DmEndpoints type, making these routes available to consumers of the rest-typings package while keeping the implementation details in the meteor app.

Comment on lines +189 to +211
type DmListEveryoneProps = PaginatedRequest<{ query: string; fields?: string }>;

const dmEndpoints = API.v1
.post('im.delete', dmDeleteEndpointsProps, dmDeleteAction('im.delete'))
.post('dm.delete', dmDeleteEndpointsProps, dmDeleteAction('dm.delete'))
.post('dm.close', dmCloseEndpointsProps, dmCloseAction('dm.close'))
.post('im.close', dmCloseEndpointsProps, dmCloseAction('im.close'));
const isDmListEveryoneProps = ajv.compile<DmListEveryoneProps>({
type: 'object',
properties: {
query: {
type: 'string',
},
fields: {
type: 'string',
},
offset: {
type: 'number',
},
count: {
type: 'number',
},
sort: {
type: 'string',
},
},
additionalProperties: false,
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Schema-type mismatch: query is required in type but optional in schema.

DmListEveryoneProps declares query: string (required), but the AJV schema on lines 191-211 doesn't include query in a required array. This allows requests without query to pass validation while the TypeScript type expects it to be present.

Proposed fix
 const isDmListEveryoneProps = ajv.compile<DmListEveryoneProps>({
 	type: 'object',
 	properties: {
 		query: {
 			type: 'string',
 		},
 		fields: {
 			type: 'string',
 		},
 		offset: {
 			type: 'number',
 		},
 		count: {
 			type: 'number',
 		},
 		sort: {
 			type: 'string',
 		},
 	},
+	required: ['query'],
 	additionalProperties: false,
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/im.ts` around lines 189 - 211, The AJV schema
for DmListEveryoneProps (isDmListEveryoneProps) does not mark "query" as
required while the TypeScript type DmListEveryoneProps declares query: string
(required); update the AJV schema used in isDmListEveryoneProps to include a
"required" array containing "query" (or alternatively change the TypeScript type
to make query optional) so the runtime validation matches the type definition;
locate the isDmListEveryoneProps AJV compile block and add required: ["query"]
to the schema to fix the mismatch.

Comment on lines +578 to +596
type DmCloseProps = {
roomId: string;
};

const DmClosePropsSchema = {
type: 'object',
properties: {
roomId: {
type: 'string',
},
userId: {
type: 'string',
},
},
);

API.v1.addRoute(
['dm.messages.others', 'im.messages.others'],
{ authRequired: true, permissionsRequired: ['view-room-administration'] },
{
async get() {
if (settings.get('API_Enable_Direct_Message_History_EndPoint') !== true) {
throw new Meteor.Error('error-endpoint-disabled', 'This endpoint is disabled', {
route: '/api/v1/im.messages.others',
});
}

const { roomId } = this.queryParams;
if (!roomId) {
throw new Meteor.Error('error-roomid-param-not-provided', 'The parameter "roomId" is required');
}
required: ['roomId', 'userId'],
additionalProperties: false,
};

const room = await Rooms.findOneById<Pick<IRoom, '_id' | 't'>>(roomId, { projection: { _id: 1, t: 1 } });
if (!room || room?.t !== 'd') {
throw new Meteor.Error('error-room-not-found', `No direct message room found by the id of: ${roomId}`);
}
const isDmCloseProps = ajv.compile<DmCloseProps>(DmClosePropsSchema);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Schema requires userId but type and action don't use it from body.

The DmClosePropsSchema requires both roomId and userId (line 592), but the DmCloseProps type only defines roomId, and the dmCloseAction reads userId from this.userId (the authenticated user), not from bodyParams. This mismatch will cause valid requests (containing only roomId) to fail AJV validation.

Proposed fix
 const DmClosePropsSchema = {
 	type: 'object',
 	properties: {
 		roomId: {
 			type: 'string',
 		},
-		userId: {
-			type: 'string',
-		},
 	},
-	required: ['roomId', 'userId'],
+	required: ['roomId'],
 	additionalProperties: false,
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
type DmCloseProps = {
roomId: string;
};
const DmClosePropsSchema = {
type: 'object',
properties: {
roomId: {
type: 'string',
},
userId: {
type: 'string',
},
},
);
API.v1.addRoute(
['dm.messages.others', 'im.messages.others'],
{ authRequired: true, permissionsRequired: ['view-room-administration'] },
{
async get() {
if (settings.get('API_Enable_Direct_Message_History_EndPoint') !== true) {
throw new Meteor.Error('error-endpoint-disabled', 'This endpoint is disabled', {
route: '/api/v1/im.messages.others',
});
}
const { roomId } = this.queryParams;
if (!roomId) {
throw new Meteor.Error('error-roomid-param-not-provided', 'The parameter "roomId" is required');
}
required: ['roomId', 'userId'],
additionalProperties: false,
};
const room = await Rooms.findOneById<Pick<IRoom, '_id' | 't'>>(roomId, { projection: { _id: 1, t: 1 } });
if (!room || room?.t !== 'd') {
throw new Meteor.Error('error-room-not-found', `No direct message room found by the id of: ${roomId}`);
}
const isDmCloseProps = ajv.compile<DmCloseProps>(DmClosePropsSchema);
type DmCloseProps = {
roomId: string;
};
const DmClosePropsSchema = {
type: 'object',
properties: {
roomId: {
type: 'string',
},
},
required: ['roomId'],
additionalProperties: false,
};
const isDmCloseProps = ajv.compile<DmCloseProps>(DmClosePropsSchema);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/im.ts` around lines 578 - 596, The JSON schema
DmClosePropsSchema requires userId but the DmCloseProps type and dmCloseAction
use this.userId (authenticated user) instead of reading userId from the request
body; update the schema to match the type and behavior by removing userId from
DmClosePropsSchema (remove the userId property and from required) so only roomId
is required, leaving DmCloseProps and isDmCloseProps unchanged; ensure
dmCloseAction continues to read userId from this.userId.

Comment on lines +665 to +676
const isDmCountersProps = ajv.compile<DmCountersProps>({
type: 'object',
properties: {
roomId: {
type: 'string',
},
userId: {
type: 'string',
},
},
additionalProperties: false,
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Schema missing required for roomId.

The isDmCountersProps schema doesn't specify required: ['roomId'], but the dmCountersAction (line 732-734) throws an error if roomId is not provided. Adding the required constraint ensures validation fails early with a proper 400 response rather than a generic error.

Proposed fix
 const isDmCountersProps = ajv.compile<DmCountersProps>({
 	type: 'object',
 	properties: {
 		roomId: {
 			type: 'string',
 		},
 		userId: {
 			type: 'string',
 		},
 	},
+	required: ['roomId'],
 	additionalProperties: false,
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isDmCountersProps = ajv.compile<DmCountersProps>({
type: 'object',
properties: {
roomId: {
type: 'string',
},
userId: {
type: 'string',
},
},
additionalProperties: false,
});
const isDmCountersProps = ajv.compile<DmCountersProps>({
type: 'object',
properties: {
roomId: {
type: 'string',
},
userId: {
type: 'string',
},
},
required: ['roomId'],
additionalProperties: false,
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/im.ts` around lines 665 - 676, The AJV schema
is missing the required constraint for roomId which causes dmCountersAction to
throw later; update the isDmCountersProps schema to include required: ['roomId']
so validation fails with a 400 when roomId is absent, and verify the
DmCountersProps type/signature still matches the schema (adjust types if
necessary).

Comment on lines +1349 to +1398
type DmEndpoints = ExtractRoutesFromAPI<typeof dmEndpoints> & {
'/v1/im.kick': {
POST: (params: DmKickProps) => void;
};
'/v1/dm.kick': {
POST: (params: DmKickProps) => void;
};
'/v1/im.leave': {
POST: (params: DmLeaveProps) => void;
};
'/v1/dm.leave': {
POST: (params: DmLeaveProps) => void;
};
'/v1/im.list': {
GET: (params: PaginatedRequest<{ fields?: string }>) => PaginatedResult<{ ims: IRoom[] }>;
};
'/v1/dm.list': {
GET: (params: PaginatedRequest<{ fields?: string }>) => PaginatedResult<{ ims: IRoom[] }>;
};
'/v1/im.list.everyone': {
GET: (params: PaginatedRequest<{ query: string; fields?: string }>) => PaginatedResult<{ ims: IRoom[] }>;
};
'/v1/dm.list.everyone': {
GET: (params: PaginatedRequest<{ query: string; fields?: string }>) => PaginatedResult<{ ims: IRoom[] }>;
};
'/v1/im.files': {
GET: (params: DmFileProps) => PaginatedResult<{
files: IUploadWithUser[];
}>;
};
'/v1/dm.files': {
GET: (params: DmFileProps) => PaginatedResult<{
files: IUploadWithUser[];
}>;
};
'/v1/im.members': {
GET: (params: DmMemberProps) => PaginatedResult<{
members: (Pick<IUser, '_id' | 'status' | 'name' | 'username' | 'utcOffset'> & {
subscription: Pick<ISubscription, '_id' | 'status' | 'ts' | 'roles'>;
})[];
}>;
};
'/v1/dm.members': {
GET: (params: DmMemberProps) => PaginatedResult<{
members: (Pick<IUser, '_id' | 'status' | 'name' | 'username' | 'utcOffset'> & {
subscription: Pick<ISubscription, '_id' | 'status' | 'ts' | 'roles'>;
})[];
}>;
};
};
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Mar 4, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for im.kick/dm.kick/im.leave/dm.leave endpoint implementations
rg -n "im\.kick|dm\.kick|im\.leave|dm\.leave" apps/meteor/app/api/server/

Repository: RocketChat/Rocket.Chat

Length of output: 303


🏁 Script executed:

#!/bin/bash
# Search for endpoint implementations across entire API server directory
rg -n "addRoute.*im\.kick|addRoute.*dm\.kick|addRoute.*im\.leave|addRoute.*dm\.leave" apps/meteor/app/api/

Repository: RocketChat/Rocket.Chat

Length of output: 48


🏁 Script executed:

#!/bin/bash
# Get the im.ts file structure and search for all route definitions
wc -l apps/meteor/app/api/server/v1/im.ts

Repository: RocketChat/Rocket.Chat

Length of output: 106


🏁 Script executed:

#!/bin/bash
# Read the entire file to understand route definitions
cat -n apps/meteor/app/api/server/v1/im.ts | head -200

Repository: RocketChat/Rocket.Chat

Length of output: 6932


🏁 Script executed:

#!/bin/bash
# Continue reading to find kick and leave endpoint definitions
sed -n '200,500p' apps/meteor/app/api/server/v1/im.ts | cat -n

Repository: RocketChat/Rocket.Chat

Length of output: 8319


🏁 Script executed:

#!/bin/bash
# Search for kick and leave endpoints more broadly
rg -n "kick|leave" apps/meteor/app/api/server/v1/im.ts | head -40

Repository: RocketChat/Rocket.Chat

Length of output: 159


🏁 Script executed:

#!/bin/bash
# Read the section showing the DmEndpoints type definition
sed -n '1320,1403p' apps/meteor/app/api/server/v1/im.ts | cat -n

Repository: RocketChat/Rocket.Chat

Length of output: 3794


🏁 Script executed:

#!/bin/bash
# Search entire apps/meteor for kick/leave endpoint implementations
rg -n "\.post\(.*kick|\.post\(.*leave" apps/meteor/app/api/ | head -20

Repository: RocketChat/Rocket.Chat

Length of output: 48


🏁 Script executed:

#!/bin/bash
# Search for any definition or implementation of kick/leave routes
rg -n "kick|leave" apps/meteor/app/api/server/ --type ts | grep -v "im.ts" | head -30

Repository: RocketChat/Rocket.Chat

Length of output: 1056


🏁 Script executed:

#!/bin/bash
# Search for any post or addRoute in im.ts to verify all endpoints
rg -n "\.post\(|API\.v1\.addRoute" apps/meteor/app/api/server/v1/im.ts

Repository: RocketChat/Rocket.Chat

Length of output: 787


🏁 Script executed:

#!/bin/bash
# Get full context of the addRoute calls to see which endpoints they register
for line in 110 153 213 296 424; do
  echo "=== Line $line ==="
  sed -n "${line},$((line+2))p" apps/meteor/app/api/server/v1/im.ts
done

Repository: RocketChat/Rocket.Chat

Length of output: 539


Remove kick and leave endpoints from DmEndpoints type or implement them.

The DmEndpoints type declares im.kick, dm.kick, im.leave, and dm.leave (lines 1350–1361), but these endpoints have no corresponding addRoute or .post() implementations in this file. Either implement these endpoints to match the type declaration, or remove them from the type if they are not intended to be exposed through this API.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/im.ts` around lines 1349 - 1398, The
DmEndpoints type declares endpoints '/v1/im.kick', '/v1/dm.kick',
'/v1/im.leave', and '/v1/dm.leave' but there are no corresponding route
implementations in this file; either remove those four entries from the
DmEndpoints type or add matching route handlers (e.g., addRoute/.post
implementations) implementing the kick and leave logic so the declared
signatures (DmKickProps, DmLeaveProps) are satisfied; locate the DmEndpoints
type and the file's route registration area to either delete the four endpoint
entries or implement POST handlers named for those routes that validate params
and execute the existing DM kick/leave behavior.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i add them temp becouse i have remove there files and in the next PR i will remove it dotn worry

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@ahmed-n-abdeltwab, understood! Thanks for the context — keeping those stubs temporarily to maintain type compatibility while the underlying files are removed makes sense. Just make sure to track the cleanup in the follow-up PR so the unimplemented endpoints don't linger in the type declaration. Would you like me to open a follow-up GitHub issue to track the removal?


✏️ Learnings added
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39340
File: apps/meteor/app/api/server/v1/im.ts:1349-1398
Timestamp: 2026-03-12T10:26:19.756Z
Learning: In `apps/meteor/app/api/server/v1/im.ts` (PR `#39340`), the `DmEndpoints` type intentionally includes temporary stub entries for `/v1/im.kick`, `/v1/dm.kick`, `/v1/im.leave`, and `/v1/dm.leave` (using `DmKickProps` and `DmLeaveProps`) even though no route handlers exist for them yet. These stubs were added to preserve type compatibility after removing the original `DmLeaveProps` and related files. They are planned for cleanup in a follow-up PR. Do not flag these as missing implementations when reviewing this file until the follow-up is merged.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: In Rocket.Chat test files, the im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). It does not accept slug-like constructions such as concatenating usernames together.

Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: The im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). Constructing slug-like identifiers like `user2${Users.userE2EE.data.username}` doesn't work for this endpoint.

Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39414
File: apps/meteor/app/api/server/v1/rooms.ts:1241-1297
Timestamp: 2026-03-10T08:13:52.153Z
Learning: In the RocketChat/Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1/rooms.ts, the pattern `ajv.compile<void>({...})` is intentionally used for the 200 response schema even when the endpoint returns `{ success: true }`. This is an established convention across all migrated endpoints (rooms.leave, rooms.favorite, rooms.delete, rooms.muteUser, rooms.unmuteUser). Do not flag this as a type mismatch during reviews of these migration PRs.

Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:01.522Z
Learning: In Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1, avoid introducing logic changes. Only perform scope-tight changes that preserve behavior; style-only cleanups (e.g., removing inline comments) may be deferred to follow-ups to keep the migration PR focused.

Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38913
File: packages/ddp-client/src/legacy/types/SDKLegacy.ts:34-34
Timestamp: 2026-02-25T20:10:16.987Z
Learning: In the RocketChat/Rocket.Chat monorepo, packages/ddp-client and apps/meteor do not use TypeScript project references. Module augmentations in apps/meteor (e.g., declare module 'rocket.chat/rest-typings') are not visible when compiling packages/ddp-client in isolation, which is why legacy SDK methods that depend on OperationResult types for OpenAPI-migrated endpoints must remain commented out.

Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:06.802Z
Learning: During PR reviews that touch endpoint files under apps/meteor/app/api/server/v1, enforce strict scope: if a PR targets a specific endpoint (e.g., rooms.favorite), do not propose changes to unrelated endpoints (e.g., rooms.invite) unless maintainers explicitly request them. Focus feedback on the touched endpoint's behavior, API surface, and related tests; avoid broad cross-endpoint changes in the same PR unless requested.

Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 13 files

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/meteor/app/api/server/v1/im.ts">

<violation number="1" location="apps/meteor/app/api/server/v1/im.ts:155">
P2: The new strict query schema (`additionalProperties: false`) for `dm.list/im.list` will reject requests with any query parameters beyond `fields`, `offset`, `count`, and `sort`. Previously, the endpoint only required authentication and silently ignored extra parameters. This creates a breaking change for clients sending deprecated or extra query parameters, which will now receive HTTP 400 errors instead of successful responses. The TODO comment at line 161 acknowledges this is a breaking query parameter change.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@ahmed-n-abdeltwab
Copy link
Copy Markdown
Contributor Author

@ggazzo 👍

Copy link
Copy Markdown
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: 1

♻️ Duplicate comments (3)
apps/meteor/app/api/server/v1/im.ts (3)

578-596: ⚠️ Potential issue | 🟠 Major

Do not require userId in the close body.

DmCloseProps only exposes roomId, and the action reads the caller from this.userId. Keeping userId required in DmClosePropsSchema turns valid room-only requests into 400s before the existing auth logic runs.

Schema fix
 const DmClosePropsSchema = {
 	type: 'object',
 	properties: {
 		roomId: {
 			type: 'string',
 		},
-		userId: {
-			type: 'string',
-		},
 	},
-	required: ['roomId', 'userId'],
+	required: ['roomId'],
 	additionalProperties: false,
 };

Based on learnings: In Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1, avoid introducing logic changes. Only perform scope-tight changes that preserve behavior; style-only cleanups may be deferred to follow-ups to keep the migration PR focused.

Also applies to: 621-627

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/im.ts` around lines 578 - 596,
DmClosePropsSchema currently requires userId which breaks calls that only send
roomId because this.userId is used for the caller; update DmClosePropsSchema by
removing 'userId' from the required array (or remove the userId property
entirely if unused) so only roomId is required, keeping DmCloseProps,
DmClosePropsSchema and isDmCloseProps intact and preserving existing auth
behavior that reads this.userId.

189-211: ⚠️ Potential issue | 🟡 Minor

Make query optional in the *.list.everyone TS contract.

isDmListEveryoneProps does not require query, but DmListEveryoneProps and the exported route type still do. That makes the generated contract stricter than the runtime validator for no functional gain.

Minimal fix
-type DmListEveryoneProps = PaginatedRequest<{ query: string; fields?: string }>;
+type DmListEveryoneProps = PaginatedRequest<{ query?: string; fields?: string }>;
...
 	'/v1/im.list.everyone': {
-		GET: (params: PaginatedRequest<{ query: string; fields?: string }>) => PaginatedResult<{ ims: IRoom[] }>;
+		GET: (params: PaginatedRequest<{ query?: string; fields?: string }>) => PaginatedResult<{ ims: IRoom[] }>;
 	};
 	'/v1/dm.list.everyone': {
-		GET: (params: PaginatedRequest<{ query: string; fields?: string }>) => PaginatedResult<{ ims: IRoom[] }>;
+		GET: (params: PaginatedRequest<{ query?: string; fields?: string }>) => PaginatedResult<{ ims: IRoom[] }>;
 	};

Based on learnings: In Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1, avoid introducing logic changes. Only perform scope-tight changes that preserve behavior; style-only cleanups may be deferred to follow-ups to keep the migration PR focused.

Also applies to: 1368-1373

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/im.ts` around lines 189 - 211, The TypeScript
contract DmListEveryoneProps currently marks query as required while the runtime
validator is optional; update DmListEveryoneProps (and any exported route type
using it, e.g., the *.list.everyone route type) to make query optional so the
compile-time type matches the ajv validator isDmListEveryoneProps; locate the
type declaration DmListEveryoneProps and change query: string to query?: string
(and update any exported route type aliases that reference DmListEveryoneProps)
to keep behavior unchanged.

660-676: ⚠️ Potential issue | 🟡 Minor

Require roomId in the counters schema.

DmCountersProps and the handler already treat roomId as mandatory. Without required: ['roomId'], AJV accepts invalid calls and the endpoint fails later with a Meteor error instead of the validation path.

Minimal fix
 const isDmCountersProps = ajv.compile<DmCountersProps>({
 	type: 'object',
 	properties: {
 		roomId: {
 			type: 'string',
 		},
 		userId: {
 			type: 'string',
 		},
 	},
+	required: ['roomId'],
 	additionalProperties: false,
 });

Also applies to: 731-734

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/im.ts` around lines 660 - 676, The AJV schema
is missing the required constraint for roomId so invalid requests pass
validation and later trigger Meteor errors; update the compiled schema used by
isDmCountersProps to include required: ['roomId'] (matching the DmCountersProps
type) so roomId is enforced at validation time, and apply the same fix to the
other identical AJV schema instance in this file (the second
isDmCountersProps-like schema around the later handler) to keep both handlers
consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/meteor/app/api/server/v1/im.ts`:
- Around line 132-151: The DmListProps schema removed the existing "query"
filter causing dm.list / im.list to lose behavior; restore the "query" property
in the AJV schema and ensure the route type still accepts it so the existing
handler (dm.list / im.list) can apply the filter as before—update the
ajv.compile call for DmListProps (and the exported route type) to include
properties.query: { type: 'object' } (or the exact shape previously used) and
keep additionalProperties:false so the handler using isDmListProps and the
dm.list/im.list route will receive and apply req.query as before.

---

Duplicate comments:
In `@apps/meteor/app/api/server/v1/im.ts`:
- Around line 578-596: DmClosePropsSchema currently requires userId which breaks
calls that only send roomId because this.userId is used for the caller; update
DmClosePropsSchema by removing 'userId' from the required array (or remove the
userId property entirely if unused) so only roomId is required, keeping
DmCloseProps, DmClosePropsSchema and isDmCloseProps intact and preserving
existing auth behavior that reads this.userId.
- Around line 189-211: The TypeScript contract DmListEveryoneProps currently
marks query as required while the runtime validator is optional; update
DmListEveryoneProps (and any exported route type using it, e.g., the
*.list.everyone route type) to make query optional so the compile-time type
matches the ajv validator isDmListEveryoneProps; locate the type declaration
DmListEveryoneProps and change query: string to query?: string (and update any
exported route type aliases that reference DmListEveryoneProps) to keep behavior
unchanged.
- Around line 660-676: The AJV schema is missing the required constraint for
roomId so invalid requests pass validation and later trigger Meteor errors;
update the compiled schema used by isDmCountersProps to include required:
['roomId'] (matching the DmCountersProps type) so roomId is enforced at
validation time, and apply the same fix to the other identical AJV schema
instance in this file (the second isDmCountersProps-like schema around the later
handler) to keep both handlers consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 249dab7c-9df5-475d-a30d-9c5b173fd68e

📥 Commits

Reviewing files that changed from the base of the PR and between 824e008 and 54203d1.

📒 Files selected for processing (1)
  • apps/meteor/app/api/server/v1/im.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🧰 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/app/api/server/v1/im.ts
🧠 Learnings (19)
📓 Common learnings
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:09.561Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs for apps/meteor/app/api/server/v1 endpoints, maintainers prefer to avoid any logic changes; style-only cleanups (like removing inline comments) may be deferred to follow-ups to keep scope tight.
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39340
File: apps/meteor/app/api/server/v1/im.ts:1349-1398
Timestamp: 2026-03-12T10:26:19.756Z
Learning: In `apps/meteor/app/api/server/v1/im.ts` (PR `#39340`), the `DmEndpoints` type intentionally includes temporary stub entries for `/v1/im.kick`, `/v1/dm.kick`, `/v1/im.leave`, and `/v1/dm.leave` (using `DmKickProps` and `DmLeaveProps`) even though no route handlers exist for them yet. These stubs were added to preserve type compatibility after removing the original `DmLeaveProps` and related files. They are planned for cleanup in a follow-up PR. Do not flag these as missing implementations when reviewing this file until the follow-up is merged.
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:18.785Z
Learning: In Rocket.Chat PR reviews, maintain strict scope boundaries—when a PR is focused on a specific endpoint (e.g., rooms.favorite), avoid reviewing or suggesting changes to other endpoints that were incidentally refactored (e.g., rooms.invite) unless explicitly requested by maintainers.
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39414
File: apps/meteor/app/api/server/v1/rooms.ts:1241-1297
Timestamp: 2026-03-10T08:13:52.153Z
Learning: In the RocketChat/Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1/rooms.ts, the pattern `ajv.compile<void>({...})` is intentionally used for the 200 response schema even when the endpoint returns `{ success: true }`. This is an established convention across all migrated endpoints (rooms.leave, rooms.favorite, rooms.delete, rooms.muteUser, rooms.unmuteUser). Do not flag this as a type mismatch during reviews of these migration PRs.
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: In Rocket.Chat test files, the im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). It does not accept slug-like constructions such as concatenating usernames together.
📚 Learning: 2026-03-12T10:26:19.756Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39340
File: apps/meteor/app/api/server/v1/im.ts:1349-1398
Timestamp: 2026-03-12T10:26:19.756Z
Learning: In `apps/meteor/app/api/server/v1/im.ts` (PR `#39340`), the `DmEndpoints` type intentionally includes temporary stub entries for `/v1/im.kick`, `/v1/dm.kick`, `/v1/im.leave`, and `/v1/dm.leave` (using `DmKickProps` and `DmLeaveProps`) even though no route handlers exist for them yet. These stubs were added to preserve type compatibility after removing the original `DmLeaveProps` and related files. They are planned for cleanup in a follow-up PR. Do not flag these as missing implementations when reviewing this file until the follow-up is merged.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-25T20:10:16.987Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38913
File: packages/ddp-client/src/legacy/types/SDKLegacy.ts:34-34
Timestamp: 2026-02-25T20:10:16.987Z
Learning: In the RocketChat/Rocket.Chat monorepo, packages/ddp-client and apps/meteor do not use TypeScript project references. Module augmentations in apps/meteor (e.g., declare module 'rocket.chat/rest-typings') are not visible when compiling packages/ddp-client in isolation, which is why legacy SDK methods that depend on OperationResult types for OpenAPI-migrated endpoints must remain commented out.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-24T19:09:01.522Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:01.522Z
Learning: In Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1, avoid introducing logic changes. Only perform scope-tight changes that preserve behavior; style-only cleanups (e.g., removing inline comments) may be deferred to follow-ups to keep the migration PR focused.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-03T11:11:48.541Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39230
File: apps/meteor/app/api/server/v1/chat.ts:214-222
Timestamp: 2026-03-03T11:11:48.541Z
Learning: In apps/meteor/server/lib/moderation/reportMessage.ts, the reportMessage function validates that description is not empty or whitespace-only with `if (!description.trim())`. When migrating the chat.reportMessage endpoint to OpenAPI, adding minLength validation to the schema preserves this existing behavior.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-10T08:13:52.153Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39414
File: apps/meteor/app/api/server/v1/rooms.ts:1241-1297
Timestamp: 2026-03-10T08:13:52.153Z
Learning: In the RocketChat/Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1/rooms.ts, the pattern `ajv.compile<void>({...})` is intentionally used for the 200 response schema even when the endpoint returns `{ success: true }`. This is an established convention across all migrated endpoints (rooms.leave, rooms.favorite, rooms.delete, rooms.muteUser, rooms.unmuteUser). Do not flag this as a type mismatch during reviews of these migration PRs.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-11T22:04:16.136Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 39545
File: apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts:59-61
Timestamp: 2026-03-11T22:04:16.136Z
Learning: In `apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts`, the `msg.u._id === uid` early-return in the `streamNewMessage` handler is intentional: the "New messages" indicator is designed to notify about messages from other users only. Self-sent messages — including those sent from a different session/device — are always skipped, by design. Do not flag this as a multi-session regression.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 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: UserBridge.doGetUserRoomIds in packages/apps-engine/src/server/bridges/UserBridge.ts has a bug where it implicitly returns undefined when the app lacks read permission (missing return statement in the else case of the permission check).

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-04T14:16:49.202Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39304
File: packages/ui-contexts/src/ActionManagerContext.ts:26-26
Timestamp: 2026-03-04T14:16:49.202Z
Learning: In `packages/ui-contexts/src/ActionManagerContext.ts` (TypeScript, RocketChat/Rocket.Chat), the `disposeView` method in `IActionManager` uses an intentionally explicit union `UiKit.ModalView['id'] | UiKit.BannerView['viewId'] | UiKit.ContextualBarView['id']` to document which view types are accepted, even though all constituents resolve to the same primitive. The inline `// eslint-disable-next-line typescript-eslint/no-duplicate-type-constituents` comment is intentional and should not be flagged or removed.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-11T16:46:50.707Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 39535
File: apps/meteor/app/apps/server/bridges/livechat.ts:249-249
Timestamp: 2026-03-11T16:46:50.707Z
Learning: In `apps/meteor/app/apps/server/bridges/livechat.ts`, `createVisitor()` intentionally does not propagate `externalIds` to `registerData`. This is by design: the method is deprecated (JSDoc: `deprecated Use createAndReturnVisitor instead. Note: This method does not support externalIds.`) to push callers toward `createAndReturnVisitor()`, which does support `externalIds`. Do not flag the missing `externalIds` field in `createVisitor()` as a bug.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 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/app/api/server/v1/im.ts
📚 Learning: 2025-09-16T13:33:49.237Z
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: The im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). Constructing slug-like identifiers like `user2${Users.userE2EE.data.username}` doesn't work for this endpoint.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2025-09-16T13:33:49.237Z
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: In Rocket.Chat test files, the im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). It does not accept slug-like constructions such as concatenating usernames together.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-11T18:17:47.912Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39425
File: apps/meteor/client/lib/chats/flows/processMessageUploads.ts:112-119
Timestamp: 2026-03-11T18:17:47.912Z
Learning: In `apps/meteor/client/lib/chats/flows/processMessageUploads.ts`, when sending multiple file uploads, each file is confirmed via its own `/rooms.mediaConfirm/${rid}/${fileId}` call and produces a separate message. Only the first file's confirm payload carries the composed message text (`msg`); all subsequent files receive `msg: ''`. This one-message-per-file behavior is intentional by design — do not flag it as a bug or suggest batching into a single message.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-09T18:39:21.178Z
Learnt from: Harxhit
Repo: RocketChat/Rocket.Chat PR: 39476
File: apps/meteor/server/methods/addAllUserToRoom.ts:0-0
Timestamp: 2026-03-09T18:39:21.178Z
Learning: In apps/meteor/server/methods/addAllUserToRoom.ts, the implementation uses a single cursor pass (Users.find(userFilter).batchSize(100)) that collects both the full user objects (collectedUsers: IUser[]) and their usernames (usernames: string[]) in one iteration. `beforeAddUserToRoom` is then called once with the full usernames batch (preserving batch-validation semantics), and the subsequent subscription/message processing loop iterates over the same stable `collectedUsers` array — no second DB query is made. This avoids any race condition between validation and processing while preserving the original batch-validation behavior.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-23T17:53:06.802Z
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:06.802Z
Learning: During PR reviews that touch endpoint files under apps/meteor/app/api/server/v1, enforce strict scope: if a PR targets a specific endpoint (e.g., rooms.favorite), do not propose changes to unrelated endpoints (e.g., rooms.invite) unless maintainers explicitly request them. Focus feedback on the touched endpoint's behavior, API surface, and related tests; avoid broad cross-endpoint changes in the same PR unless requested.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
🔇 Additional comments (1)
apps/meteor/app/api/server/v1/im.ts (1)

153-156: Please verify addRoute still reads this validator.

The other legacy API.v1.addRoute(...) registrations in this file still pass AJV validators as validateParams. If addRoute has not been updated to consume query, dm.list / im.list will skip validation here again.

#!/bin/bash
# Verify whether legacy addRoute consumes `query` or still expects `validateParams`.
rg -nC4 '\baddRoute\s*\(' apps/meteor/app/api/server/
printf '\n---\n'
rg -nC2 'validateParams:|query:\s*isDmListProps' apps/meteor/app/api/server/v1/im.ts

Comment on lines +132 to +151
type DmListProps = PaginatedRequest<{ fields?: string }>;

const isDmListProps = ajv.compile<DmListProps>({
type: 'object',
properties: {
roomId: {
fields: {
type: 'string',
},
userId: {
offset: {
type: 'number',
},
count: {
type: 'number',
},
sort: {
type: 'string',
},
},
required: ['roomId', 'userId'],
additionalProperties: false,
};

const isDmCloseProps = ajv.compile<DmCloseProps>(DmClosePropsSchema);

const dmCloseEndpointsProps = {
authRequired: true,
body: isDmCloseProps,
response: {
400: validateBadRequestErrorResponse,
401: validateUnauthorizedErrorResponse,
403: validateForbiddenErrorResponse,
200: ajv.compile<void>({
type: 'object',
properties: {
success: {
type: 'boolean',
enum: [true],
},
},
required: ['success'],
additionalProperties: false,
}),
},
};
});
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Mar 12, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Keep the query filter on dm.list / im.list.

The new DmListProps / exported route type drop query, and the handler no longer applies it. Line 161 already calls out that this is a breaking change, so it should not ride along with a behavior-preserving OpenAPI migration.

Based on learnings: In Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1, avoid introducing logic changes. Only perform scope-tight changes that preserve behavior; style-only cleanups may be deferred to follow-ups to keep the migration PR focused.

Also applies to: 157-174, 1362-1367

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/im.ts` around lines 132 - 151, The DmListProps
schema removed the existing "query" filter causing dm.list / im.list to lose
behavior; restore the "query" property in the AJV schema and ensure the route
type still accepts it so the existing handler (dm.list / im.list) can apply the
filter as before—update the ajv.compile call for DmListProps (and the exported
route type) to include properties.query: { type: 'object' } (or the exact shape
previously used) and keep additionalProperties:false so the handler using
isDmListProps and the dm.list/im.list route will receive and apply req.query as
before.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

are you sure about what are you taking about ? you are miss reading the isDmListProps with DmClosePropsSchema both are two defrent thing and i havent change anyof them

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@ahmed-n-abdeltwab, you're right that isDmListProps and DmClosePropsSchema are two completely separate schemas — I apologize for the confusing wording in my original comment.

To clarify, my concern is specifically about isDmListProps (the new schema for dm.list / im.list). The schema only includes fields, offset, count, and sort, with additionalProperties: false. This means a query parameter that the old endpoint previously accepted would now be rejected.

The TODO comment you added inside the handler itself is what caught my attention:

// TODO: CACHE: Add Breaking notice since we removed the query param

This self-acknowledgment confirms the query param was intentionally removed — but since the PR is described as a behavior-preserving OpenAPI migration, dropping an accepted parameter is a breaking change that (per the established convention in this codebase) should ideally be a separate, explicitly flagged PR rather than bundled here.

The substance of the concern stands, but I agree my original comment was poorly worded by mentioning DmClosePropsSchema in the same breath. I'll note this for future clarity.

🐰 hops back to re-examine the evidence carefully


🧠 Learnings used
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39340
File: apps/meteor/app/api/server/v1/im.ts:1349-1398
Timestamp: 2026-03-12T10:26:19.756Z
Learning: In `apps/meteor/app/api/server/v1/im.ts` (PR `#39340`), the `DmEndpoints` type intentionally includes temporary stub entries for `/v1/im.kick`, `/v1/dm.kick`, `/v1/im.leave`, and `/v1/dm.leave` (using `DmKickProps` and `DmLeaveProps`) even though no route handlers exist for them yet. These stubs were added to preserve type compatibility after removing the original `DmLeaveProps` and related files. They are planned for cleanup in a follow-up PR. Do not flag these as missing implementations when reviewing this file until the follow-up is merged.

Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: In Rocket.Chat test files, the im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). It does not accept slug-like constructions such as concatenating usernames together.

Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: The im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). Constructing slug-like identifiers like `user2${Users.userE2EE.data.username}` doesn't work for this endpoint.

Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39414
File: apps/meteor/app/api/server/v1/rooms.ts:1241-1297
Timestamp: 2026-03-10T08:13:52.153Z
Learning: In the RocketChat/Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1/rooms.ts, the pattern `ajv.compile<void>({...})` is intentionally used for the 200 response schema even when the endpoint returns `{ success: true }`. This is an established convention across all migrated endpoints (rooms.leave, rooms.favorite, rooms.delete, rooms.muteUser, rooms.unmuteUser). Do not flag this as a type mismatch during reviews of these migration PRs.

Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:01.522Z
Learning: In Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1, avoid introducing logic changes. Only perform scope-tight changes that preserve behavior; style-only cleanups (e.g., removing inline comments) may be deferred to follow-ups to keep the migration PR focused.

Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:06.802Z
Learning: During PR reviews that touch endpoint files under apps/meteor/app/api/server/v1, enforce strict scope: if a PR targets a specific endpoint (e.g., rooms.favorite), do not propose changes to unrelated endpoints (e.g., rooms.invite) unless maintainers explicitly request them. Focus feedback on the touched endpoint's behavior, API surface, and related tests; avoid broad cross-endpoint changes in the same PR unless requested.

Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/page-objects/fragments/home-content.ts:60-82
Timestamp: 2026-02-24T19:36:55.089Z
Learning: In RocketChat/Rocket.Chat e2e tests (apps/meteor/tests/e2e/page-objects/fragments/home-content.ts), thread message preview listitems do not have aria-roledescription="message", so lastThreadMessagePreview locator cannot be scoped to messageListItems (which filters for aria-roledescription="message"). It should remain scoped to page.getByRole('listitem') or mainMessageList.getByRole('listitem').

Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38913
File: packages/ddp-client/src/legacy/types/SDKLegacy.ts:34-34
Timestamp: 2026-02-25T20:10:16.987Z
Learning: In the RocketChat/Rocket.Chat monorepo, packages/ddp-client and apps/meteor do not use TypeScript project references. Module augmentations in apps/meteor (e.g., declare module 'rocket.chat/rest-typings') are not visible when compiling packages/ddp-client in isolation, which is why legacy SDK methods that depend on OperationResult types for OpenAPI-migrated endpoints must remain commented out.

Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Copy link
Copy Markdown
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: 1

♻️ Duplicate comments (2)
apps/meteor/app/api/server/v1/im.ts (2)

563-577: ⚠️ Potential issue | 🟠 Major

dm.close now requires a body field the action never reads.

DmCloseProps and dmCloseAction() only use roomId, but DmClosePropsSchema still requires userId. Valid callers sending just { roomId } will fail AJV validation before the handler can use the authenticated this.userId.

🩹 Proposed fix
 const DmClosePropsSchema = {
 	type: 'object',
 	properties: {
 		roomId: {
 			type: 'string',
 		},
-		userId: {
-			type: 'string',
-		},
 	},
-	required: ['roomId', 'userId'],
+	required: ['roomId'],
 	additionalProperties: false,
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/im.ts` around lines 563 - 577, The AJV schema
DmClosePropsSchema requires userId even though the handler and DmCloseProps only
use roomId, causing valid callers that rely on authenticated this.userId to fail
validation; update DmClosePropsSchema to remove the userId requirement (either
remove the userId property entirely or leave it optional) and change the
required array to only include "roomId" so isDmCloseProps and dmCloseAction
accept payloads like { roomId } while still disallowing additionalProperties if
desired.

132-166: ⚠️ Potential issue | 🟠 Major

Restore the query filter on dm.list / im.list.

The new request type, handler, and exported route contract all drop query, so clients that previously filtered the DM list will now get different behavior in a PR that is supposed to be an OpenAPI migration only. Please keep query in DmListProps, thread it through parseJsonQuery(), and include it in the Rooms.findPaginated(...) selector; the /v1/im.list and /v1/dm.list typings should match that restored contract too.

Based on learnings: In Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1, avoid introducing logic changes. Only perform scope-tight changes that preserve behavior; style-only cleanups (e.g., removing inline comments) may be deferred to follow-ups to keep the migration PR focused.

Also applies to: 1343-1348

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/im.ts` around lines 132 - 166, Restore the
removed "query" filter: update the DmListProps type to include query, make sure
parseJsonQuery() reads and returns the query (e.g., const { sort = { name: 1 },
fields, query } = await this.parseJsonQuery()), and pass that query into the
Rooms.findPaginated selector (merge it into the selector alongside { t: 'd',
_id: { $in: subscriptions } }). Also ensure the exported route contract/typings
for /v1/im.list and /v1/dm.list include the restored query property so the API
surface matches the previous behavior (references: DmListProps, parseJsonQuery,
Rooms.findPaginated).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/meteor/app/api/server/v1/im.ts`:
- Around line 132-136: Define the missing AJV validator isDmListProps for
DmListProps before the API.v1.addRoute call: create a constant isDmListProps =
ajv.compile<DmListProps>(...) that validates an object with optional string
"fields" and numeric "offset" and "count" and optional string "sort" and sets
additionalProperties: false; then use that constant as the query validator
referenced in API.v1.addRoute(['dm.list','im.list'], { authRequired: true,
query: isDmListProps }, ...).

---

Duplicate comments:
In `@apps/meteor/app/api/server/v1/im.ts`:
- Around line 563-577: The AJV schema DmClosePropsSchema requires userId even
though the handler and DmCloseProps only use roomId, causing valid callers that
rely on authenticated this.userId to fail validation; update DmClosePropsSchema
to remove the userId requirement (either remove the userId property entirely or
leave it optional) and change the required array to only include "roomId" so
isDmCloseProps and dmCloseAction accept payloads like { roomId } while still
disallowing additionalProperties if desired.
- Around line 132-166: Restore the removed "query" filter: update the
DmListProps type to include query, make sure parseJsonQuery() reads and returns
the query (e.g., const { sort = { name: 1 }, fields, query } = await
this.parseJsonQuery()), and pass that query into the Rooms.findPaginated
selector (merge it into the selector alongside { t: 'd', _id: { $in:
subscriptions } }). Also ensure the exported route contract/typings for
/v1/im.list and /v1/dm.list include the restored query property so the API
surface matches the previous behavior (references: DmListProps, parseJsonQuery,
Rooms.findPaginated).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8b1dbc35-7fae-4e41-82d1-53ede5221b19

📥 Commits

Reviewing files that changed from the base of the PR and between 54203d1 and 9abd127.

📒 Files selected for processing (1)
  • apps/meteor/app/api/server/v1/im.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🧰 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/app/api/server/v1/im.ts
🧠 Learnings (26)
📓 Common learnings
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:09.561Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs for apps/meteor/app/api/server/v1 endpoints, maintainers prefer to avoid any logic changes; style-only cleanups (like removing inline comments) may be deferred to follow-ups to keep scope tight.
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39340
File: apps/meteor/app/api/server/v1/im.ts:1349-1398
Timestamp: 2026-03-12T10:26:19.756Z
Learning: In `apps/meteor/app/api/server/v1/im.ts` (PR `#39340`), the `DmEndpoints` type intentionally includes temporary stub entries for `/v1/im.kick`, `/v1/dm.kick`, `/v1/im.leave`, and `/v1/dm.leave` (using `DmKickProps` and `DmLeaveProps`) even though no route handlers exist for them yet. These stubs were added to preserve type compatibility after removing the original `DmLeaveProps` and related files. They are planned for cleanup in a follow-up PR. Do not flag these as missing implementations when reviewing this file until the follow-up is merged.
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:18.785Z
Learning: In Rocket.Chat PR reviews, maintain strict scope boundaries—when a PR is focused on a specific endpoint (e.g., rooms.favorite), avoid reviewing or suggesting changes to other endpoints that were incidentally refactored (e.g., rooms.invite) unless explicitly requested by maintainers.
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39414
File: apps/meteor/app/api/server/v1/rooms.ts:1241-1297
Timestamp: 2026-03-10T08:13:52.153Z
Learning: In the RocketChat/Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1/rooms.ts, the pattern `ajv.compile<void>({...})` is intentionally used for the 200 response schema even when the endpoint returns `{ success: true }`. This is an established convention across all migrated endpoints (rooms.leave, rooms.favorite, rooms.delete, rooms.muteUser, rooms.unmuteUser). Do not flag this as a type mismatch during reviews of these migration PRs.
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: In Rocket.Chat test files, the im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). It does not accept slug-like constructions such as concatenating usernames together.
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: The im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). Constructing slug-like identifiers like `user2${Users.userE2EE.data.username}` doesn't work for this endpoint.
📚 Learning: 2026-03-12T10:26:19.756Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39340
File: apps/meteor/app/api/server/v1/im.ts:1349-1398
Timestamp: 2026-03-12T10:26:19.756Z
Learning: In `apps/meteor/app/api/server/v1/im.ts` (PR `#39340`), the `DmEndpoints` type intentionally includes temporary stub entries for `/v1/im.kick`, `/v1/dm.kick`, `/v1/im.leave`, and `/v1/dm.leave` (using `DmKickProps` and `DmLeaveProps`) even though no route handlers exist for them yet. These stubs were added to preserve type compatibility after removing the original `DmLeaveProps` and related files. They are planned for cleanup in a follow-up PR. Do not flag these as missing implementations when reviewing this file until the follow-up is merged.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-24T19:09:01.522Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:01.522Z
Learning: In Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1, avoid introducing logic changes. Only perform scope-tight changes that preserve behavior; style-only cleanups (e.g., removing inline comments) may be deferred to follow-ups to keep the migration PR focused.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-25T20:10:16.987Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38913
File: packages/ddp-client/src/legacy/types/SDKLegacy.ts:34-34
Timestamp: 2026-02-25T20:10:16.987Z
Learning: In the RocketChat/Rocket.Chat monorepo, packages/ddp-client and apps/meteor do not use TypeScript project references. Module augmentations in apps/meteor (e.g., declare module 'rocket.chat/rest-typings') are not visible when compiling packages/ddp-client in isolation, which is why legacy SDK methods that depend on OperationResult types for OpenAPI-migrated endpoints must remain commented out.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-03T11:11:48.541Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39230
File: apps/meteor/app/api/server/v1/chat.ts:214-222
Timestamp: 2026-03-03T11:11:48.541Z
Learning: In apps/meteor/server/lib/moderation/reportMessage.ts, the reportMessage function validates that description is not empty or whitespace-only with `if (!description.trim())`. When migrating the chat.reportMessage endpoint to OpenAPI, adding minLength validation to the schema preserves this existing behavior.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-10T08:13:52.153Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39414
File: apps/meteor/app/api/server/v1/rooms.ts:1241-1297
Timestamp: 2026-03-10T08:13:52.153Z
Learning: In the RocketChat/Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1/rooms.ts, the pattern `ajv.compile<void>({...})` is intentionally used for the 200 response schema even when the endpoint returns `{ success: true }`. This is an established convention across all migrated endpoints (rooms.leave, rooms.favorite, rooms.delete, rooms.muteUser, rooms.unmuteUser). Do not flag this as a type mismatch during reviews of these migration PRs.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-11T22:04:16.136Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 39545
File: apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts:59-61
Timestamp: 2026-03-11T22:04:16.136Z
Learning: In `apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts`, the `msg.u._id === uid` early-return in the `streamNewMessage` handler is intentional: the "New messages" indicator is designed to notify about messages from other users only. Self-sent messages — including those sent from a different session/device — are always skipped, by design. Do not flag this as a multi-session regression.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 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: UserBridge.doGetUserRoomIds in packages/apps-engine/src/server/bridges/UserBridge.ts has a bug where it implicitly returns undefined when the app lacks read permission (missing return statement in the else case of the permission check).

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-04T14:16:49.202Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39304
File: packages/ui-contexts/src/ActionManagerContext.ts:26-26
Timestamp: 2026-03-04T14:16:49.202Z
Learning: In `packages/ui-contexts/src/ActionManagerContext.ts` (TypeScript, RocketChat/Rocket.Chat), the `disposeView` method in `IActionManager` uses an intentionally explicit union `UiKit.ModalView['id'] | UiKit.BannerView['viewId'] | UiKit.ContextualBarView['id']` to document which view types are accepted, even though all constituents resolve to the same primitive. The inline `// eslint-disable-next-line typescript-eslint/no-duplicate-type-constituents` comment is intentional and should not be flagged or removed.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-11T16:46:50.707Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 39535
File: apps/meteor/app/apps/server/bridges/livechat.ts:249-249
Timestamp: 2026-03-11T16:46:50.707Z
Learning: In `apps/meteor/app/apps/server/bridges/livechat.ts`, `createVisitor()` intentionally does not propagate `externalIds` to `registerData`. This is by design: the method is deprecated (JSDoc: `deprecated Use createAndReturnVisitor instead. Note: This method does not support externalIds.`) to push callers toward `createAndReturnVisitor()`, which does support `externalIds`. Do not flag the missing `externalIds` field in `createVisitor()` as a bug.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 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/app/api/server/v1/im.ts
📚 Learning: 2025-09-16T13:33:49.237Z
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: The im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). Constructing slug-like identifiers like `user2${Users.userE2EE.data.username}` doesn't work for this endpoint.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-23T17:53:06.802Z
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:06.802Z
Learning: During PR reviews that touch endpoint files under apps/meteor/app/api/server/v1, enforce strict scope: if a PR targets a specific endpoint (e.g., rooms.favorite), do not propose changes to unrelated endpoints (e.g., rooms.invite) unless maintainers explicitly request them. Focus feedback on the touched endpoint's behavior, API surface, and related tests; avoid broad cross-endpoint changes in the same PR unless requested.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2025-11-10T19:06:20.146Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37408
File: apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.tsx:53-69
Timestamp: 2025-11-10T19:06:20.146Z
Learning: In the Rocket.Chat repository, do not provide suggestions or recommendations about code sections marked with TODO comments. The maintainers have already identified these as future work and external reviewers lack the full context about implementation plans and timing.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 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:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-24T19:05:56.710Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 0
File: :0-0
Timestamp: 2026-02-24T19:05:56.710Z
Learning: In Rocket.Chat PRs, keep feature PRs free of unrelated lockfile-only dependency bumps; prefer reverting lockfile drift or isolating such bumps into a separate "chore" commit/PR, and always use yarn install --immutable with the Yarn version pinned in package.json via Corepack.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-01-26T18:26:01.279Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 38227
File: apps/meteor/app/api/server/router.ts:44-49
Timestamp: 2026-01-26T18:26:01.279Z
Learning: In apps/meteor/app/api/server/router.ts, when retrieving bodyParams and queryParams from the Hono context via c.get(), do not add defensive defaults (e.g., ?? {}). The code should fail fast if these parameters are missing, as endpoint handlers expect them to be present and breaking here helps surface parsing problems rather than hiding them.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2025-09-19T15:15:04.642Z
Learnt from: rodrigok
Repo: RocketChat/Rocket.Chat PR: 36991
File: apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts:219-221
Timestamp: 2025-09-19T15:15:04.642Z
Learning: The Federation_Matrix_homeserver_domain setting in apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts is part of the old federation system and is being deprecated/removed, so configuration issues with this setting should not be flagged for improvement.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-24T19:36:55.089Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/page-objects/fragments/home-content.ts:60-82
Timestamp: 2026-02-24T19:36:55.089Z
Learning: In RocketChat/Rocket.Chat e2e tests (apps/meteor/tests/e2e/page-objects/fragments/home-content.ts), thread message preview listitems do not have aria-roledescription="message", so lastThreadMessagePreview locator cannot be scoped to messageListItems (which filters for aria-roledescription="message"). It should remain scoped to page.getByRole('listitem') or mainMessageList.getByRole('listitem').

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-11T18:15:43.905Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39425
File: apps/meteor/app/api/server/v1/rooms.ts:294-296
Timestamp: 2026-03-11T18:15:43.905Z
Learning: In Rocket.Chat's `rooms.mediaConfirm/:rid/:fileId` endpoint (apps/meteor/app/api/server/v1/rooms.ts), updating `file.name` from `bodyParams.fileName` without updating `file.path` is intentionally safe. The file path is keyed by `_id` (not by filename), so the stored path remains valid regardless of a rename. `file.name` only affects the display name in the message attachment; do not flag this as a path-divergence issue.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2025-09-16T13:33:49.237Z
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: In Rocket.Chat test files, the im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). It does not accept slug-like constructions such as concatenating usernames together.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-11T18:17:47.912Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39425
File: apps/meteor/client/lib/chats/flows/processMessageUploads.ts:112-119
Timestamp: 2026-03-11T18:17:47.912Z
Learning: In `apps/meteor/client/lib/chats/flows/processMessageUploads.ts`, when sending multiple file uploads, each file is confirmed via its own `/rooms.mediaConfirm/${rid}/${fileId}` call and produces a separate message. Only the first file's confirm payload carries the composed message text (`msg`); all subsequent files receive `msg: ''`. This one-message-per-file behavior is intentional by design — do not flag it as a bug or suggest batching into a single message.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-03-09T18:39:21.178Z
Learnt from: Harxhit
Repo: RocketChat/Rocket.Chat PR: 39476
File: apps/meteor/server/methods/addAllUserToRoom.ts:0-0
Timestamp: 2026-03-09T18:39:21.178Z
Learning: In apps/meteor/server/methods/addAllUserToRoom.ts, the implementation uses a single cursor pass (Users.find(userFilter).batchSize(100)) that collects both the full user objects (collectedUsers: IUser[]) and their usernames (usernames: string[]) in one iteration. `beforeAddUserToRoom` is then called once with the full usernames batch (preserving batch-validation semantics), and the subsequent subscription/message processing loop iterates over the same stable `collectedUsers` array — no second DB query is made. This avoids any race condition between validation and processing while preserving the original batch-validation behavior.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • apps/meteor/app/api/server/v1/im.ts

Comment on lines +132 to +136
type DmListProps = PaginatedRequest<{ fields?: string }>;

const dmDeleteAction = <Path extends string>(_path: Path): TypedAction<typeof dmDeleteEndpointsProps, Path> =>
async function action() {
const { room } = await findDirectMessageRoom(this.bodyParams, this.userId);
API.v1.addRoute(
['dm.list', 'im.list'],
{ authRequired: true, query: isDmListProps },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -nP '\bisDmListProps\b' apps/meteor/app/api/server/v1/im.ts
rg -nP '^\s*(import .*isDmListProps|const\s+isDmListProps\b|function\s+isDmListProps\b)' apps/meteor/app/api/server/v1/im.ts

Repository: RocketChat/Rocket.Chat

Length of output: 116


🏁 Script executed:

head -50 apps/meteor/app/api/server/v1/im.ts

Repository: RocketChat/Rocket.Chat

Length of output: 2558


🏁 Script executed:

rg -n 'DmListProps|isDmListProps' apps/meteor/app/api/server/v1/ --type ts

Repository: RocketChat/Rocket.Chat

Length of output: 250


🏁 Script executed:

rg -rn 'isDmListProps' apps/meteor/app/api/server/ --type ts

Repository: RocketChat/Rocket.Chat

Length of output: 136


🏁 Script executed:

rg -n 'const is.*Props\s*=' apps/meteor/app/api/server/v1/im.ts | head -20

Repository: RocketChat/Rocket.Chat

Length of output: 802


🏁 Script executed:

sed -n '120,200p' apps/meteor/app/api/server/v1/im.ts

Repository: RocketChat/Rocket.Chat

Length of output: 2135


Missing validator definition for isDmListProps.

Line 136 references isDmListProps as a query validator, but this constant is not defined anywhere in the file. Following the established pattern in this file (all other validators are defined via ajv.compile<*Props>(...)), you must add the missing validator definition for isDmListProps before the route handler, e.g.:

const isDmListProps = ajv.compile<DmListProps>({
	type: 'object',
	properties: {
		fields: { type: 'string' },
		offset: { type: 'number' },
		count: { type: 'number' },
		sort: { type: 'string' },
	},
	additionalProperties: false,
});

Without this, the file will fail TypeScript compilation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/im.ts` around lines 132 - 136, Define the
missing AJV validator isDmListProps for DmListProps before the API.v1.addRoute
call: create a constant isDmListProps = ajv.compile<DmListProps>(...) that
validates an object with optional string "fields" and numeric "offset" and
"count" and optional string "sort" and sets additionalProperties: false; then
use that constant as the query validator referenced in
API.v1.addRoute(['dm.list','im.list'], { authRequired: true, query:
isDmListProps }, ...).

@ahmed-n-abdeltwab ahmed-n-abdeltwab marked this pull request as draft March 16, 2026 19:14
@ggazzo
Copy link
Copy Markdown
Member

ggazzo commented Mar 23, 2026

Hey, thanks for the contribution! 🙏

I'm closing this PR because the endpoint(s) covered here have already been migrated as part of a larger batch migration I'm working on (see #39820). I decided to go with a mass migration approach because reviewing individual PRs for each endpoint was taking too much of my time.

That said, you're more than welcome to help by reviewing and testing the changes in #39820 to make sure everything is working correctly. Your input would be really valuable!

Thanks again for your effort! 🚀

@ggazzo ggazzo closed this Mar 23, 2026
@ahmed-n-abdeltwab
Copy link
Copy Markdown
Contributor Author

no problem at all, peace ✌️

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants