Skip to content

refactor(groups): migrate groups.members to typed REST endpoint#39865

Draft
Harxhit wants to merge 3 commits intoRocketChat:developfrom
Harxhit:groups.members
Draft

refactor(groups): migrate groups.members to typed REST endpoint#39865
Harxhit wants to merge 3 commits intoRocketChat:developfrom
Harxhit:groups.members

Conversation

@Harxhit
Copy link
Copy Markdown

@Harxhit Harxhit commented Mar 25, 2026

Proposed changes

Refactors the groups.members endpoint to use the typed REST API endpoint system used by other API routes.

The endpoint now includes:

  • Typed request validation using AJV
  • Typed response validation using AJV
  • TypeScript schema definitions for request and response
  • Support for both flat query params and query-based input (for Swagger/OpenAPI compatibility)
  • Added support for filter, status, and sort parameters
  • Consistent error handling aligned with other endpoints
  • OpenAPI-compatible schema support

Issue(s)

N/A


Further comments

This migration aligns the groups.members endpoint with the typed REST API route pattern used across the codebase.

Additionally, support for query and sort parameters was introduced in the request/response schema to ensure compatibility with Swagger/OpenAPI behavior.

Without this, requests sent via Swagger (which wrap parameters inside a query object) were failing validation due to schema mismatch with AJV.

No functional changes were introduced to the business logic. Only structure, validation, and compatibility improvements were made.


Proofs

API test proof

APiTestProof

Swagger UI Proof

Schema

schema

200

200

400

400

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced error responses when the groups.members endpoint is accessed without proper broadcast-member visibility permissions.
  • Refactor

    • Strengthened request and response validation for the groups.members endpoint through improved schema enforcement and validation mechanisms.

@Harxhit Harxhit requested review from a team as code owners March 25, 2026 17:54
@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot bot commented Mar 25, 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 25, 2026

🦋 Changeset detected

Latest commit: fbeffa5

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/rest-typings Minor
@rocket.chat/meteor Minor
@rocket.chat/api-client Patch
@rocket.chat/core-services Patch
@rocket.chat/ddp-client Patch
@rocket.chat/http-router Patch
@rocket.chat/models Patch
@rocket.chat/ui-contexts Major
@rocket.chat/web-ui-registration Major
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/federation-matrix Patch
@rocket.chat/omnichannel-services Patch
@rocket.chat/presence Patch
rocketchat-services Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/abac Patch
@rocket.chat/network-broker Patch
@rocket.chat/omni-core-ee Patch
@rocket.chat/livechat Patch
@rocket.chat/mock-providers Patch
@rocket.chat/cron Patch
@rocket.chat/instance-status Patch
@rocket.chat/omni-core Patch
@rocket.chat/server-fetch Patch
@rocket.chat/ui-client Major
@rocket.chat/media-calls Patch
@rocket.chat/uikit-playground Patch
@rocket.chat/fuselage-ui-kit Major
@rocket.chat/gazzodown Major
@rocket.chat/ui-avatar Major
@rocket.chat/ui-video-conf Major
@rocket.chat/ui-voip Major
@rocket.chat/core-typings Minor
@rocket.chat/apps Patch
@rocket.chat/model-typings Patch
@rocket.chat/license Patch
@rocket.chat/pdf-worker 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

@Harxhit Harxhit marked this pull request as draft March 25, 2026 17:54
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 25, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9e40c456-9ee0-4530-ad81-3fb5be2eff01

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR refactors the groups.members endpoint to add JSON schema validation for both request and response payloads using AJV. The endpoint implementation is restructured with explicit validation helpers and error handling, while type definitions are reorganized accordingly.

Changes

