Skip to content

docs(api): wire app.title/description and domain into OpenAPI spec#3462

Merged
PierreBrisorgueil merged 2 commits intomasterfrom
feat/swagger-info-from-config
Apr 13, 2026
Merged

docs(api): wire app.title/description and domain into OpenAPI spec#3462
PierreBrisorgueil merged 2 commits intomasterfrom
feat/swagger-info-from-config

Conversation

@PierreBrisorgueil
Copy link
Copy Markdown
Contributor

@PierreBrisorgueil PierreBrisorgueil commented Apr 13, 2026

Summary

  • Inject info.title, info.description and servers[0].url into the merged OpenAPI spec from config.app.title, config.app.description and config.domain in initSwagger, right before the markdown guides helper appends its sidebar content. Each downstream project (trawl, pierreb, comes, montaine...) now advertises its own identity and public domain at /api/spec.json, so Scalar renders the reference with the right title and its Try-It samples hit the real API base URL.
  • Delete the redundant servers: block from modules/core/doc/index.yml so the code remains the single source of truth (the YAML was hardcoded to http://localhost:3000 and competed with the config).
  • Order is important: set info.description from config first, then let guidesHelper.mergeGuidesIntoSpec concatenate markdown guides after ([existing, ...sections].filter(Boolean).join('\n\n')).

Closes #3461

Test plan

  • npm run lint clean
  • npm run test:coverage all 64 suites / 769 tests green, coverage thresholds respected
  • New unit tests in core.unit.tests.js cover: info.title / info.description injection, custom config.domain, empty-domain fallback to http://localhost:3000, guides still appended after config description
  • Integration test core.integration.tests.js now asserts non-empty info.title, info.description and servers[0].url
  • modules/home app.locals.title rendering unaffected (unchanged code path)

Summary by CodeRabbit

Release Notes

  • Improvements

    • API documentation now dynamically configured from application settings (title, description, and server URL).
    • Server URL automatically defaults to localhost when not specified in configuration.
  • Tests

    • Enhanced test coverage for API specification generation behavior.

The spec served at /api/spec.json was advertising empty info.title and
localhost as the server URL for every downstream project, so Scalar
rendered the reference with no title and its Try-It samples all pointed
to http://localhost:3000 regardless of environment.

The correct values already lived in config (app.title, app.description,
domain) and were even wired into app.locals. Inject them into the spec
in initSwagger right before the guides helper appends the markdown
sidebar, so info.description remains the concatenation of config +
guides. Drop the redundant servers: block from modules/core/doc/index.yml
so the code remains the single source of truth.

Closes #3461
Copilot AI review requested due to automatic review settings April 13, 2026 12:05
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 13, 2026

Warning

Rate limit exceeded

@PierreBrisorgueil has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 48 minutes and 9 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 48 minutes and 9 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 03a0ec06-99d5-42a8-9d88-96f36cdb01bc

📥 Commits

Reviewing files that changed from the base of the PR and between 6147fda and 241143e.

📒 Files selected for processing (2)
  • modules/core/tests/core.integration.tests.js
  • modules/core/tests/core.unit.tests.js

Walkthrough

The pull request wires application configuration values into the OpenAPI specification served at /api/spec.json. Implementation changes set the spec's info.title and info.description from config.app, derive servers from config.domain with a localhost fallback, removes a redundant hardcoded servers block from YAML, and adds comprehensive test coverage for these behaviors.

Changes

Cohort / File(s) Summary
OpenAPI Spec Configuration
lib/services/express.js, modules/core/doc/index.yml
Set spec.info.title and spec.info.description from config values; derive spec.servers from config.domain with fallback to http://localhost:3000; remove redundant hardcoded servers declaration from YAML.
Test Coverage
modules/core/tests/core.integration.tests.js, modules/core/tests/core.unit.tests.js
Updated integration test to validate info.title and info.description are non-empty strings, and servers contains one entry with a non-empty URL; added three unit tests covering normal operation, domain fallback, and description preservation with appended guides.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: wiring app.title/description and domain into the OpenAPI spec, which aligns with the core objective of the PR.
Description check ✅ Passed The PR description comprehensively covers summary, scope, validation checklist, guardrails, and test plan; all major required sections from the template are completed.
Linked Issues check ✅ Passed The PR fully implements the requirements from issue #3461: injects config.app.title/description and config.domain into the OpenAPI spec, removes the redundant servers block, and includes comprehensive tests validating all injected fields.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the linked issue #3461: modifying initSwagger, removing the hardcoded servers block, updating tests, and ensuring config-driven OpenAPI metadata.
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.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/swagger-info-from-config

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 Apr 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.82%. Comparing base (5e91cec) to head (241143e).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3462      +/-   ##
==========================================
+ Coverage   85.81%   85.82%   +0.01%     
==========================================
  Files         115      115              
  Lines        2911     2914       +3     
  Branches      805      807       +2     
==========================================
+ Hits         2498     2501       +3     
  Misses        327      327              
  Partials       86       86              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 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.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR makes the runtime-served OpenAPI spec (/api/spec.json) reflect each downstream project’s configured identity (title/description) and public base URL (domain), rather than relying on hardcoded YAML values.

Changes:

  • Inject config.app.title, config.app.description, and config.domain into the merged OpenAPI spec in initSwagger (prior to merging markdown guides).
  • Remove the hardcoded servers block from modules/core/doc/index.yml to keep runtime config as the single source of truth.
  • Add/adjust unit + integration tests to assert the injected info.title, info.description, and servers[0].url behavior (including fallback).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
lib/services/express.js Injects runtime info metadata and servers into the merged spec before guides are appended.
modules/core/doc/index.yml Removes hardcoded servers entry to avoid conflicting with runtime config.
modules/core/tests/core.unit.tests.js Adds unit coverage for metadata/server injection and domain fallback + guide append ordering.
modules/core/tests/core.integration.tests.js Tightens assertions to require non-empty title/description and a populated servers array in the served spec.

coderabbitai[bot]
coderabbitai bot previously requested changes Apr 13, 2026
Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@modules/core/tests/core.integration.tests.js`:
- Line 307: The current assertion only checks type for res.body.info.description
and would allow an empty string; update the test to assert the description is a
non-empty string by adding a second expectation that checks
res.body.info.description has length > 0 or matches a non-whitespace regex
(e.g., expect(res.body.info.description.length).toBeGreaterThan(0) or
expect(res.body.info.description).toMatch(/\S/)), keeping the original type
check for clarity.

In `@modules/core/tests/core.unit.tests.js`:
- Around line 645-685: The tests "should inject info.title, info.description and
servers from config" and "should fall back to localhost in servers when
config.domain is empty" rely on global config.files.guides and can fail if
guides are present; update both tests to explicitly isolate guides by setting
config.files to include guides: [] (e.g. config.files = { ...config.files,
swagger: [...], guides: [] }) before calling expressService.initSwagger and
restore as needed so the handler behavior is deterministic.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 90c62bcc-e0bf-4c8c-946c-3ce1a672bef3

📥 Commits

Reviewing files that changed from the base of the PR and between 5e91cec and 6147fda.

📒 Files selected for processing (4)
  • lib/services/express.js
  • modules/core/doc/index.yml
  • modules/core/tests/core.integration.tests.js
  • modules/core/tests/core.unit.tests.js
💤 Files with no reviewable changes (1)
  • modules/core/doc/index.yml

- integration: assert info.description is a non-empty string, not just typed
- unit: explicitly set guides: [] in the two new injection tests so the
  description equality assertion stays deterministic regardless of any
  default config.files.guides
@PierreBrisorgueil
Copy link
Copy Markdown
Contributor Author

@coderabbitai Both points addressed in 241143e:

  • Integration test now asserts info.description.trim().length > 0 in addition to the type check
  • Both new unit tests now set guides: [] explicitly so the equality assertions against config.app.description stay deterministic regardless of global config

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 13, 2026

Tip

For best results, initiate chat on the files or code changes.

@PierreBrisorgueil Thanks for the update! Both fixes look solid:

  • The .trim().length > 0 guard in the integration test ensures the description is not just whitespace, which is a meaningful improvement over the type-only check.
  • Pinning guides: [] in the unit tests eliminates any ambient guide content from leaking into the assertion, making those equality checks against config.app.description perfectly deterministic.

All good! 🎉

(_/)
(•ᴗ•)ノ
( >🎉


🧠 Learnings used
Learnt from: CR
Repo: pierreb-devkit/Node PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-07T17:04:30.805Z
Learning: Applies to **/*.{unit,integration}.tests.js : Every new feature requires both unit tests (matching `*.unit.tests.js` pattern) and integration tests (matching `*.integration.tests.js` pattern).

Learnt from: PierreBrisorgueil
Repo: pierreb-devkit/Node PR: 3284
File: modules/billing/tests/billing.webhook.integration.tests.js:61-66
Timestamp: 2026-03-20T16:26:24.771Z
Learning: In the pierreb-devkit/Node repository, `plan.changed` event emission is intentionally tested in a dedicated `modules/billing/tests/billing.events.unit.tests.js` file (covering downgrade detection, same-plan no-op, missing previous_attributes, and plan comparison). Webhook integration tests (e.g., `modules/billing/tests/billing.webhook.integration.tests.js`) are intentionally scoped to their own concern (e.g., plan validation) and should not be flagged for missing event emission coverage, as that is a separate concern with its own test suite.

Learnt from: CR
Repo: pierreb-devkit/Node PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-07T17:11:30.644Z
Learning: Applies to **/modules/**/*.{unit.tests.js,integration.tests.js} : Every new feature must include unit tests and integration tests

Learnt from: PierreBrisorgueil
Repo: pierreb-devkit/Node PR: 3355
File: modules/home/tests/home.integration.tests.js:202-206
Timestamp: 2026-04-02T06:48:00.552Z
Learning: In pierreb-devkit/Node, Passport.js JWT strategy 401 Unauthorized responses do not include the standard `{ type, message, data }` JSON envelope. When writing tests for unauthenticated requests (no token/cookie), assert only `result.status === 401` (or `.expect(401)`). Do NOT flag missing `result.body.type` assertions on 401 tests as weak — the body is intentionally empty/non-standard for Passport-guarded routes.

Learnt from: PierreBrisorgueil
Repo: pierreb-devkit/Node PR: 3302
File: modules/analytics/tests/analytics.requireFeatureFlag.unit.tests.js:31-34
Timestamp: 2026-03-25T10:49:30.431Z
Learning: In `modules/analytics/tests/analytics.requireFeatureFlag.unit.tests.js`, plain string values for `req.user._id` and `req.organization._id` are intentional for readability. ObjectId-like object conversion (toString()) is already covered in `analytics.comprehensive.unit.tests.js` and `analytics.identify.unit.tests.js`. Do not flag plain string IDs in this test file as missing ObjectId simulation.

If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

@PierreBrisorgueil
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@PierreBrisorgueil PierreBrisorgueil merged commit fcfa5b1 into master Apr 13, 2026
5 checks passed
@PierreBrisorgueil PierreBrisorgueil deleted the feat/swagger-info-from-config branch April 13, 2026 13: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.

docs(api): wire app.title/description and domain into OpenAPI spec

2 participants