Skip to content

docs(api): import the channels and groups prose from the definitions repo - #41645

Draft
ggazzo wants to merge 6 commits into
chore/api-openapi-metadatafrom
chore/api-openapi-import-prose
Draft

ggazzo wants to merge 6 commits into
chore/api-openapi-metadatafrom
chore/api-openapi-import-prose

Conversation

@ggazzo

@ggazzo ggazzo commented Jul 30, 2026

Copy link
Copy Markdown
Member

Stacked on #41638 — review that one first; this PR targets its branch, not develop.

Proposed changes (including videos or screenshots)

The summaries, descriptions and payload examples of our REST endpoints live in RocketChat/Rocket.Chat-Open-API, hand-maintained YAML that nothing checks against the code. I audited it against the document our own framework generates:

Operations described there 588
Operations registered here (/api/docs/json?withUndocumented=true) 674
Match by method + path 561 (377 typed, 184 still legacy)
Described there, not registered here 27
Registered here with no prose anywhere 113

So most of the prose can simply move next to the route it documents, where it is reviewed with the code that changes it.

This PR imports the 226 operations that are already typed (90% of the typed call sites in the repository):

  • summary and description, including the per-endpoint changelog tables the definitions repository keeps (### Changelog appears in 66% of its descriptions);
  • named request and response examples — the feature it uses most (1010 example objects, 156 payloads documenting two to six alternatives), which feat(api): richer OpenAPI metadata for typed endpoints #41638 taught the framework to express;
  • the tags, so the generated document groups endpoints exactly like the published documentation does — 32 groups (Channels 42, Rooms 26, Groups 22, Users 16, Teams 16, Import 10, Moderation 9, Settings 8, Integration 8, Video Conference 7, …) instead of the ad hoc tags we had.

Types are deliberately not imported. The schemas in this repository are the source of truth and are validated at runtime; the hand-written ones are looser (required appears 284 times across 10901 type nodes) and would be a regression.

How it was done

scripts/import-openapi-prose.ts matches operations by method and path (normalizing :id to {id}), injects the prose into the route options, and writes the bulky examples into a sibling <file>.examples.ts so the endpoint definitions stay readable:

API.v1.get(
	'channels.history',
	{
		summary: 'Get Channel History',
		description: `Retrieves the history of a channel. You must be a member of the channel or have the \`preview-c-room\` permission. ...`,
		examples: channelsExamples['channels.history'],
		authRequired: true,
		query: isChannelsHistoryProps,
		response: { 200: channelsHistoryResponseSchema, 400: ..., 401: ..., 403: ... },
	},
	async function action() { /* unchanged */ },
);

The script is idempotent (it skips call sites that already declare a summary) and only keeps examples for status codes the route actually declares.

Issue(s)

Steps to test or reproduce

  1. curl -s localhost:3000/api/docs/json | jq '.paths["/api/v1/channels.history"].get | {summary, description, examples: (.responses."200".content."application/json".examples | keys)}'
  2. Open /api-docs, group Channels: every operation now has a summary, a description with its changelog, and selectable example scenarios in the response panel.
  3. Re-running the import changes nothing: bun scripts/import-openapi-prose.ts --spec ../Rocket.Chat-Open-API --dry-run apps/meteor/server/api/v1/channels.ts reports would import 0.

Further comments

Re-running the import after the definitions repository changes is a single command:

bun scripts/import-openapi-prose.ts --spec ../Rocket.Chat-Open-API apps/meteor/server/api/v1/*.ts

It is idempotent: call sites that already declare a summary are skipped, and only examples for status codes the route actually declares are kept.

Two findings from the audit that are worth handling separately:

  • 113 registered operations have no prose at all anywhere — those need writing, not importing. 25 of them are typed, so they can be documented right away.
  • 335 matching operations are still registered through the legacy addRoute and have nowhere to put documentation until they are typed.
  • 27 documented operations no longer exist in the code (/api/v1/livechat/sms-incoming/{service} and friends); the definitions repository should drop them.

@dionisio-bot

dionisio-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

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

changeset-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 47dabea

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

This PR includes changesets to release 3 packages
Name Type
@rocket.chat/meteor Patch
@rocket.chat/core-typings Patch
@rocket.chat/rest-typings 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

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

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 Plus

Run ID: baad0144-0207-4b07-b8ec-6f44652db7f3

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

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.

@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.80%. Comparing base (f5a13bb) to head (47dabea).

Additional details and impacted files

Impacted file tree graph

@@                      Coverage Diff                       @@
##           chore/api-openapi-metadata   #41645      +/-   ##
==============================================================
+ Coverage                       68.77%   68.80%   +0.02%     
==============================================================
  Files                            4156     4195      +39     
  Lines                          159825   159714     -111     
  Branches                        28070    28039      -31     
==============================================================
- Hits                           109927   109892      -35     
+ Misses                          44722    44641      -81     
- Partials                         5176     5181       +5     
Flag Coverage Δ
e2e 58.85% <ø> (+0.01%) ⬆️
e2e-api 46.04% <100.00%> (+0.31%) ⬆️
unit 70.74% <ø> (-0.02%) ⬇️

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 force-pushed the chore/api-openapi-import-prose branch 14 times, most recently from 7d592f1 to 58490bb Compare August 3, 2026 20:25
ggazzo added 6 commits August 3, 2026 17:48
…s repo

The summaries, descriptions, payload examples and tags of our endpoints have
been maintained by hand in RocketChat/Rocket.Chat-Open-API, where nothing checks
them against the code and they drift silently. Of the 588 operations described
there, 561 match a route registered by this repository, so the prose can live
next to the routes it documents and be reviewed with the code that changes them.

This imports the prose of every typed route that has one - 359 operations:

- summary and description, including the per endpoint changelog tables the
  definitions repository keeps;
- the named request and response examples;
- the tags, so the generated document groups endpoints the same way the published
  documentation does instead of the ad hoc tags we had.

Types are deliberately NOT imported - the schemas here are the source of truth
and are validated at runtime, while the hand-written ones are looser. What is
left out is the routes still registered through the legacy `addRoute`, which have
nowhere to carry documentation until they are typed.

`scripts/import-openapi-prose.ts` performs the import, matching operations by
method and path, so re-running it after the definitions repository changes is a
single command. Examples land in a sibling `<file>.examples.ts` module to keep
the route options readable.
…ects

The examples import surfaced a pre-existing violation in businessHours.ts and customField.ts, where the sibling imports sat after a deeper parent one. It went unnoticed because the lint task was reading them from cache.
`dm.*` and `im.*` are the same endpoint under two names and declare their options
in a shared object, which the import skipped: it only recognized options written
inline at the call site. It now resolves the identifier to its declaration, and
the definitions repository describes only one name of each pair, so the twin's
prose is reused.

Fourteen more operations documented, and the edits are applied from the last
offset backwards - shared objects are declared before the call sites that use
them, so they no longer come out in file order.
Importing `OpenAPIDocumentation` here put every example in the type graph of every
endpoint that uses them. The modules only need to describe the shape of a payload
example, so they declare it themselves and the cross package edge is gone.
Declaring the tags in the route options put them in the type every caller of the
endpoint sees, and 368 of them collapsed it: `Type 'Endpoints' recursively
references itself as a base type`, fifty times over, with two thousand errors
cascading through the client. Reproducing it locally needed the build artifacts out
of the program - their presence was hiding the failure that CI kept reporting.

The grouping now lives in `operationTags`, a generated map from operation to tags
that the document builder applies while assembling the paths. Same document, none
of the type weight.
The wiring was lost resolving a rebase conflict, leaving the generated map with no consumer and the operations ungrouped.
@ggazzo
ggazzo force-pushed the chore/api-openapi-import-prose branch from 58490bb to 47dabea Compare August 3, 2026 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant