Skip to content

fix(api): convert room apis#39827

Merged
ggazzo merged 27 commits intochore/apisfrom
chore/apis-rooms
Mar 24, 2026
Merged

fix(api): convert room apis#39827
ggazzo merged 27 commits intochore/apisfrom
chore/apis-rooms

Conversation

@ggazzo
Copy link
Copy Markdown
Member

@ggazzo ggazzo commented Mar 24, 2026

…ge parameter

Proposed changes (including videos or screenshots)

Issue(s)

Steps to test or reproduce

Further comments

…ge parameter

Summary by CodeRabbit

Release Notes

  • New Features

    • Added optional parameters to several room and team-related API endpoints.
    • Enhanced message attachment schemas with additional fields.
  • Bug Fixes

    • Improved error handling and validation across API endpoints with standardized error responses.
    • Fixed conditional field inclusion in pin and quote attachments to prevent sending undefined values.
  • API Changes

    • Stricter validation on query parameters; some now require array format instead of single values.
    • Updated API request/response schemas for consistency and better type safety.
    • Modified error type identifiers in validation failures.

@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot bot commented Mar 24, 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 targeting the wrong base branch. It should target 8.4.0, but it targets 8.3.0

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 24, 2026

⚠️ No Changeset found

Latest commit: 9c2b7e1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 24, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ab80a977-1fc6-41e5-99ca-8c0111495d09

📥 Commits

Reviewing files that changed from the base of the PR and between 2336ba3 and 9c2b7e1.

📒 Files selected for processing (24)
  • apps/meteor/app/api/server/ApiClass.ts
  • apps/meteor/app/api/server/ajv.ts
  • apps/meteor/app/api/server/lib/rooms.ts
  • apps/meteor/app/api/server/v1/call-history.ts
  • apps/meteor/app/api/server/v1/chat.ts
  • apps/meteor/app/api/server/v1/im.ts
  • apps/meteor/app/api/server/v1/rooms.ts
  • apps/meteor/app/autotranslate/client/lib/autotranslate.ts
  • apps/meteor/app/message-pin/server/pinMessage.ts
  • apps/meteor/client/views/admin/rooms/RoomsTable.tsx
  • apps/meteor/client/views/room/contextualBar/Info/EditRoomInfo/EditRoomInfo.tsx
  • apps/meteor/lib/createQuoteAttachment.ts
  • apps/meteor/tests/end-to-end/api/chat.ts
  • apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts
  • apps/meteor/tests/end-to-end/api/rooms.ts
  • packages/core-typings/src/Ajv.ts
  • packages/core-typings/src/IMessage/MessageAttachment/MessageAttachmentDefault.ts
  • packages/core-typings/src/IMessage/MessageAttachment/MessageQuoteAttachment.ts
  • packages/core-typings/src/IRoom.ts
  • packages/model-typings/src/models/IRoomsModel.ts
  • packages/models/src/models/Rooms.ts
  • packages/rest-typings/src/v1/Ajv.ts
  • packages/rest-typings/src/v1/omnichannel.ts
  • packages/rest-typings/src/v1/rooms.ts

Walkthrough

This pull request refactors API route registrations across chat, DM/IM, and rooms endpoints from standalone addRoute to typed fluent .post()/.get() patterns with explicit AJV validators and response schemas. It also strengthens the type system by introducing IRoomAdmin, constraining room name parameters to exclude fname, tightening MessageAttachment schema validation, and updating test assertions to match new error formats.

Changes

Cohort / File(s) Summary
API Route Type Refinements
apps/meteor/app/api/server/ApiClass.ts
Added overload signatures for failure() and unauthorized() methods to enable explicit no-argument calls with tighter typing.
Chat Endpoints Migration
apps/meteor/app/api/server/v1/chat.ts
Large-scale migration of chat endpoints (delete, syncMessages, getMessage, etc.) from addRoute to fluent .post()/.get() with explicit body/query validators and per-status response schemas; internal handler logic unchanged.
DM/IM Endpoints Migration
apps/meteor/app/api/server/v1/im.ts
Introduced dm.messages.others, dm.list, dm.list.everyone endpoints via fluent chain with new paginated response schemas; removed standalone addRoute blocks.
Rooms Endpoints Migration
apps/meteor/app/api/server/v1/rooms.ts
Refactored multiple autocomplete and admin endpoints (createDiscussion, adminRooms, etc.) from addRoute with manual validation to fluent .post()/.get() with AJV validators and standardized 400/401 error handling.
Call History & AJV Config
apps/meteor/app/api/server/v1/call-history.ts, packages/rest-typings/src/v1/Ajv.ts
Restricted call-history state parameter to array-only form; changed query coercion from boolean true to 'array' for stricter parameter handling.
Schema Validation & Message Attachments
apps/meteor/app/api/server/ajv.ts, packages/core-typings/src/IMessage/MessageAttachment/MessageAttachmentDefault.ts
Mutated MessageAttachmentDefault schema to enforce additionalProperties: false; extended type with optional attachments and content fields.
Type System Extensions
packages/core-typings/src/IRoom.ts, packages/core-typings/src/Ajv.ts, packages/core-typings/src/IMessage/MessageAttachment/MessageQuoteAttachment.ts
Added IRoomAdmin type alias; updated Ajv schemas to include IRoomAdmin; relaxed MessageQuoteAttachment.author_link to optional and required message_link.
Room Model Signature Constraints
packages/model-typings/src/models/IRoomsModel.ts, packages/models/src/models/Rooms.ts
Removed IRoom['fname'] support from room name search methods (findRoomsByNameOrFnameStarting, findOneByNameOrFname, etc.); narrowed parameter types to IRoom['name'] only.
Autocomplete & Admin Validators
packages/rest-typings/src/v1/rooms.ts
Switched six autocomplete/admin validators from ajv.compile to ajvQuery.compile; relaxed RoomsAutocompleteAvailableForTeamsProps.name to optional; added AdminRoomType enum; extended RoomsSaveRoomSettingsProps with roomCustomFields, systemMessages, joinCode.
Omnichannel Query Validation
packages/rest-typings/src/v1/omnichannel.ts
Changed departmentId parameter validation from oneOf to anyOf to allow flexible schema matching.
Core Message Utilities
apps/meteor/lib/createQuoteAttachment.ts, apps/meteor/app/message-pin/server/pinMessage.ts
Conditionally include md field only when truthy; conditionally include content in pin message payload; tightened null checks with optional chaining.
Autotranslate TypeScript
apps/meteor/app/autotranslate/client/lib/autotranslate.ts
Removed TypeScript error suppression comment on recursive attachment assignment.
Room Search API Parameter
apps/meteor/app/api/server/lib/rooms.ts
Made name parameter optional in findRoomsAvailableForTeams.
Client UI Type Handling & Payloads
apps/meteor/client/views/admin/rooms/RoomsTable.tsx, apps/meteor/client/views/room/contextualBar/Info/EditRoomInfo/EditRoomInfo.tsx
Added explicit type cast for room types array; updated systemMessages inclusion logic to remove dependency on hideSysMes condition.
End-to-End Test Assertions
apps/meteor/tests/end-to-end/api/chat.ts, apps/meteor/tests/end-to-end/api/rooms.ts, apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts
Updated error type expectations from invalid-params to error-invalid-params; shifted from exact error message matching to substring assertions for schema validation messages; adjusted invalid parameter test payloads (agents, open, tags).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • RocketChat/Rocket.Chat#39825: Migrates rooms endpoints from API.v1.addRoute to typed fluent .post()/.get() patterns with explicit AJV response schemas and shared successResponseSchema, directly paralleling the refactoring pattern applied across chat and DM/IM endpoints in this PR.

Suggested labels

type: chore


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.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.52%. Comparing base (2336ba3) to head (9c2b7e1).
⚠️ Report is 2 commits behind head on chore/apis.

Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff               @@
##           chore/apis   #39827      +/-   ##
==============================================
- Coverage       70.58%   70.52%   -0.07%     
==============================================
  Files            3256     3256              
  Lines          115791   115791              
  Branches        21085    21060      -25     
