Skip to content

feat(api-doc): add user and userRole paths with detailed documentation#900

Merged
nevil-mathew merged 15 commits into
developfrom
api-doc-rewrite
Jul 20, 2026
Merged

feat(api-doc): add user and userRole paths with detailed documentation#900
nevil-mathew merged 15 commits into
developfrom
api-doc-rewrite

Conversation

@nevil-mathew

@nevil-mathew nevil-mathew commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator
  • Implemented user-related API paths including read, profileById, setLanguagePreference, update, and share.
  • Added userRole paths for listing, creating, updating, and deleting user roles.
  • Included comprehensive descriptions, parameters, and response schemas for each endpoint.
  • Introduced scripts for route inventory and coverage checks to ensure API documentation accuracy.
  • Added validation for public controller actions.

Summary

  • Added extensive OpenAPI/Redoc documentation for user- and userRole-related API paths, including authenticated user profile read/update, language preference, mentor profile share, and user-role list/create/update/delete (plus deprecated default-role behavior), along with the checkUsername public endpoint.
  • Introduced/expanded many reusable OpenAPI component schemas and updated the bundled OpenAPI spec wiring to include the new user/userRole/public paths and their referenced components (including detailed request/response/error envelopes and “gap/shape-only/unconfirmed” notes).
  • Added API documentation tooling to improve correctness vs runtime routing: live route inventory generation, route inventory coverage checking against the bundled api-doc.yaml (with baseline suppression), and Redocly-based build/lint automation.

API contract and security changes

  • New public endpoint (and validator):
    • GET /user/v1/public/checkUsername (checkUsername) with username query param and documented 200/406/422 responses.
    • Added src/validators/v1/public.js export checkUsername(req) which trims/validates username and returns username field is empty on validation failure.
  • Auth/security documentation updates:
    • Added Redocly/OpenAPI security scheme for API-key style auth via header X-auth-token.
    • The OpenAPI spec also documents internal access auth via internal_access_token (matching process.env.INTERNAL_ACCESS_TOKEN) for internal endpoints.
  • Documentation corrections/standardization:
    • Fixed/standardized Role-Permission Mapping documentation (removed previously fabricated path params/examples and corrected method/status expectations).

Database migrations and rollback impact

  • No database migration files were added/modified in this PR.
  • Infrastructure changes affect local/CI runtime setup (Docker Compose + env), so rollback is primarily about reverting those configuration/doc-tooling changes rather than schema state.

Environment, config, and CI pipeline changes

  • Docker/In-dev environment:
    • Updated Docker Compose stacks to replace prior Mongo-oriented setup with Kafka/ZooKeeper/Redis + Citus-based Postgres, including:
      • Health checks for dependencies and depends_on gating on healthy services.
      • Postgres parameterization via environment variables and switch to a Citus image.
      • Kafka port/advertising changes and added health checks.
      • user service rebuilt from local context with nodemon + remote debug enabled.
    • Updated dev-ops/integration_test.env to use Docker-service connectivity (DEV_DATABASE_URL, APPLICATION_HOST, etc.), add CI-only placeholder external-service URLs required at boot, rename email encryption env vars, disable captcha, and adjust cloud-storage-related placeholders.
  • Ignore/regenerated artifacts:
    • .dockerignore updated to ignore node_modules.
    • .gitignore updated to exclude regenerated API-doc tooling outputs (route inventory JSON and *redoc-static.html).
  • CI (CircleCI):
    • Disabled/removed unit and integration test execution and coverage artifact publishing in the build job.
    • Replaced those steps with an API-doc pipeline:
      • bundle OpenAPI docs,
      • lint docs with a max-problem threshold,
      • generate live route inventory (via Docker boot),
      • check route coverage vs api-doc.yaml,
      • upload src/api-doc/api-doc.yaml as an artifact.

Background workers / queues / external integrations

  • No worker/queue implementation changes.
  • CI/integration runtime now expects additional external service base URL placeholders at boot (documented via dev-ops/integration_test.env updates).

Risk and impact

  • Main functional risk is CI behavior: removing unit/integration test execution increases regression risk.
  • Documentation coverage checks can fail the build if runtime routes diverge from the documented spec; a baseline suppression file is included to mitigate known gaps.
  • Many schemas explicitly mark missing captured examples (“gap/shape-only/unconfirmed”), so consumers should not assume exact example payloads where flagged.

Expected-but-not-changed items

  • No database migrations were added/modified.
  • No env sample updates were indicated beyond dev-ops/integration_test.env and Docker Compose/env wiring; e.g., src/.env.sample (if present) was not referenced in the provided change set.

- Implemented user-related API paths including read, profileById, setLanguagePreference, update, and share.
- Added userRole paths for listing, creating, updating, and deleting user roles.
- Included comprehensive descriptions, parameters, and response schemas for each endpoint.
- Introduced scripts for route inventory and coverage checks to ensure API documentation accuracy.
- Added validation for public controller actions.
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@nevil-mathew, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 39 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 54c22385-cfcc-4838-9b88-f3594f090bcf

📥 Commits

Reviewing files that changed from the base of the PR and between 1da1117 and e39a76a.

📒 Files selected for processing (29)
  • src/api-doc/api-doc.yaml
  • src/api-doc/components/account.yaml
  • src/api-doc/components/admin.yaml
  • src/api-doc/components/cloudServices.yaml
  • src/api-doc/components/entity-type.yaml
  • src/api-doc/components/feature.yaml
  • src/api-doc/components/form.yaml
  • src/api-doc/components/notification.yaml
  • src/api-doc/components/org-admin.yaml
  • src/api-doc/components/organization.yaml
  • src/api-doc/components/public.yaml
  • src/api-doc/components/userRole.yaml
  • src/api-doc/components/userentity.yaml
  • src/api-doc/openapi.yaml
  • src/api-doc/paths/cloud-services.yaml
  • src/api-doc/paths/entity-type.yaml
  • src/api-doc/paths/entity.yaml
  • src/api-doc/paths/feature.yaml
  • src/api-doc/paths/form.yaml
  • src/api-doc/paths/modules.yaml
  • src/api-doc/paths/notification.yaml
  • src/api-doc/paths/org-admin.yaml
  • src/api-doc/paths/permissions.yaml
  • src/api-doc/paths/public.yaml
  • src/api-doc/paths/rolePermissionMapping.yaml
  • src/api-doc/paths/tenant.yaml
  • src/api-doc/paths/userRole.yaml
  • src/package.json
  • src/scripts/api-doc/strip-internal-notes.js

Walkthrough

The PR adds extensive OpenAPI schemas and endpoint definitions, introduces route inventory and coverage validation, updates CI to build API documentation, and reworks Docker Compose services around Citus Postgres and health-gated dependencies.

Changes

API documentation and infrastructure