Cohort / File(s) Summary
Version Bump
.changeset/flat-stingrays-complain.md
Changeset documenting a minor version bump for @rocket.chat/rest-typings and @rocket.chat/meteor packages due to groups.members endpoint validation changes.
Endpoint Implementation
apps/meteor/app/api/server/v1/groups.ts
Refactored groups.members endpoint from inline definition to structured groupsEndPoints constant with explicit AJV-based request and response validation. Added typed exports via GroupsHistoryEndpoints and module augmentation to extend Endpoints interface.
Type Definitions & Exports
packages/rest-typings/src/v1/groups/GroupsMembersProps.ts, packages/rest-typings/src/v1/groups/groups.ts, packages/rest-typings/src/v1/groups/index.ts
Deleted GroupsMembersProps.ts file and removed its corresponding endpoint definition from GroupsEndpoints type. Updated barrel exports in index.ts to remove GroupsMembersProps and add BaseProps.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

type: chore

🚥 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 title accurately reflects the main change: migrating the groups.members endpoint to a typed REST endpoint system with proper validation.
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.


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.

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 5 files

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: 2

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

1371-1375: Rename the extracted route alias to match groups.members.

GroupsHistoryEndpoints looks like a leftover copy/paste. Keeping that name here makes the module augmentation harder to follow and creates an avoidable collision point when groups.history is migrated.