==============================================
- Hits            81727    81657      -70     
- Misses          31994    32067      +73     
+ Partials         2070     2067       -3     
Flag Coverage Δ
e2e 60.39% <50.00%> (+<0.01%) ⬆️
e2e-api 48.07% <ø> (-1.02%) ⬇️
unit 71.05% <0.00%> (-0.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ggazzo ggazzo added this to the 8.4.0 milestone Mar 24, 2026
Migrates rooms.createDiscussion, adminRooms, autocomplete.adminRooms,
adminRooms.getRoom, autocomplete.channelAndPrivate,
autocomplete.channelAndPrivate.withPagination,
autocomplete.availableForTeams, saveRoomSettings to typed endpoints.

Also:
- Add IRoomAdmin type and Typia schema for admin room projections
- Fix RoomsAdminRoomsProps.types to use enum instead of string[]
- Fix RoomsSaveRoomSettingsProps.favorite inner fields to be required

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@ggazzo ggazzo force-pushed the chore/apis-rooms branch from 5b62bca to 13b16f2 Compare March 24, 2026 02:41
ggazzo and others added 3 commits March 24, 2026 00:37
With typed body/query validators, AJV rejects missing required params
before the handler, changing the error message format.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…tring arrays

When a query param like types=c arrives as a single string, AJV with
coerceTypes: 'array' automatically wraps it into ['c'], matching the
array schema without needing manual normalization in handlers.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
ggazzo and others added 7 commits March 24, 2026 09:30
…JV message

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…name optional

GET query validators need ajvQuery (coerceTypes) to handle string→number
coercion from URL query params. Also make name optional in
availableForTeams to match original handler behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…eForTeams

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
With coerceTypes: 'array' on ajvQuery, a single string value is
automatically coerced to an array, making this test case no longer
applicable.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
With coerceTypes: 'array' on ajvQuery, single values are automatically
coerced to arrays, making the oneOf between array and scalar unnecessary.
The oneOf was causing validation failures because both branches matched
after coercion.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
ggazzo and others added 6 commits March 24, 2026 11:06
…elds to RoomsSaveRoomSettingsProps

These fields are accepted by saveRoomSettings but were missing from the
REST type and schema, causing validation failures with
additionalProperties: false.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
… validation test

The ajvQuery instance uses coerceTypes: 'array', which coerces single-element
arrays to scalars, making the previous test input valid after coercion.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…msSaveRoomSettingsProps

string[] is not assignable to MessageTypesValues[] which caused a TS2345
error when passing params to saveRoomSettings.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…m validation test

String values are coerced to arrays by ajvQuery (coerceTypes: 'array'),
so 'invalid' becomes ['invalid'] which passes validation.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…rtmentId

With ajvQuery coerceTypes: 'array', a string value matches both the
string schema and can be coerced to match the array schema, causing
oneOf validation to fail with 'must match exactly one schema'.
anyOf allows multiple matches which handles coercion correctly.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@ggazzo ggazzo marked this pull request as ready for review March 24, 2026 23:04
@ggazzo ggazzo requested review from a team as code owners March 24, 2026 23:04
@ggazzo ggazzo merged commit 932aa61 into chore/apis Mar 24, 2026
43 of 45 checks passed
@ggazzo ggazzo deleted the chore/apis-rooms branch March 24, 2026 23:05
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.

4 issues found across 24 files

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:814">
P2: `if (!msgs)` is unreachable because `toArray()` always returns an array. This dead branch means the "No messages found" error path never runs.</violation>
</file>

<file name="apps/meteor/client/views/room/contextualBar/Info/EditRoomInfo/EditRoomInfo.tsx">

<violation number="1" location="apps/meteor/client/views/room/contextualBar/Info/EditRoomInfo/EditRoomInfo.tsx:174">
P1: Disabling “Hide System Messages” can stop working because `systemMessages` is now sent as `undefined` instead of an explicit clearing value.</violation>
</file>

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

<violation number="1" location="apps/meteor/app/api/server/v1/rooms.ts:755">
P1: `$ref: '#/components/schemas/IRoomAdmin'` references a schema that is never registered with this `ajv` instance via `addSchema()`. This will cause `ajv.compile()` to throw at module load time, or fail validation in test environments. Use an inline object schema instead (similar to the other endpoints in this file).</violation>

<violation number="2" location="apps/meteor/app/api/server/v1/rooms.ts:1220">
P2: Typo: `projections` should be `projection` (singular). MongoDB silently ignores the unrecognized option, so the full user document is fetched instead of just `_id`.</violation>
</file>

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

...((data.joinCode || 'joinCodeRequired' in data) && { joinCode: joinCodeRequired ? data.joinCode : '' }),
...((data.systemMessages || !hideSysMes) && {
systemMessages: hideSysMes && data.systemMessages,
systemMessages: data.systemMessages,
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 24, 2026

Choose a reason for hiding this comment

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

P1: Disabling “Hide System Messages” can stop working because systemMessages is now sent as undefined instead of an explicit clearing value.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/meteor/client/views/room/contextualBar/Info/EditRoomInfo/EditRoomInfo.tsx, line 174:

<comment>Disabling “Hide System Messages” can stop working because `systemMessages` is now sent as `undefined` instead of an explicit clearing value.</comment>

<file context>
@@ -171,7 +171,7 @@ const EditRoomInfo = ({ room, onClickClose, onClickBack }: EditRoomInfoProps) =>
 					...((data.joinCode || 'joinCodeRequired' in data) && { joinCode: joinCodeRequired ? data.joinCode : '' }),
 					...((data.systemMessages || !hideSysMes) && {
-						systemMessages: hideSysMes && data.systemMessages,
+						systemMessages: data.systemMessages,
 					}),
 					retentionEnabled,
</file context>
Suggested change
systemMessages: data.systemMessages,
systemMessages: hideSysMes ? data.systemMessages : false,
Fix with Cubic

response: {
200: ajv.compile<Pick<IRoom, RoomAdminFieldsType>>({
allOf: [
{ $ref: '#/components/schemas/IRoomAdmin' },
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 24, 2026

Choose a reason for hiding this comment

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

P1: $ref: '#/components/schemas/IRoomAdmin' references a schema that is never registered with this ajv instance via addSchema(). This will cause ajv.compile() to throw at module load time, or fail validation in test environments. Use an inline object schema instead (similar to the other endpoints in this file).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/meteor/app/api/server/v1/rooms.ts, line 755:

<comment>`$ref: '#/components/schemas/IRoomAdmin'` references a schema that is never registered with this `ajv` instance via `addSchema()`. This will cause `ajv.compile()` to throw at module load time, or fail validation in test environments. Use an inline object schema instead (similar to the other endpoints in this file).</comment>

<file context>
@@ -653,334 +671,466 @@ API.v1.get(
+		response: {
+			200: ajv.compile<Pick<IRoom, RoomAdminFieldsType>>({
+				allOf: [
+					{ $ref: '#/components/schemas/IRoomAdmin' },
+					{ type: 'object', properties: { success: { type: 'boolean', enum: [true] } }, required: ['success'] },
+				],
</file context>
Fix with Cubic

Comment on lines +814 to +816
if (!msgs) {
throw new Meteor.Error('error-no-messages', 'No messages found');
}
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 24, 2026

Choose a reason for hiding this comment

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

P2: if (!msgs) is unreachable because toArray() always returns an array. This dead branch means the "No messages found" error path never runs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/meteor/app/api/server/v1/im.ts, line 814:

<comment>`if (!msgs)` is unreachable because `toArray()` always returns an array. This dead branch means the "No messages found" error path never runs.</comment>

<file context>
@@ -743,6 +743,162 @@ const dmCreateResponseSchema = ajv.compile<{ room: IRoom & { rid: string } }>({
+
+		const [msgs, total] = await Promise.all([cursor.toArray(), totalCount]);
+
+		if (!msgs) {
+			throw new Meteor.Error('error-no-messages', 'No messages found');
+		}
</file context>
Suggested change
if (!msgs) {
throw new Meteor.Error('error-no-messages', 'No messages found');
}
if (msgs.length === 0) {
throw new Meteor.Error('error-no-messages', 'No messages found');
}
Fix with Cubic

}

const user = await Users.findOneById(this.userId, { projections: { _id: 1 } });
const user = await Users.findOneById(this.userId, { projections: { _id: 1 } });
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 24, 2026

Choose a reason for hiding this comment

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

P2: Typo: projections should be projection (singular). MongoDB silently ignores the unrecognized option, so the full user document is fetched instead of just _id.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/meteor/app/api/server/v1/rooms.ts, line 1220:

<comment>Typo: `projections` should be `projection` (singular). MongoDB silently ignores the unrecognized option, so the full user document is fetched instead of just `_id`.</comment>

<file context>
@@ -1049,31 +1199,37 @@ API.v1.post(
+		}
 
-			const user = await Users.findOneById(this.userId, { projections: { _id: 1 } });
+		const user = await Users.findOneById(this.userId, { projections: { _id: 1 } });
 
-			if (!user) {
</file context>
Suggested change
const user = await Users.findOneById(this.userId, { projections: { _id: 1 } });
const user = await Users.findOneById(this.userId, { projection: { _id: 1 } });
Fix with Cubic

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.

1 participant