Layer / File(s) Summary
Runtime infrastructure
docker-compose.yml, dev-ops/docker-compose.yml, dev-ops/integration_test.env
Compose stacks now use Citus Postgres, health checks, service-based database configuration, restart policies, and health-gated dependencies.
OpenAPI contracts
src/api-doc/components/*, src/api-doc/openapi.yaml
Adds reusable request/response schemas, security definitions, response examples, and service metadata across API domains.
Endpoint documentation
src/api-doc/paths/*
Adds path definitions for account, user, tenant, organization, admin, entity, feature, form, notification, permission, role, cloud-service, public, and health operations.
Documentation validation
src/scripts/api-doc/*, src/package.json, .circleci/config.yml, src/redocly.yaml
Adds bundling, linting, route inventory, structural route-coverage checks, baseline handling, and CI artifact publication.
Repository support
.gitignore, .dockerignore, src/validators/v1/public.js
Updates generated-output ignores, anchors the dependency ignore rule, and adds username query validation.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CircleCI
  participant Redocly
  participant route_inventory
  participant ExpressApp
  participant coverage_check

  CircleCI->>Redocly: Bundle and lint OpenAPI document
  CircleCI->>route_inventory: Generate route inventory
  route_inventory->>ExpressApp: Boot app and intercept listen
  ExpressApp-->>route_inventory: Registered route patterns
  CircleCI->>coverage_check: Check documented route coverage
  coverage_check->>route_inventory: Read route inventory
  coverage_check->>Redocly: Read bundled documented paths
  coverage_check-->>CircleCI: Pass or fail coverage validation
Loading

Possibly related PRs

Suggested labels: api-contract, config, docs

Poem

A rabbit hops through YAML bright,
Bundling paths by morning light.
Routes are counted, gaps take flight,
Containers wait till health is right.
“Docs now bloom!” the bunny sings.

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title follows Conventional Commit format and clearly summarizes the documentation-focused API-doc changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Api Docs Updated ✅ Passed Only change is an internal script that strips x-internal-note lines from bundled api-doc.yaml; no public contract code changed.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch api-doc-rewrite

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.

nevil-mathew and others added 7 commits July 16, 2026 18:25
Fixes nullable-type-sibling (missing type alongside nullable across
user.yaml profile/organization response schemas), invalid type: 'null'
usage in system.yaml (OAS 3.0 doesn't support JSON Schema null type),
a stray schema-level examples: block in tenant.yaml (redundant with
the requestBody-level examples already present), and two path
parameters in cloud-services.yaml that were declared in: path with a
snake_case name but are actually camelCase query parameters per the
validator (fileName/filePath) - also moved their internal validator
commentary out of description into x-internal-note.

Warnings down 89 -> 72 as a side effect. 72 warnings (operationId,
example validation, missing 2xx/4xx) remain for the next pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… warnings)

Adds operationId to every operation that was missing one, following the
existing repo convention (verb+Resource, e.g. createFeature/updateForm)
for generic path keys, and keeping already-descriptive path keys as-is
(e.g. getRequests, bulkUserCreate) for org-admin.yaml/notification.yaml/
cloud-services.yaml. Two org-admin.yaml operations were suffixed
OrgAdmin to avoid colliding with existing operationIds of the same verb
in admin.yaml (deactivateUser) and to disambiguate from a generic name
(updateUser/createUsers).

Warnings down 72 -> 31.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Quote numeric-string path param examples (user.yaml) to match their
  string schema.
- Add missing 401 responses to cloud-services.yaml's getDownloadableUrl
  and getSampleCSV (auth middleware applies to both, same as
  getSignedUrl already had).
- Add a 401 to organization.yaml's list operation.
- Wire up entity.yaml's read/delete operations to their already-defined
  but unused readUserEntity200Response/deleteUserEntity400Response
  component schemas, and add new shape-only updateUserEntity202Response/
  entityList200Response schemas for update/list, all with no fabricated
  captured example (schema only + x-internal-note per repo convention).
- Add missing `meta`/`meta.formsVersion` properties to several response
  schemas (entity-type.yaml, userentity.yaml, profile.yaml's shared
  Unauthorized401Response) whose examples included a meta.correlation
  block the schema didn't declare.
- Add nullable: true to organization-feature.yaml request properties
  that use `example: null` without it.
- Fix three org-admin.yaml oneOf/discriminator response schemas
  (updateRequestStatus 400, inheritEntityType 400, updateUser 400) whose
  sibling branches were indistinguishable loose `message: string`
  schemas - added enum/const-style restriction per branch so examples
  match exactly one schema, and added a discriminator to
  updateRequestStatus's oneOf. Cleaned the accompanying "(GAP, no
  captured body)" text out of the example values themselves into
  x-internal-note, matching the target public-description style.
- Disambiguate tenant.yaml's tenantUpsertRequest oneOf (createTenant vs
  updateTenant) with additionalProperties: false on the update branch,
  since code/domains/status are stripped server-side and were the only
  fields distinguishing a create-shaped body from an update-shaped one.

redocly lint: 0 errors, 1 warning (no-server-example.com, intentionally
kept per src/redocly.yaml - the spec legitimately documents a local dev
server).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…criptions

Finishes the GAP-text/internal-commentary cleanup pass across all
paths/*.yaml and components/*.yaml files. Every response/operation
description that previously contained "GAP: ...", "shape-only",
"verbatim capture", "no captured example", "CORRECTION (post-hoc
review): ...", source file references (services/*.js, controllers/*.js,
validators/*.js), or docs-process commentary now has that content
relocated to a sibling x-internal-note field, with the public
description rewritten as plain customer-facing API documentation. No
factual/behavioral content was deleted - only relocated and reworded.
Several files had already received this treatment in a prior session
and needed no further changes.

Remaining "GAP:"/"shape-only" strings in the tree are exclusively
inside x-internal-note block-scalar continuations (not descriptions)
or top-of-file YAML `#` comments, which aren't part of the rendered
public spec.

redocly lint: still 0 errors, 1 warning (no-server-example.com,
intentional).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Regenerates the redocly-bundled output (docs:bundle script) so the
generated file reflects the lint-clean, GAP-text-cleaned source in
openapi.yaml/paths/components. Bundling emitted 3 pre-existing
component-name-collision warnings (e.g. deactivateUser400Response
defined differently in org-admin.yaml vs admin.yaml, auto-renamed by
the bundler) - these are structural naming collisions across domains,
not lint errors, and existed before this session's changes; out of
scope for this pass. redocly lint on the regenerated bundle: 0 errors,
1 warning (no-server-example.com, intentional).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Refactored the description in the OpenAPI info section for clarity.
- Added detailed tags for various API categories to improve documentation structure.
- Removed deprecated endpoints from the OpenAPI paths.
- Introduced new tenant and organization feature endpoints in the OpenAPI paths.
- Added a new Redocly configuration file to enhance API documentation management.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

🟠 Major comments (30)
dev-ops/integration_test.env-97-98 (1)

97-98: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Provide hex values for the encryption key and IV. src/utils/emailEncryption.js reads both with Buffer.from(..., 'hex'), so the current Base64 strings decode incorrectly and break email encryption/decryption.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@dev-ops/integration_test.env` around lines 97 - 98, Replace the Base64 values
assigned to EMAIL_ID_ENCRYPTION_KEY and EMAIL_ID_ENCRYPTION_IV with valid
hexadecimal strings of the required key and IV lengths, matching the
Buffer.from(..., 'hex') parsing in email encryption. Keep both environment
variable names unchanged.
docker-compose.yml-86-89 (1)

86-89: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Bind the published inspector port to localhost.

9229:9229 exposes the Node inspector on all host interfaces. Restrict it to loopback unless remote debugging is intentional.

Suggested change
-      - '9229:9229'
+      - '127.0.0.1:9229:9229'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker-compose.yml` around lines 86 - 89, Update the inspector port mapping
in the service configuration near the nodemon command to bind host port 9229
only to localhost, while preserving the container port and existing application
port mapping.
src/api-doc/components/user.yaml-286-289 (1)

286-289: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Replace complete JWTs with inert placeholders.

These examples contain full signed token strings and encoded identity data. Even if expired, they trigger secret scanning and should not be published as reusable credentials.

Also applies to: 465-481, 622-625, 749-749

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/components/user.yaml` around lines 286 - 289, Replace the
complete signed JWT examples in the affected schema definitions, including the
refresh_token example and the additionally referenced locations, with inert
non-credential placeholders. Preserve the example fields and YAML structure
while ensuring no encoded identity data, signatures, or reusable token-like
values remain.

Source: Linters/SAST tools

src/api-doc/components/entity-type.yaml-29-37 (1)

29-37: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not advertise a validator-rejected allow_filtering value.

The schema permits any boolean and explicitly examples true, while the documented validator requires this field to be empty. Remove the property/example or constrain it to the values the validator actually accepts.

As per path instructions, request schemas and examples must remain consistent with src/validators/**.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/components/entity-type.yaml` around lines 29 - 37, Update the
allow_filtering definition in the entity-type request schema to match the
validator’s isEmpty() requirement: remove the property and its example, or
constrain documentation and examples to validator-accepted empty values. Do not
advertise true or any other boolean value that validation rejects.

Source: Path instructions

src/api-doc/paths/account.yaml-593-601 (1)

593-601: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not use an error envelope for successful responses.

Both 200 responses reference clientErrorResponse, which advertises responseCode: CLIENT_ERROR. Define shape-only success components until captures are available.

As per path instructions, uncaptured responses must be shape-only and must not invent response bodies.

Also applies to: 641-649

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/account.yaml` around lines 593 - 601, Update both
successful 200 response schemas in the account API documentation to stop
referencing clientErrorResponse. Define or reference shape-only success
components for these uncaptured responses, containing only the verified response
structure without invented response bodies or responseCode: CLIENT_ERROR.

Source: Path instructions

src/api-doc/paths/account.yaml-88-93 (1)

88-93: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Mark required JSON bodies as required.

Without requestBody.required: true, an absent body is valid OpenAPI even when its schema contains required fields. Add it to each operation whose documented payload is mandatory.

As per path instructions, request schemas must match validator-required behavior.

Also applies to: 181-185, 227-231, 288-292, 334-338, 409-413, 492-496, 538-542, 587-591, 635-639, 771-775, 925-929

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/account.yaml` around lines 88 - 93, Mark each listed JSON
request body as mandatory by adding requestBody.required: true to the operations
using the referenced request schemas, including the loginRequest operation and
all additional locations noted in the review. Keep the existing descriptions,
content types, and schema references unchanged, and ensure the OpenAPI
documentation matches validator-required behavior.

Source: Path instructions

src/api-doc/components/account.yaml-64-68 (1)

64-68: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Encode the full phonephone_code dependency.

The current anyOf branches only guarantee an identity field. A payload containing both email and phone but no phone_code still validates, despite the documented server rule.

  • src/api-doc/components/account.yaml#L64-L68: require phone_code whenever phone is present for account creation.
  • src/api-doc/components/account.yaml#L187-L193: apply the same dependency to registration OTP.
  • src/api-doc/components/admin.yaml#L30-L32: ensure the email branch cannot bypass phone_code when phone is also supplied.

As per path instructions, cross-field constraints must match scripts/api-doc/cross-field-rules.json.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/components/account.yaml` around lines 64 - 68, Update the
identity validation branches in src/api-doc/components/account.yaml lines 64-68
and 187-193, and src/api-doc/components/admin.yaml lines 30-32, so any payload
containing phone also requires phone_code, including email-plus-phone payloads.
Keep the schemas consistent with scripts/api-doc/cross-field-rules.json and
preserve the existing email-or-phone identity requirements.

Source: Path instructions

src/api-doc/components/userRole.yaml-105-113 (1)

105-113: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Remove the inferred INACTIVE request value or verify it in the validator manifest.

The component explicitly says this enum member comes from convention rather than the operation's validator. Publishing it tells clients the API accepts an unverified value.

As per path instructions, request enum values must be taken from scripts/api-doc/validator-fields.json, not inferred.

Also applies to: 143-146

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/components/userRole.yaml` around lines 105 - 113, Update the
status enum in the user role schema and the additionally referenced occurrence
to include only request values verified in
scripts/api-doc/validator-fields.json. Remove INACTIVE unless the validator
manifest confirms it, and keep the documented ACTIVE value and surrounding
schema metadata unchanged.

Source: Path instructions

src/api-doc/components/entity-type.yaml-444-492 (1)

444-492: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep uncaptured record payloads shape-only.

These schemas enumerate fields inferred from another operation while explicitly stating that the returning query-layer shape was not verified.

  • src/api-doc/components/entity-type.yaml#L444-L492: remove inferred updated-record properties from result.
  • src/api-doc/components/userentity.yaml#L287-L331: leave read result items as unstructured objects until captured or query-backed.
  • src/api-doc/components/userentity.yaml#L501-L534: do the same for entity-list items.

As per path instructions, do not accept invented schemas; uncaptured responses must remain shape-only.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/components/entity-type.yaml` around lines 444 - 492, Keep
uncaptured record payloads shape-only: in
src/api-doc/components/entity-type.yaml:444-492, remove the inferred properties
from updateEntityType202Response.result; in
src/api-doc/components/userentity.yaml:287-331 and
src/api-doc/components/userentity.yaml:501-534, leave the read and entity-list
result items as unstructured objects. Preserve the surrounding response
envelopes and metadata.

Source: Path instructions

src/api-doc/components/account.yaml-266-274 (1)

266-274: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Add minItems: 1 to arrays documented as non-empty.

These schemas currently accept empty arrays that their descriptions and validators reject.

  • src/api-doc/components/account.yaml#L266-L274: constrain emailIds.
  • src/api-doc/components/admin.yaml#L888-L905: constrain both id and email.
  • src/api-doc/components/entity-type.yaml#L22-L28: constrain create model_names.
  • src/api-doc/components/entity-type.yaml#L61-L77: constrain update model_names.
  • src/api-doc/components/org-admin.yaml#L465-L483: constrain ids and emails.
  • src/api-doc/components/organization.yaml#L99-L105: constrain added registration codes.
  • src/api-doc/components/organization.yaml#L123-L129: constrain removed registration codes.

As per path instructions, array structure in OpenAPI must match validator behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/components/account.yaml` around lines 266 - 274, Add minItems: 1
to every non-empty array schema: emailIds in src/api-doc/components/account.yaml
(266-274); id and email in src/api-doc/components/admin.yaml (888-905); create
and update model_names in src/api-doc/components/entity-type.yaml (22-28,
61-77); ids and emails in src/api-doc/components/org-admin.yaml (465-483); and
added and removed registration codes in src/api-doc/components/organization.yaml
(99-105, 123-129). Keep the existing item types and validation structure
unchanged.

Source: Path instructions

src/api-doc/paths/account.yaml-340-352 (1)

340-352: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not reuse captured examples from different endpoints.

resetPassword inherits the login example, and registrationOtp inherits the generate-OTP example despite neither endpoint having a capture. This presents unverified bodies as endpoint-specific examples; use dedicated shape-only schemas.

As per path instructions, response examples must come from the matching entry in captured-responses.json; uncaptured status/message combinations must remain shape-only.

Also applies to: 432-443

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/account.yaml` around lines 340 - 352, Update the
resetPassword 200 response and the registrationOtp response around their
existing schema references so they no longer reuse login or generate-OTP schemas
containing captured examples. Use dedicated shape-only response schemas for each
endpoint, preserving the documented response structure while leaving uncaptured
status/message combinations without examples.

Source: Path instructions

src/api-doc/components/user.yaml-740-749 (1)

740-749: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Require the field that the schema actually defines.

required names refreshToken, while the payload property is refresh_token. Consequently, a valid logout payload fails schema validation.

Proposed fix
   required:
-    - refreshToken
+    - refresh_token
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/components/user.yaml` around lines 740 - 749, Update the
logoutRequest schema’s required list to reference the defined refresh_token
property instead of refreshToken, while preserving the existing property name
and validation behavior.
src/api-doc/paths/account.yaml-761-788 (1)

761-788: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Declare InternalAccessToken instead of disabling security.

security: [] advertises anonymous access, but the documented 401 response requires internal_access_token. Use the existing internal security scheme.

Proposed fix
-    security: []
+    security:
+      - InternalAccessToken: []

As per path instructions, auth requirements and exact security headers are part of the public contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/account.yaml` around lines 761 - 788, Update the
validateUserSession operation’s security declaration to require the existing
InternalAccessToken security scheme instead of using security: []. Preserve the
current request and response definitions, including the documented 401 behavior.

Source: Path instructions

src/api-doc/components/org-admin.yaml-793-822 (1)

793-822: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Require upload_type before the documented crash path.

The schema accepts an omitted upload_type, although the controller calls .toUpperCase() unconditionally and returns a 500. Add request validation, update validator-fields.json, and mark the field required here.

Proposed schema change
 createUsersRequest:
   type: object
+  required:
+    - upload_type

As per path instructions, validation changes and matching OpenAPI requirements must be updated together.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/components/org-admin.yaml` around lines 793 - 822, Require
upload_type in the createUsersRequest schema and add matching request validation
for the create-users operation, updating validator-fields.json with the
appropriate field rule. Ensure validation runs before the controller’s
upload_type.toUpperCase() path so omitted values produce a validation error
instead of an uncaught server error.

Source: Path instructions

src/api-doc/components/tenant.yaml-63-110 (1)

63-110: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Represent the documented JSON-string input variants.

theming, configuration, and meta are documented as accepting JSON strings, but their schemas allow only objects. Generated clients will reject inputs the server accepts. Model each field with oneOf for the validated object and JSON string forms, or remove the unsupported claim.

Also applies to: 141-174

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/components/tenant.yaml` around lines 63 - 110, Update the schemas
for theming, configuration, and meta to match their documented inputs by using
oneOf variants for the validated object form and a JSON string form. Preserve
each field’s existing object validation, properties, required fields, and
examples, and apply the same correction to the corresponding fields in the
additional referenced section.
src/api-doc/components/organization-feature.yaml-330-344 (1)

330-344: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep every uncaptured response shape-only.

These sites explicitly state that no captured response exists but still publish concrete examples. Remove those examples until they can be copied verbatim from captured-responses.json.

  • src/api-doc/components/organization-feature.yaml#L330-L344: remove examples from the uncaptured update success schema.
  • src/api-doc/components/organization-feature.yaml#L441-L631: remove message examples from uncaptured failure schemas.
  • src/api-doc/components/tenant.yaml#L361-L453: remove examples from uncaptured tenant creation failures.
  • src/api-doc/components/tenant.yaml#L500-L783: remove examples from uncaptured update/domain/permission responses.
  • src/api-doc/components/tenant.yaml#L971-L1148: remove examples from uncaptured internal-read and bulk-create failures.
  • src/api-doc/paths/modules.yaml#L70-L101: remove fabricated create success/failure bodies.
  • src/api-doc/paths/modules.yaml#L177-L225: remove fabricated update bodies.
  • src/api-doc/paths/modules.yaml#L305-L338: remove fabricated list bodies.
  • src/api-doc/paths/modules.yaml#L378-L412: remove fabricated delete bodies.
  • src/api-doc/paths/org-admin.yaml#L121-L141: retain only the captured request-not-found example.
  • src/api-doc/paths/org-admin.yaml#L458-L472: remove the uncaptured entity-type-not-found body.
  • src/api-doc/paths/org-admin.yaml#L535-L555: retain only the captured user-not-found example.

As per path instructions, “Response example blocks must be copied verbatim from scripts/api-doc/captured-responses.json” and uncaptured combinations must be shape-only.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/components/organization-feature.yaml` around lines 330 - 344,
Remove all response examples from uncaptured, shape-only schemas across
src/api-doc/components/organization-feature.yaml (330-344, 441-631),
src/api-doc/components/tenant.yaml (361-453, 500-783, 971-1148), and fabricated
response bodies in src/api-doc/paths/modules.yaml (70-101, 177-225, 305-338,
378-412); also remove the uncaptured entity-type-not-found body in
src/api-doc/paths/org-admin.yaml (458-472). In src/api-doc/paths/org-admin.yaml
(121-141 and 535-555), retain only the captured request-not-found and
user-not-found examples respectively. Keep response examples only when copied
verbatim from captured-responses.json, leaving uncaptured responses shape-only.

Source: Path instructions

src/api-doc/paths/org-admin.yaml-7-16 (1)

7-16: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Fix the known root-document routing defects in this PR.

The fragment acknowledges that deactivateUser is wired with a nonexistent {id}, getRequestDetails omits its required {id}, and updateUser/createUsers are not exposed at all. Shipping the fragments without correcting openapi.yaml leaves the generated public contract missing or pointing to the wrong routes.

As per path instructions, path and method accuracy must be checked against the controller contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/org-admin.yaml` around lines 7 - 16, Update the root
OpenAPI document to correct the org-admin route wiring: point deactivateUser to
its body-based path without a nonexistent {id}, add the missing updateUser and
createUsers entries, and include /{id} in getRequestDetails. Verify each path
and method against the org-admin controller contract while preserving the
existing fragment references.

Source: Path instructions

src/api-doc/paths/form.yaml-119-194 (1)

119-194: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Do not advertise no-formId branches under a required path.

This operation is /read/{formId} with a required parameter, so the body-based lookup and list-all examples are unreachable through the documented route. The list-all branch also returns a different response schema that is absent here. Add separate root-path operations if they are routable, or remove these branches and constrain this body to {}.

As per path instructions, API paths, methods, requests, and responses must match the public runtime contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/form.yaml` around lines 119 - 194, Update the readForm API
documentation so the required {formId} route only documents the reachable formId
lookup with an empty request body. Remove the byTypeAndSubType and
listAllVersions examples and related no-formId claims from the operation
description and internal note; document separate root-path operations only if
those routes are publicly routable, using their correct request and response
schemas.

Source: Path instructions

src/api-doc/components/form.yaml-217-264 (1)

217-264: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Model the template_name/fields requirement in the schema.

The prose says these fields must occur together, but data.required only contains template_name, so generated clients accept a request the validator rejects. Add fields after recording this rule in cross-field-rules.json and regenerating the schema.

Proposed schema correction
       required:
         - template_name
+        - fields

As per path instructions, “Cross-field rules (anyOf/oneOf constraints) must come from scripts/api-doc/cross-field-rules.json.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/components/form.yaml` around lines 217 - 264, Update the
cross-field rule for updateFormRequest.data in
scripts/api-doc/cross-field-rules.json so template_name and fields are required
together, then regenerate the API schema. Ensure the generated data schema
represents the pairing with the repository’s established anyOf/oneOf pattern
instead of listing only template_name as unconditionally required.

Source: Path instructions

src/api-doc/components/securitySchemes.yaml-1-4 (1)

1-4: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove the invalid bearer property.

bearer: null is not a valid field on an apiKey security scheme and will break OpenAPI validation/bundling. The X-auth-token header definition is otherwise correct.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/components/securitySchemes.yaml` around lines 1 - 4, Remove the
invalid bearer property from the security scheme definition, while preserving
the existing apiKey type, X-auth-token name, and header location.

Source: Path instructions

.circleci/config.yml-22-27 (1)

22-27: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Restore unit and integration test execution.

The documentation workflow disables both existing test suites and their artifacts. Add the OpenAPI checks alongside these gates rather than replacing all application regression coverage.

Also applies to: 37-43

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.circleci/config.yml around lines 22 - 27, Restore the commented-out unit
and integration test steps in the CircleCI workflow, including their coverage
artifact storage, and add the OpenAPI checks alongside them. Preserve all
application regression gates rather than replacing them with only OpenAPI
validation.
src/api-doc/paths/organization.yaml-168-179 (1)

168-179: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Document the organizationIds request-body branch.

The operation advertises behavior driven by body.organizationIds, but defines no requestBody. Clients therefore cannot discover or validate this branch. Add its code-backed schema or remove the branch if it is not an HTTP input.

As per path instructions, request schemas must match documented controller and validator behavior.

Also applies to: 180-224

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/organization.yaml` around lines 168 - 179, The organization
list operation documents an organizationIds request-body branch without defining
a requestBody. Update the operation around the organization list path definition
to add a requestBody schema matching the controller and validator’s supported
organizationIds input, or remove the branch documentation if it is not an HTTP
input; keep the tenant_code and paginated branches unchanged.

Source: Path instructions

src/api-doc/paths/rolePermissionMapping.yaml-87-108 (1)

87-108: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep uncaptured responses shape-only.

These blocks explicitly have no captured response but still publish inferred example bodies. Remove their examples sections and retain only code-backed schemas.

As per path instructions, uncaptured status/message combinations must not invent response bodies.

Also applies to: 124-140, 216-231, 247-255, 317-349

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/rolePermissionMapping.yaml` around lines 87 - 108, Remove
the inferred examples for all uncaptured status/message blocks in the
role-permission mapping paths, including the block keyed by
gap_no_captured_example and the additional ranges identified in the review.
Retain only their code-backed schema definitions, preserving the existing
response shape without publishing example values.

Source: Path instructions

src/api-doc/paths/permissions.yaml-103-122 (1)

103-122: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Remove uncaptured response examples.

Each selected block says no endpoint capture exists but still supplies an example body, including inferred status/message values and placeholders. Shape-only responses must contain only schemas; the 401 captured through the wrong service path should likewise not be presented as this endpoint’s capture.

As per path instructions, response examples must be copied verbatim from matching captured responses; gaps must remain shape-only.

Also applies to: 138-147, 225-244, 260-279, 366-393, 408-415, 437-452, 491-506, 522-541

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/permissions.yaml` around lines 103 - 122, Remove the
fabricated `value` response bodies from the `gap_no_captured_example` blocks in
the permissions path, including the additionally referenced response ranges.
Leave each response shape-only with its schema and metadata; do not include
inferred values, placeholders, or the 401 response captured through another
service path.

Source: Path instructions

src/validators/v1/public.js-6-8 (1)

6-8: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Update the matching OpenAPI operation for this required query field.

This validator makes username required and changes validation-failure behavior, but the supplied API-doc changes contain no corresponding public-controller operation. Add/update its query schema and validation-error response in this PR.

As per path instructions, validator changes to required fields and validation errors must update matching OpenAPI documentation in the same PR.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/validators/v1/public.js` around lines 6 - 8, Update the OpenAPI
documentation for the public-controller operation corresponding to checkUsername
so its query schema marks username as required and its responses document the
validation-error behavior introduced by the validator. Locate the matching
operation by its public endpoint/controller symbol and keep the documented field
name and validation response aligned with checkUsername.

Source: Path instructions

src/api-doc/paths/permissions.yaml-103-541 (1)

103-541: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Uncaptured responses are being published with invented example values. Shape-only gaps should expose schemas without examples or property-level example values.

  • src/api-doc/paths/permissions.yaml#L103-L541: remove all examples lacking a matching endpoint capture, including the wrong-base-path 401.
  • src/api-doc/paths/rolePermissionMapping.yaml#L87-L349: remove inferred success and failure bodies where the summaries acknowledge no captures.
  • src/api-doc/paths/tenant.yaml#L578-L600: remove inferred responseCode and message examples from the uncaptured bulk-create success response.

As per path instructions, response examples must be copied verbatim from matching captured responses.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/permissions.yaml` around lines 103 - 541, Remove all
uncaptured response examples from src/api-doc/paths/permissions.yaml (anchor,
lines 103-541), including the wrong-base-path 401 example, leaving schemas only
unless a matching capture exists. Apply the same removal to inferred success and
failure examples in src/api-doc/paths/rolePermissionMapping.yaml (lines 87-349).
In src/api-doc/paths/tenant.yaml (lines 578-600), remove the inferred
responseCode and message example values from the uncaptured bulk-create success
response; retain only verbatim examples backed by matching captured responses.

Source: Path instructions

src/api-doc/paths/tenant.yaml-21-23 (1)

21-23: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Resolve the create-request contradiction.

The description says code and domains are always stripped and cannot be changed, while the create example supplies both fields and describes creation of a new tenant. Document the actual create-branch inputs from the validator/controller rather than publishing mutually exclusive behavior.

As per path instructions, request schemas and examples must match validated behavior.

Also applies to: 49-61

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/tenant.yaml` around lines 21 - 23, Update the tenant
endpoint documentation around tenantUpsertRequest to reflect the
validator/controller’s actual create-branch behavior: document which fields are
accepted when creating a tenant, and align the request schema and create example
with those validated inputs. Remove the contradictory claim that code and
domains are always stripped if they are supported during creation, while
preserving the correct update-branch restrictions.

Source: Path instructions

src/api-doc/paths/tenant.yaml-296-345 (1)

296-345: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Id-less route variants must be modeled as separate OpenAPI paths. A path parameter cannot be optional, and prose beneath the parameterized path does not expose the sibling route to clients or coverage tooling.

  • src/api-doc/paths/tenant.yaml#L296-L345: make {id} required and add /user/v1/tenant/read.
  • src/api-doc/paths/user.yaml#L1-L28: add /user/v1/user/read.
  • src/api-doc/paths/user.yaml#L93-L123: add /user/v1/user/profileById with its query parameters and cross-field rules.

As per path instructions, verify OpenAPI syntax and document every public path accurately.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/tenant.yaml` around lines 296 - 345, Model each id-less
route as a separate OpenAPI path: in src/api-doc/paths/tenant.yaml lines
296-345, make the id parameter required and add /user/v1/tenant/read; in
src/api-doc/paths/user.yaml lines 1-28, add /user/v1/user/read; and in
src/api-doc/paths/user.yaml lines 93-123, add /user/v1/user/profileById with its
query parameters and cross-field validation rules. Verify the resulting OpenAPI
syntax and accurately document every public path.

Source: Path instructions

src/api-doc/paths/organization.yaml-14-15 (1)

14-15: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Align the documented authorization status code.

The description says insufficient roles return 400 USER_IS_NOT_A_ADMIN, but the response contract assigns permission failures to 401 and describes 400 only as uniqueness/registration-code errors. Confirm the controller behavior and document the authorization envelope under the actual status.

As per path instructions, treat these files as the public API contract and verify status codes against implementation.

Also applies to: 41-59

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/organization.yaml` around lines 14 - 15, Verify the
organization endpoint’s controller behavior for insufficient ADMIN_ROLE or
TENANT_ADMIN_ROLE permissions, then align the authorization description and
response envelope in the OpenAPI path with the actual status, likely 401 rather
than 400. Keep 400 documented only for uniqueness or registration-code errors,
and update all affected authorization text in the path.

Source: Path instructions

src/api-doc/paths/tenant.yaml-543-570 (1)

543-570: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use the configured bulk-upload headers here.

organizationcode/tenantcode don’t match the runtime headers; the code reads common.ORG_CODE_HEADER and common.TENANT_CODE_HEADER, whose defaults are x-org-code and x-tenant-code. Update the OpenAPI names to those values (or the shipped env overrides).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/tenant.yaml` around lines 543 - 570, Update the header
parameter names in the bulk-upload endpoint definition to use the configured
values from common.ORG_CODE_HEADER and common.TENANT_CODE_HEADER, defaulting to
x-org-code and x-tenant-code instead of organizationcode and tenantcode. Keep
the existing descriptions, required settings, schemas, and examples unchanged.

Source: Path instructions

🟡 Minor comments (5)
src/api-doc/paths/notification.yaml-108-149 (1)

108-149: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Remove the unreachable code/list behavior from the by-ID operation.

This route requires {id} and declares no code query parameter, so clients cannot invoke either behavior described at Lines 119-120. Document those semantics only on the collection route, or expose an actual code parameter on a route where id is optional.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/notification.yaml` around lines 108 - 149, Update the
templateById GET operation’s description to remove the claims that code can
identify the template and that omitting both identifiers invokes list behavior,
since this operation requires the id path parameter and exposes no code query
parameter. Document those semantics only on the collection operation, or
otherwise expose code through a route where id is optional.
src/api-doc/components/profile.yaml-69-71 (1)

69-71: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Mark share_link nullable.

The example is null, but the schema permits only strings. This makes the documented example invalid and causes generated clients to reject a legitimate null value.

         share_link:
           type: string
+          nullable: true
           example: null
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/components/profile.yaml` around lines 69 - 71, Update the
share_link schema property to explicitly allow null values while retaining its
string type and existing example. Ensure the generated schema and clients
recognize share_link as nullable.
src/api-doc/paths/userRole.yaml-100-102 (1)

100-102: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove the empty request body from the list operation.

This GET takes no body, so publishing requestBody with empty content adds an invalid or misleading contract surface. Omit the block entirely.

As per path instructions, request schemas must match controller behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/userRole.yaml` around lines 100 - 102, Remove the
requestBody block from the GET list operation in the user role path definition,
including its description and empty content, so the published schema matches the
controller’s bodyless behavior.

Source: Path instructions

src/api-doc/paths/permissions.yaml-149-175 (1)

149-175: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Include {id} in the update and delete endpoint descriptions.

Both path items require an id path parameter, but their public descriptions show /update and /delete without it.

As per path instructions, verify public path accuracy.

Also applies to: 453-469

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/permissions.yaml` around lines 149 - 175, Update the public
descriptions for the updatePermissions and corresponding delete endpoint path
items to show the full routes including the required `{id}` path segment,
preserving the existing `/user/v1/permissions/update` and `/delete` route text
otherwise.

Source: Path instructions

src/api-doc/paths/rolePermissionMapping.yaml-12-18 (1)

12-18: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove draft-history commentary from public descriptions.

Details about previous fabricated drafts, router internals, controller fields, and gaps.jsonl are implementation notes rather than consumer-facing API behavior. Move them to x-internal-note or repository documentation.

As per path instructions, review these descriptions as the public API contract.

Also applies to: 152-158

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-doc/paths/rolePermissionMapping.yaml` around lines 12 - 18, Remove
the draft-history and implementation-detail commentary from the public API
descriptions in rolePermissionMapping.yaml, including the analogous content at
the referenced later section. Keep the descriptions limited to consumer-facing
endpoint behavior; move any necessary historical or internal details to
x-internal-note or repository documentation.

Source: Path instructions

🧹 Nitpick comments (3)
src/scripts/api-doc/route-inventory.js (3)

89-103: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use optional chaining for cleaner error message extraction.

Using optional chaining can simplify error message assignments.

♻️ Proposed fix
 process.on('unhandledRejection', (err) => {
-	const message = (err && err.message) || String(err)
+	const message = err?.message || String(err)
 	if (/ECONNREFUSED|ENOTFOUND|ETIMEDOUT|EAI_AGAIN/.test(message)) {
 		reportUnreachable('unhandled connection failure during boot (DB/Redis/Kafka)', err)
 	}
 	reportUnreachable('unhandled rejection during boot', err)
 })

 process.on('uncaughtException', (err) => {
-	const message = (err && err.message) || String(err)
+	const message = err?.message || String(err)
 	if (/ECONNREFUSED|ENOTFOUND|ETIMEDOUT|EAI_AGAIN/.test(message)) {
 		reportUnreachable('uncaught connection failure during boot (DB/Redis/Kafka)', err)
 	}
 	reportUnreachable('uncaught exception during boot', err)
 })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/scripts/api-doc/route-inventory.js` around lines 89 - 103, In the
unhandledRejection and uncaughtException handlers, simplify error message
extraction by replacing the explicit err && err.message check with optional
chaining while preserving the existing String(err) fallback and connection-error
detection behavior.

29-42: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use optional chaining for cleaner object property access.

Consider using optional chaining (?.) instead of logical AND (&&) for conciseness.

♻️ Proposed fix
 function layerPath(layer) {
-	if (layer.route && layer.route.path !== undefined) return layer.route.path
-	if (layer.regexp && layer.regexp.fast_star) return '*'
+	if (layer.route?.path !== undefined) return layer.route.path
+	if (layer.regexp?.fast_star) return '*'
 	if (layer.regexp) {
 		// best-effort readable form for non-route middleware mount points
 		const match = layer.regexp
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/scripts/api-doc/route-inventory.js` around lines 29 - 42, Update
layerPath to use optional chaining when accessing nested route and regexp
properties, replacing the existing guarded property access while preserving the
current path, wildcard, readable-regexp, and null-return behavior.

27-27: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove unused METHODS constant.

The METHODS array is assigned but never used, as HTTP methods are safely extracted directly from layer.route.methods.

♻️ Proposed fix
-const METHODS = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'all']
-
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/scripts/api-doc/route-inventory.js` at line 27, Remove the unused METHODS
constant from the route inventory module; retain the existing direct extraction
of HTTP methods from layer.route.methods.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cb662bad-9a2e-483a-aa20-dfd29d785e3c

📥 Commits

Reviewing files that changed from the base of the PR and between c2263ae and 8cfcfc1.

📒 Files selected for processing (48)
  • .circleci/config.yml
  • .dockerignore
  • .gitignore
  • dev-ops/docker-compose.yml
  • dev-ops/integration_test.env
  • docker-compose.yml
  • src/api-doc/api-doc.yaml
  • src/api-doc/components/account.yaml
  • src/api-doc/components/admin.yaml
  • src/api-doc/components/cloudServices.yaml
  • src/api-doc/components/entity-type.yaml
  • src/api-doc/components/feature.yaml
  • src/api-doc/components/form.yaml
  • src/api-doc/components/notification.yaml
  • src/api-doc/components/org-admin.yaml
  • src/api-doc/components/organization-feature.yaml
  • src/api-doc/components/organization.yaml
  • src/api-doc/components/profile.yaml
  • src/api-doc/components/securitySchemes.yaml
  • src/api-doc/components/tenant.yaml
  • src/api-doc/components/user.yaml
  • src/api-doc/components/userRole.yaml
  • src/api-doc/components/userentity.yaml
  • src/api-doc/openapi.yaml
  • src/api-doc/paths/account.yaml
  • src/api-doc/paths/admin.yaml
  • src/api-doc/paths/cloud-services.yaml
  • src/api-doc/paths/entity-type.yaml
  • src/api-doc/paths/entity.yaml
  • src/api-doc/paths/feature.yaml
  • src/api-doc/paths/form.yaml
  • src/api-doc/paths/modules.yaml
  • src/api-doc/paths/notification.yaml
  • src/api-doc/paths/org-admin.yaml
  • src/api-doc/paths/organization-feature.yaml
  • src/api-doc/paths/organization.yaml
  • src/api-doc/paths/permissions.yaml
  • src/api-doc/paths/rolePermissionMapping.yaml
  • src/api-doc/paths/system.yaml
  • src/api-doc/paths/tenant.yaml
  • src/api-doc/paths/user.yaml
  • src/api-doc/paths/userRole.yaml
  • src/package.json
  • src/redocly.yaml
  • src/scripts/api-doc/check-route-coverage.js
  • src/scripts/api-doc/route-coverage-baseline.json
  • src/scripts/api-doc/route-inventory.js
  • src/validators/v1/public.js
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
src/api-doc/**

⚙️ CodeRabbit configuration file

Review these files as the public API contract. Check OpenAPI syntax, path/method accuracy, request and response schemas, examples, auth/security requirements, status codes, and consistency with src/controllers/v1/, src/services/, src/validators/v1/, and src/dtos/. Do not accept invented schemas or responses; prefer documented behavior backed by validators, controllers, DTOs, or captured responses.

Files:

  • src/api-doc/api-doc.yaml
  • src/api-doc/components/securitySchemes.yaml
  • src/api-doc/components/cloudServices.yaml
  • src/api-doc/paths/cloud-services.yaml
  • src/api-doc/paths/feature.yaml
  • src/api-doc/paths/form.yaml
  • src/api-doc/paths/system.yaml
  • src/api-doc/openapi.yaml
  • src/api-doc/paths/admin.yaml
  • src/api-doc/paths/modules.yaml
  • src/api-doc/paths/userRole.yaml
  • src/api-doc/paths/user.yaml
  • src/api-doc/components/notification.yaml
  • src/api-doc/paths/permissions.yaml
  • src/api-doc/components/admin.yaml
  • src/api-doc/paths/entity.yaml
  • src/api-doc/components/feature.yaml
  • src/api-doc/paths/notification.yaml
  • src/api-doc/components/form.yaml
  • src/api-doc/paths/organization.yaml
  • src/api-doc/paths/tenant.yaml
  • src/api-doc/paths/organization-feature.yaml
  • src/api-doc/paths/org-admin.yaml
  • src/api-doc/paths/entity-type.yaml
  • src/api-doc/paths/rolePermissionMapping.yaml
  • src/api-doc/components/profile.yaml
  • src/api-doc/components/account.yaml
  • src/api-doc/components/userRole.yaml
  • src/api-doc/components/userentity.yaml
  • src/api-doc/components/organization.yaml
  • src/api-doc/components/entity-type.yaml
  • src/api-doc/components/tenant.yaml
  • src/api-doc/components/organization-feature.yaml
  • src/api-doc/components/org-admin.yaml
  • src/api-doc/paths/account.yaml
  • src/api-doc/components/user.yaml
src/validators/**

⚙️ CodeRabbit configuration file

Validate all incoming data thoroughly. Check for missing or incomplete validation rules. If request validation changes required fields, optional fields, formats, enum values, array/object structure, cross-field rules, or validation error behavior, verify that the matching OpenAPI request schema and validation-failure documentation under src/api-doc/** are updated in the same PR.

Files:

  • src/validators/v1/public.js
🪛 ast-grep (0.44.1)
src/scripts/api-doc/check-route-coverage.js

[warning] 67-67: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFileSync(ROUTE_INVENTORY_FILE, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename)


[warning] 73-73: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFileSync(API_DOC_FILE, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename)


[warning] 82-82: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFileSync(BASELINE_FILE, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename)

src/scripts/api-doc/route-inventory.js

[warning] 77-77: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(OUTPUT_FILE, JSON.stringify(output, null, 2) + '\n')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename)


[warning] 118-118: Avoid require with non-literal values
Context: require(APP_FILE)
Note: [CWE-829] Inclusion of Functionality from Untrusted Control Sphere (dynamic require).

(detect-non-literal-require)

🪛 Betterleaks (1.6.1)
dev-ops/integration_test.env

[high] 97-97: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

src/api-doc/components/user.yaml

[high] 286-286: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)


[high] 289-289: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)


[high] 465-465: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)


[high] 481-481: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)


[high] 622-622: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)


[high] 625-625: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)


[high] 749-749: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

🪛 Checkov (3.3.8)
src/api-doc/api-doc.yaml

[medium] 1651-1655: Ensure that arrays have a maximum number of items

(CKV_OPENAPI_21)


[high] 5036-5037: AWS Access Key

(CKV_SECRET_2)


[high] 7010-7021: Ensure that API keys are not sent over cleartext

(CKV_OPENAPI_20)

src/api-doc/paths/cloud-services.yaml

[high] 73-74: AWS Access Key

(CKV_SECRET_2)

🪛 ESLint
src/scripts/api-doc/route-inventory.js

[error] 27-27: 'METHODS' is assigned a value but never used.

(no-unused-vars)

🪛 GitHub Check: SonarCloud
src/api-doc/api-doc.yaml

[failure] 7650-7650: Password hashes should not be disclosed

Make sure this bcrypt password hash gets revoked, changed, and removed from the code.

See more on SonarQube Cloud

🪛 GitHub Check: SonarCloud Code Analysis
src/scripts/api-doc/check-route-coverage.js

[warning] 28-28: Prefer node:path over path.

See more on https://sonarcloud.io/project/issues?id=ELEVATE-Project_user&issues=AZ9rADTzudde5MzmDoc2&open=AZ9rADTzudde5MzmDoc2&pullRequest=900


[warning] 27-27: Prefer node:fs over fs.

See more on https://sonarcloud.io/project/issues?id=ELEVATE-Project_user&issues=AZ9rADTzudde5MzmDoc1&open=AZ9rADTzudde5MzmDoc1&pullRequest=900

src/scripts/api-doc/route-inventory.js

[warning] 21-21: Prefer node:fs over fs.

See more on https://sonarcloud.io/project/issues?id=ELEVATE-Project_user&issues=AZ9rADTNudde5MzmDocr&open=AZ9rADTNudde5MzmDocr&pullRequest=900


[warning] 90-90: 'err' will use Object's default stringification format ('[object Object]') when stringified.

See more on https://sonarcloud.io/project/issues?id=ELEVATE-Project_user&issues=AZ9rADTNudde5MzmDocz&open=AZ9rADTNudde5MzmDocz&pullRequest=900


[warning] 22-22: Prefer node:path over path.

See more on https://sonarcloud.io/project/issues?id=ELEVATE-Project_user&issues=AZ9rADTNudde5MzmDocs&open=AZ9rADTNudde5MzmDocs&pullRequest=900


[warning] 90-90: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=ELEVATE-Project_user&issues=AZ9rADTNudde5MzmDocy&open=AZ9rADTNudde5MzmDocy&pullRequest=900


[warning] 30-30: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=ELEVATE-Project_user&issues=AZ9rADTNudde5MzmDoct&open=AZ9rADTNudde5MzmDoct&pullRequest=900


[warning] 85-85: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=ELEVATE-Project_user&issues=AZ9rADTNudde5MzmDocx&open=AZ9rADTNudde5MzmDocx&pullRequest=900


[warning] 38-38: Prefer String#replaceAll() over String#replace().

See more on https://sonarcloud.io/project/issues?id=ELEVATE-Project_user&issues=AZ9rADTNudde5MzmDocv&open=AZ9rADTNudde5MzmDocv&pullRequest=900


[warning] 53-53: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=ELEVATE-Project_user&issues=AZ9rADTNudde5MzmDocw&open=AZ9rADTNudde5MzmDocw&pullRequest=900


[warning] 31-31: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=ELEVATE-Project_user&issues=AZ9rADTNudde5MzmDocu&open=AZ9rADTNudde5MzmDocu&pullRequest=900


[warning] 98-98: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=ELEVATE-Project_user&issues=AZ9rADTNudde5MzmDoc0&open=AZ9rADTNudde5MzmDoc0&pullRequest=900

@nevil-mathew

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

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.

@nevil-mathew

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Action 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.

- Added 401 Unauthorized responses for create, update, and read operations in form.yaml.
- Updated request and response schemas in modules.yaml, removing unnecessary fields.
- Enhanced error handling in notification.yaml for template creation conflicts.
- Clarified error descriptions and added 500 Internal Server Error responses in org-admin.yaml.
- Improved permissions.yaml with detailed error handling for create and update operations.
- Introduced new branding and userInvites endpoints in public.yaml with comprehensive documentation.
- Revised rolePermissionMapping.yaml to correct endpoint documentation and response structures.
- Updated tenant.yaml with example values for domain-related operations.
- Enhanced userRole.yaml to reflect accurate error handling for role title conflicts.
- Modified package.json to include new documentation build scripts.
@sonarqubecloud

Copy link
Copy Markdown

@nevil-mathew
nevil-mathew merged commit 577b9da into develop Jul 20, 2026
3 of 4 checks passed
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