♻️ Suggested rename
-export type GroupsHistoryEndpoints = ExtractRoutesFromAPI<typeof groupsEndPoints>;
+export type GroupsMembersEndpoints = ExtractRoutesFromAPI<typeof groupsEndPoints>;

 declare module '@rocket.chat/rest-typings' {
 	// eslint-disable-next-line `@typescript-eslint/naming-convention`, `@typescript-eslint/no-empty-interface`
-	interface Endpoints extends GroupsHistoryEndpoints {}
+	interface Endpoints extends GroupsMembersEndpoints {}
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/groups.ts` around lines 1371 - 1375, The
exported type alias GroupsHistoryEndpoints should be renamed to
GroupsMembersEndpoints to reflect the actual routes extracted from
groupsEndPoints; update the declaration export type GroupsHistoryEndpoints =
ExtractRoutesFromAPI<typeof groupsEndPoints> to export type
GroupsMembersEndpoints = ExtractRoutesFromAPI<typeof groupsEndPoints> and change
the module augmentation to extend that new type (interface Endpoints extends
GroupsMembersEndpoints {}) so the alias matches the `groups.members` intent and
avoids collision with groups.history.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.changeset/flat-stingrays-complain.md:
- Line 6: Update the changeset "flat-stingrays-complain" to fix the typo
`groups.memebers` → `groups.members` and rewrite the copy to explicitly state
the migration is non-breaking and should be recorded as a minor change; mention
that AJV validation and OpenAPI/request schema changes only adjust
validators/types in rocket.chat/rest-typings (removal of endpoint
types/validators) and do not break existing clients, and use the suggested
wording pattern for non-breaking OpenAPI migrations.

In `@apps/meteor/app/api/server/v1/groups.ts`:
- Around line 80-94: Update the isGroupsMembersResponse AJV schema so the 200
response is fully typed and enforces all pagination fields: ensure the schema
for members remains an array of items with $ref '#/components/schemas/IUser',
keep success as boolean enum [true], and add "count", "offset", and "total" to
the schema's required array (i.e., required:
['members','count','offset','total','success']) so runtime validation and the
exported endpoint types reflect the actual handler contract; make no other
structural changes to the object shape or additionalProperties setting.

---

Nitpick comments:
In `@apps/meteor/app/api/server/v1/groups.ts`:
- Around line 1371-1375: The exported type alias GroupsHistoryEndpoints should
be renamed to GroupsMembersEndpoints to reflect the actual routes extracted from
groupsEndPoints; update the declaration export type GroupsHistoryEndpoints =
ExtractRoutesFromAPI<typeof groupsEndPoints> to export type
GroupsMembersEndpoints = ExtractRoutesFromAPI<typeof groupsEndPoints> and change
the module augmentation to extend that new type (interface Endpoints extends
GroupsMembersEndpoints {}) so the alias matches the `groups.members` intent and
avoids collision with groups.history.
🪄 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: 04d2b330-73e9-43ad-8856-e1b3047caec3

📥 Commits

Reviewing files that changed from the base of the PR and between 147fa09 and 5b34d5c.

📒 Files selected for processing (5)
  • .changeset/flat-stingrays-complain.md
  • apps/meteor/app/api/server/v1/groups.ts
  • packages/rest-typings/src/v1/groups/GroupsMembersProps.ts
  • packages/rest-typings/src/v1/groups/groups.ts
  • packages/rest-typings/src/v1/groups/index.ts
💤 Files with no reviewable changes (2)
  • packages/rest-typings/src/v1/groups/groups.ts
  • packages/rest-typings/src/v1/groups/GroupsMembersProps.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/groups.ts
  • packages/rest-typings/src/v1/groups/index.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: smirk-dev
Repo: RocketChat/Rocket.Chat PR: 39625
File: apps/meteor/app/api/server/v1/push.ts:85-97
Timestamp: 2026-03-14T14:58:58.834Z
Learning: In RocketChat/Rocket.Chat, the `push.token` POST/DELETE endpoints in `apps/meteor/app/api/server/v1/push.ts` were already migrated to the chained router API pattern on `develop` prior to PR `#39625`. `cleanTokenResult` (which strips `authToken` and returns `PushTokenResult`) and `isPushTokenPOSTProps`/`isPushTokenDELETEProps` validators already exist on `develop`. PR `#39625` only migrates `push.get` and `push.info` to the chained pattern. Do not flag `cleanTokenResult` or `PushTokenResult` as newly introduced behavior-breaking changes when reviewing this PR.
Learnt from: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39647
File: apps/meteor/app/api/server/v1/users.ts:710-757
Timestamp: 2026-03-15T14:31:28.969Z
Learning: In RocketChat/Rocket.Chat, the `UserCreateParamsPOST` type in `apps/meteor/app/api/server/v1/users.ts` (migrated from `packages/rest-typings/src/v1/users/UserCreateParamsPOST.ts`) intentionally has `fields: string` (non-optional) and `settings?: IUserSettings` without a corresponding AJV schema entry. This is a pre-existing divergence carried over verbatim from the original rest-typings source (PR `#39647`). Do not flag this type/schema misalignment during the OpenAPI migration review — it is tracked as a separate follow-up fix.
Learnt from: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39676
File: .changeset/migrate-users-register-openapi.md:3-3
Timestamp: 2026-03-16T21:50:42.118Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs, removing endpoint types and validators from `rocket.chat/rest-typings` (e.g., `UserRegisterParamsPOST`, `/v1/users.register` entry) is the *required* migration pattern per RocketChat/Rocket.Chat-Open-API#150 Rule 7 ("No More rest-typings or Manual Typings"). The endpoint type is re-exposed via a module augmentation `.d.ts` file in the consuming package (e.g., `packages/web-ui-registration/src/users-register.d.ts`). This is NOT a breaking change — the correct changeset bump for `rocket.chat/rest-typings` in this scenario is `minor`, not `major`. Do not flag this as a breaking change during OpenAPI migration reviews.
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: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39676
File: apps/meteor/app/api/server/v1/users.ts:862-869
Timestamp: 2026-03-16T23:33:15.721Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs (e.g., PR `#39676` for users.register in apps/meteor/app/api/server/v1/users.ts), calls to `this.parseJsonQuery()` inside migrated handlers are intentionally preserved without adding a corresponding `query` AJV schema to the route options. Adding query-param schemas for the `fields`/`sort`/`query` parameters consumed by `parseJsonQuery()` is a separate cross-cutting concern shared by many endpoints (e.g., users.create, users.update, users.list) and is explicitly out of scope for individual endpoint migration PRs. Do not flag the absence of a `query` schema for `parseJsonQuery()` usage as a violation of OpenAPI/AJV contract during migration reviews.
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: 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: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39647
File: apps/meteor/app/api/server/v1/users.ts:891-899
Timestamp: 2026-03-15T14:31:23.493Z
Learning: In RocketChat/Rocket.Chat, `IUser.inactiveReason` in `packages/core-typings/src/IUser.ts` is typed as `'deactivated' | 'pending_approval' | 'idle_too_long'` (optional, no `null`), but the database stores `null` for newly created users. The Typia-generated `$ref: '#/components/schemas/IUser'` schema therefore correctly rejects `null` for `inactiveReason`. This causes the test "should create a new user with default roles" to fail when response validation is active (TEST_MODE). The fix is to add `| null` to `inactiveReason` in core-typings and rebuild Typia schemas in a separate PR. Do not flag this test failure as a bug introduced by the users.create OpenAPI migration (PR `#39647`). Do not suggest inlining a custom schema to work around it, as migration rules require using `$ref` when a Typia schema exists.
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 39553
File: apps/meteor/app/api/server/v1/stats.ts:98-117
Timestamp: 2026-03-20T13:52:29.575Z
Learning: In `apps/meteor/app/api/server/v1/stats.ts`, the `statistics.telemetry` POST endpoint intentionally has no `body` AJV schema in its route options. The proper request body shape (a `params` array of telemetry event objects) has not been formally defined yet, so body validation is deferred to a follow-up. Do not flag the missing body schema for this endpoint during OpenAPI migration reviews.
📚 Learning: 2026-03-16T21:50:37.589Z
Learnt from: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39676
File: .changeset/migrate-users-register-openapi.md:3-3
Timestamp: 2026-03-16T21:50:37.589Z
Learning: For changes related to OpenAPI migrations in Rocket.Chat/OpenAPI, when removing endpoint types and validators from rocket.chat/rest-typings (e.g., UserRegisterParamsPOST, /v1/users.register) document this as a minor changeset (not breaking) per RocketChat/Rocket.Chat-Open-API#150 Rule 7. Note that the endpoint type is re-exposed via a module augmentation .d.ts in the consuming package (e.g., packages/web-ui-registration/src/users-register.d.ts). In reviews, ensure the changeset clearly states: this is a non-breaking change, the major version should not be bumped, and the changeset reflects a minor version bump. Do not treat this as a breaking change during OpenAPI migrations.

Applied to files:

  • .changeset/flat-stingrays-complain.md
📚 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/flat-stingrays-complain.md
📚 Learning: 2026-03-15T14:31:28.969Z
Learnt from: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39647
File: apps/meteor/app/api/server/v1/users.ts:710-757
Timestamp: 2026-03-15T14:31:28.969Z
Learning: In RocketChat/Rocket.Chat, the `UserCreateParamsPOST` type in `apps/meteor/app/api/server/v1/users.ts` (migrated from `packages/rest-typings/src/v1/users/UserCreateParamsPOST.ts`) intentionally has `fields: string` (non-optional) and `settings?: IUserSettings` without a corresponding AJV schema entry. This is a pre-existing divergence carried over verbatim from the original rest-typings source (PR `#39647`). Do not flag this type/schema misalignment during the OpenAPI migration review — it is tracked as a separate follow-up fix.

Applied to files:

  • .changeset/flat-stingrays-complain.md
  • apps/meteor/app/api/server/v1/groups.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:

  • .changeset/flat-stingrays-complain.md
  • apps/meteor/app/api/server/v1/groups.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/flat-stingrays-complain.md
📚 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:

  • .changeset/flat-stingrays-complain.md
📚 Learning: 2026-03-14T14:58:58.834Z
Learnt from: smirk-dev
Repo: RocketChat/Rocket.Chat PR: 39625
File: apps/meteor/app/api/server/v1/push.ts:85-97
Timestamp: 2026-03-14T14:58:58.834Z
Learning: In RocketChat/Rocket.Chat, the `push.token` POST/DELETE endpoints in `apps/meteor/app/api/server/v1/push.ts` were already migrated to the chained router API pattern on `develop` prior to PR `#39625`. `cleanTokenResult` (which strips `authToken` and returns `PushTokenResult`) and `isPushTokenPOSTProps`/`isPushTokenDELETEProps` validators already exist on `develop`. PR `#39625` only migrates `push.get` and `push.info` to the chained pattern. Do not flag `cleanTokenResult` or `PushTokenResult` as newly introduced behavior-breaking changes when reviewing this PR.

Applied to files:

  • .changeset/flat-stingrays-complain.md
  • apps/meteor/app/api/server/v1/groups.ts
📚 Learning: 2026-03-12T10:26:26.697Z
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:26.697Z
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:

  • .changeset/flat-stingrays-complain.md
  • apps/meteor/app/api/server/v1/groups.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:

  • .changeset/flat-stingrays-complain.md
  • apps/meteor/app/api/server/v1/groups.ts
📚 Learning: 2026-03-16T23:33:15.721Z
Learnt from: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39676
File: apps/meteor/app/api/server/v1/users.ts:862-869
Timestamp: 2026-03-16T23:33:15.721Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs (e.g., PR `#39676` for users.register in apps/meteor/app/api/server/v1/users.ts), calls to `this.parseJsonQuery()` inside migrated handlers are intentionally preserved without adding a corresponding `query` AJV schema to the route options. Adding query-param schemas for the `fields`/`sort`/`query` parameters consumed by `parseJsonQuery()` is a separate cross-cutting concern shared by many endpoints (e.g., users.create, users.update, users.list) and is explicitly out of scope for individual endpoint migration PRs. Do not flag the absence of a `query` schema for `parseJsonQuery()` usage as a violation of OpenAPI/AJV contract during migration reviews.

Applied to files:

  • .changeset/flat-stingrays-complain.md
  • apps/meteor/app/api/server/v1/groups.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/flat-stingrays-complain.md
  • apps/meteor/app/api/server/v1/groups.ts
📚 Learning: 2026-03-16T21:50:42.118Z
Learnt from: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39676
File: .changeset/migrate-users-register-openapi.md:3-3
Timestamp: 2026-03-16T21:50:42.118Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs, removing endpoint types and validators from `rocket.chat/rest-typings` (e.g., `UserRegisterParamsPOST`, `/v1/users.register` entry) is the *required* migration pattern per RocketChat/Rocket.Chat-Open-API#150 Rule 7 ("No More rest-typings or Manual Typings"). The endpoint type is re-exposed via a module augmentation `.d.ts` file in the consuming package (e.g., `packages/web-ui-registration/src/users-register.d.ts`). This is NOT a breaking change — the correct changeset bump for `rocket.chat/rest-typings` in this scenario is `minor`, not `major`. Do not flag this as a breaking change during OpenAPI migration reviews.

Applied to files:

  • apps/meteor/app/api/server/v1/groups.ts
  • packages/rest-typings/src/v1/groups/index.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/groups.ts
📚 Learning: 2026-03-20T13:52:29.575Z
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 39553
File: apps/meteor/app/api/server/v1/stats.ts:98-117
Timestamp: 2026-03-20T13:52:29.575Z
Learning: In `apps/meteor/app/api/server/v1/stats.ts`, the `statistics.telemetry` POST endpoint intentionally has no `body` AJV schema in its route options. The proper request body shape (a `params` array of telemetry event objects) has not been formally defined yet, so body validation is deferred to a follow-up. Do not flag the missing body schema for this endpoint during OpenAPI migration reviews.

Applied to files:

  • apps/meteor/app/api/server/v1/groups.ts
📚 Learning: 2025-11-27T17:56:26.050Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37557
File: apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx:115-116
Timestamp: 2025-11-27T17:56:26.050Z
Learning: In Rocket.Chat, the GET /v1/abac/rooms endpoint (implemented in ee/packages/abac/src/index.ts) only returns rooms where abacAttributes exists and is not an empty array (query: { abacAttributes: { $exists: true, $ne: [] } }). Therefore, in components consuming this endpoint (like AdminABACRooms.tsx), room.abacAttributes is guaranteed to be defined for all returned rooms, and optional chaining before calling array methods like .join() is sufficient without additional null coalescing.

Applied to files:

  • apps/meteor/app/api/server/v1/groups.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/groups.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/groups.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/groups.ts
  • packages/rest-typings/src/v1/groups/index.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/groups.ts
  • packages/rest-typings/src/v1/groups/index.ts
🔇 Additional comments (1)
packages/rest-typings/src/v1/groups/index.ts (1)

3-3: LGTM.

Re-exporting BaseProps here keeps the shared group base helpers available after removing the endpoint-specific GroupsMembersProps barrel.

Comment on lines +80 to +94
const isGroupsMembersResponse = ajv.compile({
type: 'object',
properties: {
members: {
type: 'array',
items: { $ref: '#/components/schemas/IUser' },
},
count: { type: 'integer' },
offset: { type: 'integer' },
total: { type: 'integer' },
success: { type: 'boolean', enum: [true] },
},
required: ['members', 'success'],
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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Examine the groups.ts file to see the current state and patterns
cat -n apps/meteor/app/api/server/v1/groups.ts | head -150

Repository: RocketChat/Rocket.Chat

Length of output: 6668


🏁 Script executed:

# Look for similar response schema patterns in rooms.ts to confirm the convention
rg "ajv\.compile" apps/meteor/app/api/server/v1/rooms.ts -A 10 | head -100

Repository: RocketChat/Rocket.Chat

Length of output: 2266


🏁 Script executed:

# Check if there's a changeset describing this as an OpenAPI migration
fd -e md apps/meteor/app/api/server/v1/ | head -20

Repository: RocketChat/Rocket.Chat

Length of output: 491


🏁 Script executed:

# Search for pagination-field patterns in other migrated endpoints
rg "count.*offset.*total" apps/meteor/app/api/server/v1/ --type ts -B 2 | head -80

Repository: RocketChat/Rocket.Chat

Length of output: 3920


🏁 Script executed:

# Check if there's a changeset or PR context for this groups.ts file
find apps/meteor/app/api/server/v1 -name "*.md" -o -name "changeset*" | head -10

Repository: RocketChat/Rocket.Chat

Length of output: 48


🏁 Script executed:

# Verify by examining rooms.ts more closely to see the pattern distinction
rg "rooms\.delete|rooms\.leave|rooms\.favorite" apps/meteor/app/api/server/v1/rooms.ts -B 5 -A 15 | head -80

Repository: RocketChat/Rocket.Chat

Length of output: 1381


🏁 Script executed:

# Check the context around groups.ts to verify it's an OpenAPI migration
rg "GroupsHistoryEndpoints|GroupsMembersEndpoints" apps/meteor/app/api/server/v1/groups.ts -A 3 -B 3

Repository: RocketChat/Rocket.Chat

Length of output: 364


🏁 Script executed:

# Confirm the pattern: compare groups.members (paginated) vs a simple groups endpoint
rg "groups\.(delete|leave|archive)" apps/meteor/app/api/server/v1/groups.ts -B 5 -A 15 | head -100

Repository: RocketChat/Rocket.Chat

Length of output: 1159


Explicitly type the 200 response schema and require all pagination fields.

The groups.members endpoint is paginated; the handler always returns members, count, offset, total, and success (lines 141–146). The response schema must reflect this contract. Leaving the generic type unspecified and omitting pagination fields from required weakens both the exported endpoint type and runtime validation. All similar paginated endpoints across the codebase (settings, videoConference, moderation, etc.) explicitly include these fields in their required array.

Suggested fix
+type GroupsMembersResponse = {
+	members: IUser[];
+	count: number;
+	offset: number;
+	total: number;
+	success: true;
+};
+
-const isGroupsMembersResponse = ajv.compile({
+const isGroupsMembersResponse = ajv.compile<GroupsMembersResponse>({
 	type: 'object',
 	properties: {
 		members: {
 			type: 'array',
 			items: { $ref: '#/components/schemas/IUser' },
 		},
 		count: { type: 'integer' },
 		offset: { type: 'integer' },
 		total: { type: 'integer' },
 		success: { type: 'boolean', enum: [true] },
 	},
-	required: ['members', 'success'],
+	required: ['members', 'count', 'offset', 'total', 'success'],
 	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/groups.ts` around lines 80 - 94, Update the
isGroupsMembersResponse AJV schema so the 200 response is fully typed and
enforces all pagination fields: ensure the schema for members remains an array
of items with $ref '#/components/schemas/IUser', keep success as boolean enum
[true], and add "count", "offset", and "total" to the schema's required array
(i.e., required: ['members','count','offset','total','success']) so runtime
validation and the exported endpoint types reflect the actual handler contract;
make no other structural changes to the object shape or additionalProperties
setting.

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