Skip to content

chore: Add OpenAPI support for teams discovery endpoints#39945

Open
vivekyarra wants to merge 1 commit intoRocketChat:developfrom
vivekyarra:chore/openapi-migrate-teams-discovery
Open

chore: Add OpenAPI support for teams discovery endpoints#39945
vivekyarra wants to merge 1 commit intoRocketChat:developfrom
vivekyarra:chore/openapi-migrate-teams-discovery

Conversation

@vivekyarra
Copy link
Copy Markdown

@vivekyarra vivekyarra commented Mar 29, 2026

Proposed changes

Migrates 6 teams discovery/listing endpoints from the deprecated API.v1.addRoute
pattern to the new API.v1.get pattern with full OpenAPI support.

Endpoints migrated:

  • teams.list
  • teams.listAll
  • teams.listChildren
  • teams.members
  • teams.info
  • teams.autocomplete

Changes per endpoint:

  • Added AJV query validators with proper schemas
  • Added OpenAPI response schemas (200, 400, 401, 403, 404 where applicable)
  • Zero changes to business logic — behavior is identical

Issue(s)

Relates to #34983

Steps to test or reproduce

  1. GET /api/v1/teams.list — returns paginated team list
  2. GET /api/v1/teams.listAll — returns all teams (admin only)
  3. GET /api/v1/teams.listChildren?teamId=xxx — returns team rooms
  4. GET /api/v1/teams.members?teamId=xxx — returns team members
  5. GET /api/v1/teams.info?teamId=xxx — returns team info
  6. GET /api/v1/teams.autocomplete?name=xxx — returns autocomplete results

Further comments

GSoC 2026 contributor applying for the OpenClaw Integration project.
Second qualifying PR following the same migration pattern as #39225, #39227, and #39932.

Summary by CodeRabbit

Release Notes

  • Chores
    • Added OpenAPI specification support for teams discovery endpoints, improving API documentation standards.
    • Enhanced request validation and standardized error handling across team-related API endpoints for improved reliability.

@vivekyarra vivekyarra requested a review from a team as a code owner March 29, 2026 11:20
@dionisio-bot
Copy link
Copy Markdown
Contributor

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

🦋 Changeset detected

Latest commit: 148aecf

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/meteor Patch
@rocket.chat/core-typings Patch
@rocket.chat/rest-typings Patch
@rocket.chat/uikit-playground Patch
@rocket.chat/api-client Patch
@rocket.chat/apps Patch
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/ddp-client Patch
@rocket.chat/fuselage-ui-kit Patch
@rocket.chat/gazzodown Patch
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/ui-avatar Patch
@rocket.chat/ui-client Patch
@rocket.chat/ui-contexts Patch
@rocket.chat/ui-voip Patch
@rocket.chat/web-ui-registration Patch
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/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 Patch
@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 29, 2026

Walkthrough

Added OpenAPI support for team discovery endpoints by introducing AJV-based query validation and explicit response schemas for six team read operations, replacing inline validation assertions with schema-driven route definitions while preserving underlying business logic.

Changes

Cohort / File(s) Summary
Changeset Entry
.changeset/teams-discovery-openapi.md
New changeset declaring patch release for teams discovery OpenAPI support.
Teams API Endpoints
apps/meteor/app/api/server/v1/teams.ts
Migrated six team read endpoints (teams.list, teams.listAll, teams.listChildren, teams.members, teams.info, teams.autocomplete) from inline meteor/check validation to AJV-based query validators and explicit success/error response schemas; business logic preserved.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

type: chore

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main objective: migrating six teams discovery endpoints to add OpenAPI support, which is the core change reflected throughout the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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 2 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: 1

🤖 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/teams.ts`:
- Around line 97-110: The TeamsMembersQuerySchema's status property only
declares type: 'array' so a single string query like ?status=online fails under
current ajvQuery coercion; update the TeamsMembersQuerySchema to accept both a
string and an array (e.g., set status type to ['array','string'] with items: {
type: 'string' }) and then normalize/coerce the value in the request handler
(e.g., if typeof status === 'string' convert to [status]) so both repeated
params and single values validate and work; reference TeamsMembersQuerySchema
and the status property for the change.
🪄 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: f1edb0c9-eeb4-437e-8f8f-d0940cd364ff

📥 Commits

Reviewing files that changed from the base of the PR and between 4235cd9 and 148aecf.

📒 Files selected for processing (2)
  • .changeset/teams-discovery-openapi.md
  • apps/meteor/app/api/server/v1/teams.ts
📜 Review details
🧰 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/teams.ts
🧠 Learnings (17)
📓 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: 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: 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: .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: 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: 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: 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-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/teams-discovery-openapi.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: 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/teams-discovery-openapi.md
📚 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/teams-discovery-openapi.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/teams-discovery-openapi.md
  • apps/meteor/app/api/server/v1/teams.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/teams-discovery-openapi.md
  • apps/meteor/app/api/server/v1/teams.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:

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

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

  • apps/meteor/app/api/server/v1/teams.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/teams.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/teams.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/teams.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/teams.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/teams.ts
🔇 Additional comments (10)
.changeset/teams-discovery-openapi.md (1)

1-5: LGTM!

The changeset correctly declares a patch release for the OpenAPI migration. This is appropriate since the PR adds schema-based validation and documentation without changing business logic or removing types from rest-typings.

apps/meteor/app/api/server/v1/teams.ts (9)

6-21: LGTM!

Imports correctly bring in ajvQuery for query validation (with type coercion for HTTP query strings) and ajv for response schemas. Error response validators align with the HTTP status codes used in route definitions.


34-63: LGTM!

Type definitions accurately model the query parameters. The optional TypeScript properties combined with oneOf schema constraints correctly enforce that at least one identifier is provided at runtime.


127-275: LGTM!

Response schemas correctly define the expected payloads. Using $ref for ITeam and IRoom maintains consistency with centralized component schemas. The teamsMembersResponseSchema properly handles nullable roles with oneOf: [array, null].


277-301: LGTM!

Clean migration to the new API.v1.get pattern with appropriate query validation and response schemas. Handler logic is preserved.


303-328: LGTM!

Correctly includes 403 response schema for the permission-required endpoint. Migration preserves the view-all-teams permission check.


652-678: LGTM!

Migration correctly uses the existing isTeamsListChildrenProps validator from rest-typings. The 404 response schema properly documents the API.v1.notFound() return path.


680-718: LGTM!

Migration correctly includes 403 response for the permission-gated flow. Handler logic is preserved with proper status/username/name filter extraction.


850-883: LGTM!

Migration correctly documents error responses. Note: Team/Room not found returns 400 via API.v1.failure() rather than 404 — this preserves existing behavior and the schema accurately reflects it.


912-930: LGTM!

Clean migration with strict schema validation (additionalProperties: false, minLength: 1). The minimal response schema coverage (200, 400, 401) matches the simple handler logic.

Comment on lines +97 to +110
const TeamsMembersQuerySchema = {
type: 'object',
properties: {
teamId: { type: 'string', nullable: true },
teamName: { type: 'string', nullable: true },
status: { type: 'array', items: { type: 'string' }, nullable: true },
username: { type: 'string', nullable: true },
name: { type: 'string', nullable: true },
count: { type: 'number', nullable: true },
offset: { type: 'number', nullable: true },
},
oneOf: [{ required: ['teamId'] }, { required: ['teamName'] }],
additionalProperties: true,
} as const;
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for how status param is used in client calls to teams.members
rg -n -C3 'teams\.members' --type=ts --type=tsx -g '!*.test.*' -g '!*spec*' | head -50

Repository: RocketChat/Rocket.Chat

Length of output: 93


🌐 Web query:

Does AJV coerceTypes: true automatically coerce single string to array?

💡 Result:

No, AJV with coerceTypes: true does not automatically coerce a single string to an array. With coerceTypes: true, AJV performs coercion between scalar types (string, number, boolean, null) according to specific rules, such as string to number if the string is numeric, or string "true"/"false" to boolean. However, coercion from a string (or other scalar) to an array requires coerceTypes: "array". The official documentation explicitly states that array coercions need {coerceTypes: "array"}, and shows examples like "foo" → ["foo"] only in that mode.

Citations:


🏁 Script executed:

# First, let's examine the teams.ts file to understand ajvQuery configuration and endpoint implementation
cat -n apps/meteor/app/api/server/v1/teams.ts | head -150

Repository: RocketChat/Rocket.Chat

Length of output: 5402


🏁 Script executed:

# Search for ajvQuery configuration in the teams.ts file
rg -n "ajvQuery\|coerceTypes" apps/meteor/app/api/server/v1/teams.ts

Repository: RocketChat/Rocket.Chat

Length of output: 48


🏁 Script executed:

# Find the teams.members endpoint implementation
rg -n -A 20 "teams\.members|TeamsMembersQuerySchema" apps/meteor/app/api/server/v1/teams.ts

Repository: RocketChat/Rocket.Chat

Length of output: 2292


🏁 Script executed:

# Check for similar array-type query parameters in other v1 endpoints
rg -n "type.*array.*items" apps/meteor/app/api/server/v1/ --type=ts | head -20

Repository: RocketChat/Rocket.Chat

Length of output: 2279


🏁 Script executed:

# Find where ajvQuery is initialized and what coerceTypes setting is used
rg -n "ajvQuery.*=" --type=ts -A 3 | grep -A 3 "coerceTypes"

Repository: RocketChat/Rocket.Chat

Length of output: 251


🏁 Script executed:

# Find where ajvQuery is imported/exported from rest-typings
rg -n "export.*ajvQuery\|const ajvQuery" --type=ts

Repository: RocketChat/Rocket.Chat

Length of output: 48


🏁 Script executed:

# Check the actual endpoint usage - does it expect array or handle single value?
rg -n -B 5 -A 10 "status.*this.queryParams" apps/meteor/app/api/server/v1/teams.ts

Repository: RocketChat/Rocket.Chat

Length of output: 651


🏁 Script executed:

# Search for how status is actually used in the endpoint logic
rg -n -A 20 "const.*status.*=.*queryParams" apps/meteor/app/api/server/v1/teams.ts

Repository: RocketChat/Rocket.Chat

Length of output: 855


🏁 Script executed:

# Check if there are other array query parameters in teams.ts or similar endpoints
rg -B 2 "type.*array.*items.*type.*string.*nullable" apps/meteor/app/api/server/v1/teams.ts

Repository: RocketChat/Rocket.Chat

Length of output: 231


🏁 Script executed:

# Look for any documentation or handling of array query params in the codebase
rg -n "coerceTypes.*array" --type=ts

Repository: RocketChat/Rocket.Chat

Length of output: 48


🏁 Script executed:

# Check if status parameter is tested anywhere to see expected behavior
rg -n "teams\.members.*status" --type=ts -g '!*.test.*' -g '!*spec*' | head -20

Repository: RocketChat/Rocket.Chat

Length of output: 48


The status array query parameter lacks proper AJV coercion configuration.

With ajvQuery configured as coerceTypes: true, a single string value (e.g., ?status=online) will fail validation — array coercion requires coerceTypes: 'array'. Repeated parameters (?status=online&status=away) work because HTTP frameworks parse them as arrays natively, but the schema should clarify the intended usage or the AJV config should be adjusted.

Either:

  1. Update the schema to accept type: 'string' and coerce within the handler, or
  2. Configure ajvQuery to use coerceTypes: 'array', or
  3. Document that status only accepts repeated query parameters.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/api/server/v1/teams.ts` around lines 97 - 110, The
TeamsMembersQuerySchema's status property only declares type: 'array' so a
single string query like ?status=online fails under current ajvQuery coercion;
update the TeamsMembersQuerySchema to accept both a string and an array (e.g.,
set status type to ['array','string'] with items: { type: 'string' }) and then
normalize/coerce the value in the request handler (e.g., if typeof status ===
'string' convert to [status]) so both repeated params and single values validate
and work; reference TeamsMembersQuerySchema and the status property for the
change.

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