Skip to content

[Devportal] Improve the db schemas and rest apis#2249

Open
Piumal1999 wants to merge 17 commits into
wso2:mainfrom
Piumal1999:restapis
Open

[Devportal] Improve the db schemas and rest apis#2249
Piumal1999 wants to merge 17 commits into
wso2:mainfrom
Piumal1999:restapis

Conversation

@Piumal1999

@Piumal1999 Piumal1999 commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Purpose

$subject

Approach

Move webhook subscribers to database
Rename subscriptionPolicies to subscriptionPlans
Improve the rest apis based on wso2 rest api guidelines
Add agent visibility field to API metadata create/update requests
Refactor role and group handling in passport configuration

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR migrates Developer Portal contracts and runtime behavior from subscription policies to subscription plans, adds webhook subscriber API support, standardizes documented and returned error payloads, and converts multiple list endpoints to { list, pagination } responses. It also updates database schema and models, switches stored API file content fields to FILE_CONTENT, revises organization and key manager data handling, updates portal UI and samples, and refreshes OpenAPI, REST API docs, scopes, and configuration examples.

Suggested reviewers

  • RakhithaRR
  • Tharsanan1
  • VirajSalaka
  • renuka-fernando
  • malinthaprasan
  • AnuGayan
  • chamilaadhi
  • Arshardh
  • dushaniw
  • tgtshanika
  • senthuran16
  • tharikaGitHub
  • CrowleyRajapakse
  • hisanhunais
  • HiranyaKavishani
  • HeshanSudarshana
  • ashera96
  • pubudu538
  • Krishanx92
  • PasanT9
  • lasanthaS
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 24.24% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The PR description is largely incomplete and does not follow the required template structure, missing critical sections like Goals, User stories, Documentation, Automation tests, Security checks, and Samples. Provide a complete PR description following the template with Purpose, Goals, Approach, User stories, Documentation links, test coverage details, security verification, samples overview, related PRs, and test environment specifications.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the main changes: improvements to database schemas and REST APIs for the developer portal.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 18

Note

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
portals/developer-portal/src/models/organization.js (1)

92-95: ⚠️ Potential issue | 🟠 Major

Add uniqueness constraint or validation to prevent duplicate organization assets with null VIEW_ID.

The unique index UQ_ORGANIZATION_ASSETS_TYPE_NAME_PATH_ORG_VIEW includes VIEW_ID, which is nullable. PostgreSQL permits multiple NULL values in unique indexes, allowing duplicate rows with the same FILE_TYPE, FILE_NAME, FILE_PATH, and ORG_ID whenever VIEW_ID is NULL. This risk is compounded by the ON DELETE SET NULL foreign key, which nullifies VIEW_ID when views are deleted—potentially creating unintended duplicates.

No validation logic or documented design explanation mitigates this. Either enforce VIEW_ID as NOT NULL (if views are always required), or implement a partial unique index or CHECK constraint to handle null-view cases explicitly.

🤖 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 `@portals/developer-portal/src/models/organization.js` around lines 92 - 95,
The VIEW_ID field in the organization assets model is nullable but included in a
unique constraint, which allows PostgreSQL to permit multiple NULL values and
create duplicate rows with the same FILE_TYPE, FILE_NAME, FILE_PATH, and ORG_ID.
To fix this, either change allowNull to false for VIEW_ID in the field
definition to enforce that views are always required, or implement a partial
unique index in the migration that excludes NULL VIEW_ID values (such as a
constraint that only applies when VIEW_ID IS NOT NULL). Additionally, consider
updating the ON DELETE SET NULL foreign key behavior to ON DELETE CASCADE or ON
DELETE RESTRICT if making VIEW_ID non-nullable, and document the design decision
for null-view scenarios.
portals/developer-portal/src/services/keyManagerService.js (2)

124-127: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use resolved payload name in duplicate-name response.

Line 126 always reads from req.body?.name; for YAML upload flows this can produce an unclear conflict message. Capture the resolved payload name and use it in the 409 response.

Proposed fix
 const createKeyManager = async (req, res) => {
+    let resolvedPayload;
     try {
         const orgId = req.params.orgId;
-        const payload = _resolvePayload(req);
+        const payload = _resolvePayload(req);
+        resolvedPayload = payload;
 
         const validationError = _validateRequiredFields(payload);
         if (validationError) {
             return res.status(400).json({ error: validationError });
         }
@@
     } catch (error) {
         if (error instanceof Sequelize.UniqueConstraintError) {
             return res.status(409).json({
-                error: `A key manager with name "${req.body?.name}" already exists in this organization.`
+                error: `A key manager with name "${resolvedPayload?.name || req.body?.name}" already exists in this organization.`
             });
         }
🤖 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 `@portals/developer-portal/src/services/keyManagerService.js` around lines 124
- 127, The duplicate key manager error response in the
Sequelize.UniqueConstraintError handler uses req.body?.name directly, which
produces unclear messages in YAML upload flows. Instead, capture the resolved
payload name that was used for the key manager creation (this should be
available earlier in the request handler logic) and use that resolved name in
the 409 response message instead of req.body?.name, ensuring the conflict
message accurately reflects the actual name that was processed.

96-104: ⚠️ Potential issue | 🟡 Minor

Type constraint enforcement confirmed via OpenAPI schema validation, not at database/model layer.

Unsupported key manager types are rejected by the OpenAPI validator before requests reach service code. The KeyManagerRequest and KeyManagerResponseSchema definitions in devportal-openapi-spec-v1.yaml enforce an enum constraint: [ASGARDEO, WSO2IS, KEYCLOAK, GENERIC_OIDC]. However, no CHECK constraint or ENUM type exists at the database level, and the Sequelize model uses DataTypes.STRING without validation. This means direct DAO calls or database access bypassing the API would not enforce type constraints. For API-driven create/update operations, the OpenAPI validator catches invalid types before the service layer, so the simplified field validation is appropriate in that context.

🤖 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 `@portals/developer-portal/src/services/keyManagerService.js` around lines 96 -
104, The _validateRequiredFields function currently only validates the presence
of required fields but does not enforce type constraints for the type field. Add
additional validation within _validateRequiredFields to check that the type
value is one of the allowed enum values: ASGARDEO, WSO2IS, KEYCLOAK, or
GENERIC_OIDC. This will ensure type constraints are enforced at the service
layer, protecting against invalid requests that may bypass OpenAPI validation or
access the service through alternative code paths.
portals/developer-portal/src/dao/admin.js (1)

127-134: ⚠️ Potential issue | 🔴 Critical

Fix field name mismatch between organization create and update operations.

createOrganization (line 41) reads orgData.orgConfig, but updateOrganization (line 133) reads orgData.orgConfiguration. Additionally, the update service layer does not populate this field when preparing the payload, causing ORG_CONFIG to be set as undefined when updating an organization. This results in silent data loss of the organization configuration.

Align both functions to use the same field name, and ensure the update service layer constructs the config field in the same manner as the create path.

🤖 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 `@portals/developer-portal/src/dao/admin.js` around lines 127 - 134, The
createOrganization function reads orgData.orgConfig while updateOrganization
reads orgData.orgConfiguration, creating a field name mismatch that causes
ORG_CONFIG to be set as undefined during updates. In the updateOrganization
function, change the ORG_CONFIG field assignment from orgData.orgConfiguration
to orgData.orgConfig to match the createOrganization function. Additionally,
ensure that the update service layer constructs and populates the config field
in the same manner as the create path to prevent silent data loss.
portals/developer-portal/src/utils/sampleApiLoader.js (1)

65-72: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add a stable planID to design-mode plan objects.

Line 65-72 constructs plans without planID, but the subscription card/template now reads planID for DOM IDs and button data attributes. This can produce empty IDs and incorrect subscription button metadata in design mode.

Proposed fix
 const plans = (spec.subscriptionPlans || []).map(p => {
     const plan = plansMap[p];
     return {
+        planID: plan?.planID ?? p,
         planName: p,
         displayName: plan?.displayName ?? p,
         description: plan?.description ?? '',
         requestCount: plan?.requestCount ?? 1000,
     };
 });
🤖 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 `@portals/developer-portal/src/utils/sampleApiLoader.js` around lines 65 - 72,
The plan objects constructed in the map function starting at line 65 are missing
a planID property, which is now required by the subscription card/template for
DOM IDs and button data attributes. Add a planID field to the returned object in
the map function that provides a stable identifier; this can be derived from the
plan key p or the plansMap entry to ensure consistent IDs across renders in
design mode.
🟡 Minor comments (28)
docs/rest-apis/devportal/api-content.md-90-92 (1)

90-92: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the correct field name in validation error examples.

These examples use field: "orgName" while the endpoint path parameter is orgId. Please update the field value to match the documented request shape.

Also applies to: 234-236, 361-363, 467-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 `@docs/rest-apis/devportal/api-content.md` around lines 90 - 92, The validation
error examples in the API documentation are using an incorrect field name. In
all validation error response objects, change the field value from "orgName" to
"orgId" to match the actual endpoint path parameter. Update this field name in
all four locations mentioned: the primary example at lines 90-92 and the
additional instances at lines 234-236, 361-363, and 467-469, ensuring all
validation error examples consistently reference the correct field identifier.
portals/developer-portal/src/utils/util.js-286-287 (1)

286-287: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clamp pagination query values to non-negative bounds.

Line 286-287 accepts negative limit/offset values from query input. Clamp both values to >= 0 (while preserving max limit 100) to keep pagination metadata valid.

Suggested patch
-    const limit = Math.min(parseInt((req.query && req.query.limit) || '20', 10) || 20, 100);
-    const offset = parseInt((req.query && req.query.offset) || '0', 10) || 0;
+    const parsedLimit = Number.parseInt((req.query && req.query.limit) || '20', 10);
+    const parsedOffset = Number.parseInt((req.query && req.query.offset) || '0', 10);
+    const limit = Math.min(Math.max(Number.isNaN(parsedLimit) ? 20 : parsedLimit, 0), 100);
+    const offset = Math.max(Number.isNaN(parsedOffset) ? 0 : parsedOffset, 0);
🤖 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 `@portals/developer-portal/src/utils/util.js` around lines 286 - 287, In the
pagination parsing section where limit and offset variables are declared, apply
Math.max with a minimum value of 0 to both the limit and offset calculations.
For the limit variable, ensure it clamps to a non-negative value while
preserving the existing maximum of 100 using Math.min. For the offset variable,
ensure it clamps to a non-negative minimum value of 0. This will prevent
negative pagination values from being passed through while maintaining the
existing max limit constraint.
portals/developer-portal/src/pages/partials/tech-side-common-banner.hbs-15-15 (1)

15-15: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the banner copy punctuation and sentence style.

Line 15 has a double period and awkward capitalization in a user-facing sentence. Please normalize the copy.

Proposed fix
-          <p>APIs, Applications and Subscription plans are displayed here..</p>
+          <p>APIs, applications, and subscription plans are displayed here.</p>
🤖 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 `@portals/developer-portal/src/pages/partials/tech-side-common-banner.hbs` at
line 15, The paragraph element containing the text "APIs, Applications and
Subscription plans are displayed here.." has two issues that need to be
corrected: first, remove the double period at the end and replace it with a
single period, and second, change the capital "S" in "Subscription" to lowercase
"s" to follow proper sentence capitalization conventions. This will normalize
the user-facing text in the tech-side-common-banner.hbs partial.
docs/rest-apis/devportal/providers.md-122-128 (1)

122-128: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove duplicate status=error rows in enumerated-value tables.

Each of these sections lists the same status | error row twice. Keep a single row per section for clarity.

Also applies to: 259-265, 438-444

🤖 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 `@docs/rest-apis/devportal/providers.md` around lines 122 - 128, The enumerated
value tables in the Enumerated Values sections contain duplicate rows with the
same `status | error` entry. Remove all duplicate rows from these tables,
ensuring that each unique enumerated value appears only once in the Enumerated
Values section. This applies to all three sections mentioned in the comment
where the duplication occurs, so check each Enumerated Values table and
eliminate any repeated rows with identical property and value combinations.
portals/developer-portal/docs/introduction/concepts.md-48-48 (1)

48-48: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the repeated term in the definition sentence.

Line 48 currently repeats the same term (“subscription plan” twice). Replace the parenthetical with the legacy term or remove it to avoid confusion.

🤖 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 `@portals/developer-portal/docs/introduction/concepts.md` at line 48, The
definition of subscription plan in the concepts.md file contains a redundant
repetition where "subscription plan" appears both as the main term and within
the parenthetical explanation. Either remove the parenthetical entirely if it
provides no additional information, or replace it with a legacy term or
alternative name that developers may recognize, such as the term it was
previously called if applicable. This will eliminate confusion and improve the
clarity of the definition.
docs/rest-apis/devportal/organization-content.md-533-533 (1)

533-533: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix heading level progression in the response-schema section.

The heading at Line 533 jumps one level too deep for this section. Align it with the surrounding heading hierarchy.

🤖 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 `@docs/rest-apis/devportal/organization-content.md` at line 533, The
"Enumerated Values" heading in the response-schema section uses four hash marks
(level 4 heading), which breaks the proper heading hierarchy progression. Change
the "#### Enumerated Values" heading to use three hash marks instead (level 3
heading) to align it correctly with the surrounding heading structure in the
document.

Source: Linters/SAST tools

docs/rest-apis/devportal/views.md-124-130 (1)

124-130: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Deduplicate repeated status enum rows in Enumerated Values tables.

The changed sections repeat status | error twice. A single row is sufficient and clearer.

Also applies to: 368-374, 482-488, 586-592

🤖 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 `@docs/rest-apis/devportal/views.md` around lines 124 - 130, The Enumerated
Values tables contain duplicate rows for the status property showing error
twice. Remove the duplicate status | error row from each of the affected
Enumerated Values tables (found at lines 124-130, 368-374, 482-488, and 586-592)
and keep only a single row for each unique enum value. This will make the
documentation clearer and more concise.
docs/rest-apis/devportal/organizations.md-162-168 (1)

162-168: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove duplicated status enum rows in the response-schema tables.

Each Enumerated Values table repeats status | error twice. Keep a single row per property/value pair for clarity and consistency.

Also applies to: 417-421, 598-602

🤖 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 `@docs/rest-apis/devportal/organizations.md` around lines 162 - 168, Remove the
duplicate rows in the Enumerated Values tables throughout the document. The
status property with value error is repeated twice in the table at the specified
location and also at lines 417-421 and 598-602. In each case, delete the
duplicate row so that each property/value pair appears exactly once in the
table. Keep only one entry for status | error in each Enumerated Values table.
docs/rest-apis/devportal/views.md-165-167 (1)

165-167: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the blank line inside the blockquote before the 200 response example.

This section triggers markdownlint MD028; remove the blank quoted line to keep blockquote formatting valid.

🤖 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 `@docs/rest-apis/devportal/views.md` around lines 165 - 167, In the blockquote
section containing "Example responses" and "200 Response", there is a blank
quoted line (a line with only `>`) between these two lines that violates the
MD028 markdownlint rule. Remove the blank quoted line to maintain continuous
blockquote formatting without internal breaks.

Source: Linters/SAST tools

docs/rest-apis/devportal/organization-content.md-132-138 (1)

132-138: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove duplicated status entries from Enumerated Values tables.

Several updated tables list status | error twice. Keep only one row per value.

Also applies to: 268-274, 418-424, 533-538

🤖 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 `@docs/rest-apis/devportal/organization-content.md` around lines 132 - 138,
Remove duplicate rows from the Enumerated Values tables throughout the document.
In each Enumerated Values table, identify and delete any duplicate entries where
the same property-value pair (such as status|error) appears more than once. Keep
only a single instance of each unique value. This issue occurs in multiple
tables throughout the file, so carefully review each Enumerated Values table and
eliminate all duplicate rows while preserving one copy of each unique entry.
portals/developer-portal/src/models/keyManager.js-36-38 (1)

36-38: ⚠️ Potential issue | 🟡 Minor

Confirm: DP_KEY_MANAGER.TYPE lacks value validation across all layers.

The model at lines 36–38 removes enum constraints, and verification shows no alternative validation enforces accepted type values:

  • Request validation (_validateRequiredFields) only checks presence, not value
  • DAO and service layers accept TYPE without constraint
  • No KEY_MANAGER_TYPE or allowable-types definition exists
  • Database schema uses VARCHAR(255) with no enum type

Any string is currently permitted. Establish an authoritative list of valid types and validate in request handling or service logic before persistence.

🤖 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 `@portals/developer-portal/src/models/keyManager.js` around lines 36 - 38, The
TYPE field in the DP_KEY_MANAGER model at lines 36-38 has no enum or value
constraints, and no validation enforces acceptable type values anywhere in the
request handling or service layers. Define an authoritative list of valid
KEY_MANAGER_TYPE values as a constant, then add validation logic to check that
the TYPE value is one of the allowed types in the _validateRequiredFields
function or in the service layer before the TYPE is persisted to ensure only
valid types are accepted.
docs/rest-apis/devportal/applications.md-82-94 (1)

82-94: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align the 200 example with the paginated response schema.

Line 82 documents a { list, pagination } envelope, but the 200 example in this section still shows a top-level array. Please make both shapes consistent.

🤖 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 `@docs/rest-apis/devportal/applications.md` around lines 82 - 94, The 200
example response in this section shows a top-level array, but the schema
documentation (lines 82-94) defines a response envelope with list and pagination
properties. Update the 200 example to wrap the applications array in a list
property and include the pagination object at the top level to match the schema
structure being documented, ensuring the example response body shows { list:
[...], pagination: {...} } format instead of a bare array.
docs/rest-apis/devportal/applications.md-166-183 (1)

166-183: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep one consistent 400 error shape per endpoint section.

These sections introduce the standardized error envelope, but the same endpoint docs still include a legacy message-only 400 example. Please remove or relabel legacy samples to avoid response-contract ambiguity.

Also applies to: 308-325

🤖 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 `@docs/rest-apis/devportal/applications.md` around lines 166 - 183, The
endpoint documentation shows inconsistent error response formats within the same
section: a structured error envelope with a status, code, message, and errors
array, followed by an incomplete legacy format with only status, code, and
message. Remove or clearly relabel the incomplete legacy 400 error example (the
one showing MISSING_REQUIRED_PARAMETER format) to maintain a single consistent
error response shape per endpoint section. Apply the same consolidation to the
other affected areas mentioned in the comment (also at lines 308-325) to ensure
response-contract clarity throughout the documentation.
docs/rest-apis/devportal/key-managers.md-129-146 (1)

129-146: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use one 400 error format consistently in each endpoint section.

These blocks add the standardized envelope, but the same sections still include legacy message-only 400 examples. Please keep a single documented 400 format (or clearly separate alternatives).

Also applies to: 653-670

🤖 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 `@docs/rest-apis/devportal/key-managers.md` around lines 129 - 146, The
documentation contains inconsistent 400 error response formats within the same
endpoint sections, mixing the detailed standardized envelope format with status,
code, message, and errors array against simpler legacy message-only formats.
Choose a single standardized 400 error response format and apply it consistently
throughout each endpoint section in the key-managers.md file. Remove duplicate
or alternative 400 error examples, or if multiple formats are necessary for
different scenarios, clearly separate them with descriptive headers explaining
when each format applies. This issue occurs in multiple locations including the
lines mentioned at 653-670, so audit the entire document for consistency.
docs/rest-apis/devportal/application-keys.md-81-98 (1)

81-98: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Standardize 400 examples consistently across all key endpoints.

These sections adopt the new error envelope, but each endpoint still includes a legacy message-only 400 example in the same block. Please keep a single documented 400 structure (or clearly mark alternatives) to avoid client-side parsing confusion.

Also applies to: 224-241, 437-454, 563-580

🤖 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 `@docs/rest-apis/devportal/application-keys.md` around lines 81 - 98, The
documentation contains inconsistent 400 error response examples across multiple
endpoints in the application-keys.md file. Currently, each endpoint shows both a
new structured error envelope format (with field-level error details) and a
legacy message-only format in the same documentation block, which creates
ambiguity for API clients. Review all 400 error examples at the specified line
ranges (81-98, 224-241, 437-454, 563-580) and standardize them to use a single
consistent error response structure throughout the document. Choose one format
as the canonical response structure and remove or clearly differentiate any
legacy alternatives to ensure clients have clear, unambiguous documentation of
the expected 400 response format.
docs/rest-apis/devportal/labels.md-71-92 (1)

71-92: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Standardize 400 examples across label endpoints.

These sections introduce the new error envelope, but legacy message-only 400 samples remain in the same endpoint blocks. Please keep one consistent 400 response format (or clearly label alternatives).

Also applies to: 225-246, 359-380, 468-486

🤖 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 `@docs/rest-apis/devportal/labels.md` around lines 71 - 92, The 400 error
response examples in the labels endpoint documentation are inconsistent, with
both a structured error envelope format (containing status, code, message, and
errors array) and a legacy message-only format (with just status, code, and
message) appearing in the same sections. Standardize all 400 response examples
across the specified line ranges (71-92, 225-246, 359-380, 468-486) to use a
single consistent format throughout the document. If both formats are needed for
different scenarios, clearly label each variant to indicate which error
condition produces which response structure.
docs/rest-apis/devportal/labels.md-54-67 (1)

54-67: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align endpoint wording with the new response envelope.

The create/upsert examples now return { list, pagination }. Please update nearby operation/response wording so it no longer implies a plain array response.

Also applies to: 208-221

🤖 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 `@docs/rest-apis/devportal/labels.md` around lines 54 - 67, The response
envelope structure has changed to return an object with "list" and "pagination"
fields instead of a plain array. Update the operation and response descriptions
in the documentation to reflect this new structure. Locate the wording that
currently describes the endpoint as returning a plain array and revise it to
indicate the response contains a "list" field with the array of items and a
"pagination" field with metadata. Apply this wording change to both the primary
section (around lines 54-67) and the secondary section (around lines 208-221)
where the response is documented.
portals/developer-portal/src/services/webhooks/subscriberRegistry.js-53-59 (1)

53-59: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid silently swallowing subscriber lookup errors.

Returning null for all exceptions hides operational failures and makes downstream behavior indistinguishable from a true “not found” case. Add error logging (and optionally rethrow non-not-found failures) so delivery issues are diagnosable.

🤖 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 `@portals/developer-portal/src/services/webhooks/subscriberRegistry.js` around
lines 53 - 59, The catch block in the getSubscriber function is silently
swallowing all exceptions and returning null, which masks operational failures
and makes it impossible to distinguish a genuine not-found case from an actual
error. To fix this, add error logging in the catch block to record all
exceptions for debugging purposes. Additionally, check if the caught error is a
not-found error (such as one thrown by whDao.get when the record doesn't exist)
and return null only in that case, while rethrowing any other unexpected errors
so they propagate up and are handled by the caller.
docs/rest-apis/devportal/api-keys.md-297-303 (1)

297-303: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove duplicate heading in the list response section.

Line 297 introduces a second #### Enumerated Values heading in the same section. Rename or merge it to keep the structure unambiguous.

🤖 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 `@docs/rest-apis/devportal/api-keys.md` around lines 297 - 303, The document
contains a duplicate `#### Enumerated Values` heading in the list response
section around line 297. Remove the second occurrence of this heading and
consolidate the enumerated values table content under a single heading to
maintain a clear document structure. Ensure the status values table is organized
under only one properly positioned heading to avoid confusion.

Source: Linters/SAST tools

docs/rest-apis/devportal/subscriptions.md-288-294 (1)

288-294: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Resolve duplicate heading in the response schema section.

Line 288 repeats #### Enumerated Values, which creates duplicate-heading lint noise and makes the section harder to navigate. Rename one heading (for example, “Error Enumerated Values”).

🤖 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 `@docs/rest-apis/devportal/subscriptions.md` around lines 288 - 294, The
markdown document contains duplicate `#### Enumerated Values` headings in the
response schema section around the subscription status error response. Rename
the second occurrence of the `#### Enumerated Values` heading to a more
descriptive name that reflects its context, such as `#### Error Enumerated
Values` or `#### Error Response Enumerated Values`, to eliminate the duplicate
heading and improve section clarity and navigation.

Source: Linters/SAST tools

docs/rest-apis/devportal/webhook-events.md-86-93 (1)

86-93: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use GET-appropriate 403 example messaging.

Lines 92 and 227 describe write-mode restrictions on read endpoints. Please update those 403 examples to permission/scope-oriented wording for the two GET operations.

Also applies to: 225-228

🤖 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 `@docs/rest-apis/devportal/webhook-events.md` around lines 86 - 93, The 403
error response examples at lines 92 and 227 in the webhook-events.md file
contain messaging about write operations being disabled, which is inappropriate
for GET endpoints. Replace the "Write operations are disabled in read-only
mode." message with permission or scope-oriented error messaging that is more
suitable for read operations, such as messages that reference insufficient
permissions or missing required scopes. Apply this same fix to both 403 response
examples mentioned (lines 92 and 225-228) to ensure consistency across all GET
operation documentation.
docs/rest-apis/devportal/webhook-subscribers.md-87-89 (1)

87-89: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align error examples to webhook-subscriber semantics.

Lines 87/88 and 422/423 use orgName validation examples, and Lines 114-116 and 459-461 use organization-conflict examples. These should reflect subscriber-specific fields/codes to avoid client-side confusion.

Also applies to: 114-116, 422-424, 459-461

🤖 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 `@docs/rest-apis/devportal/webhook-subscribers.md` around lines 87 - 89,
Replace the validation error examples at lines 87-88 and 422-423 that use the
orgName field with subscriber-specific field examples (such as name, url, or
events fields that are actually part of webhook subscriber validation).
Additionally, update the organization-conflict error examples at lines 114-116
and 459-461 to use subscriber-conflict specific error codes and messages instead
of organization-level conflict semantics. Ensure all error examples in the
webhook-subscribers documentation accurately reflect the actual fields and error
codes used in the webhook subscriber API to prevent client-side confusion.
portals/developer-portal/src/pages/api-flows/page.hbs-511-513 (1)

511-513: ⚠️ Potential issue | 🟡 Minor

Casing inconsistency across ecosystem is documented but this template path is correctly aligned.

The page.hbs template uses planId (camelCase), and viewConfigureController.js (line 89-96) explicitly maps DAO field PLAN_ID to this key. The subscription plan DAO (line 44) defensively accepts both planId and planID forms. However, the broader codebase exhibits inconsistent naming—some DTOs expose planID (uppercase), and the OpenAPI spec (lines 4214-4219) acknowledges "Alternative casing accepted by the DAO." Audit other callers of subscription plan endpoints to ensure consistent key usage when consuming API 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 `@portals/developer-portal/src/pages/api-flows/page.hbs` around lines 511 -
513, The codebase exhibits inconsistent casing when handling subscription plan
identifiers across different API consumers. While page.hbs correctly uses
camelCase planId aligned with viewConfigureController.js mapping and the
subscription plan DAO defensive handling, other callers of subscription plan
endpoints may be using inconsistent key naming (planID vs planId). Audit all
other consumers of subscription plan API responses throughout the codebase and
ensure they consistently use the same casing convention (planId) when accessing
the plan identifier from API responses, aligning with how
viewConfigureController.js maps the DAO field PLAN_ID.
docs/rest-apis/devportal/utilities.md-110-113 (1)

110-113: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove the duplicated enumerated-value row for status.

The table repeats the same status = error entry twice.

Suggested fix
 |Property|Value|
 |---|---|
 |status|error|
-|status|error|
🤖 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 `@docs/rest-apis/devportal/utilities.md` around lines 110 - 113, The table in
the utilities documentation contains a duplicate row with the same status
property and value. Remove one of the duplicate `|status|error|` rows from the
table so that the enumerated value for the status property appears only once in
the table structure.
portals/developer-portal/src/pages/application/partials/subscriptions.hbs-8-14 (1)

8-14: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove stray template output and close the list markup.

Line 8 renders subscribedPlan.length directly in the card, and the list opened on Line 11 is not closed. This can produce incorrect UI output.

Suggested fix
-        {{subscribedPlan.length}}
         {{`#if` subscribedPlan}}
         <h6 class="dev-header h6">Subscribed Plan:
             <ul class="plan-label">
                 <li>{{subscribedPlan.plan}}</li>
+            </ul>
         </h6>
🤖 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 `@portals/developer-portal/src/pages/application/partials/subscriptions.hbs`
around lines 8 - 14, Remove the stray `{{subscribedPlan.length}}` output that
appears before the if condition check on line 8, as this renders unnecessary
content to the UI. Additionally, add the missing closing `</ul>` tag after the
`<li>{{subscribedPlan.plan}}</li>` list item to properly close the unordered
list with class plan-label that was opened on line 11. This will ensure correct
markup structure and prevent the list content from leaking into subsequent
elements.
portals/developer-portal/docs/administer/subscription-plans.md-3-3 (1)

3-3: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix duplicated wording in the introduction.

Line 3 repeats the same term (“subscription plan … subscription plan”). Please simplify the sentence to avoid confusion.

Proposed fix
-A subscription plan (also called a subscription plan) is a named usage tier that controls how much of an API a developer can consume.
+A subscription plan is a named usage tier that controls how much of an API a developer can consume.
🤖 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 `@portals/developer-portal/docs/administer/subscription-plans.md` at line 3,
The introduction sentence on line 3 contains redundant wording where
"subscription plan" is repeated twice in the phrase "A subscription plan (also
called a subscription plan)". Remove the duplicate parenthetical phrase "also
called a subscription plan" entirely and keep only the definition that follows,
so the sentence simply reads "A subscription plan is a named usage tier..." to
make the introduction clearer and more concise.
docs/rest-apis/devportal/apis.md-177-183 (1)

177-183: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove duplicate status=error entries from enumerated-value tables.

Each section currently repeats the same value twice, which makes the schema tables noisy.

Also applies to: 383-388, 524-530, 704-710, 826-831

🤖 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 `@docs/rest-apis/devportal/apis.md` around lines 177 - 183, Remove the
duplicate enumerated value table entries where the same status value is listed
multiple times. In the Enumerated Values tables (appearing at the specified line
ranges throughout the document), consolidate duplicate rows so that each unique
status value appears only once in the table. For example, when the table shows
status|error listed twice in consecutive rows, delete one of the duplicate rows
to keep only a single entry for that value.
docs/rest-apis/devportal/apis.md-550-550 (1)

550-550: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align status wording with the accepted API status values.

Line 550 says “unpublished,” while the documented status values are CREATED/PUBLISHED. Use the concrete status name to avoid invalid payload assumptions.

🤖 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 `@docs/rest-apis/devportal/apis.md` at line 550, The description on line 550
references "unpublished" as a status value, but this is not a concrete API
status. Replace the word "unpublished" with the actual documented status value
(either `CREATED` or `PUBLISHED`) that cannot be transitioned to when active
subscriptions exist. Use the concrete status name from the accepted API status
values to ensure the documentation accurately reflects valid payload states.
🧹 Nitpick comments (1)
portals/developer-portal/src/services/adminService.js (1)

158-163: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Make the default-subscription-plan success log conditional.

Line 162 currently reports success even when config.generateDefaultSubPlans is disabled. This can mislead operational troubleshooting.

Suggested patch
-            if (config.generateDefaultSubPlans) {
-                await subscriptionPlanDao.createMany(orgId, constants.DEFAULT_SUBSCRIPTION_PLANS, t);
-            }
-            logger.info('Default subscription plans created successfully', {
-                orgId
-            });
+            if (config.generateDefaultSubPlans) {
+                await subscriptionPlanDao.createMany(orgId, constants.DEFAULT_SUBSCRIPTION_PLANS, t);
+                logger.info('Default subscription plans created successfully', { orgId });
+            } else {
+                logger.info('Default subscription plans creation skipped by configuration', { orgId });
+            }
🤖 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 `@portals/developer-portal/src/services/adminService.js` around lines 158 -
163, The logger.info call that reports successful creation of default
subscription plans is currently outside the conditional block that checks
config.generateDefaultSubPlans, causing it to log success even when the plans
are not created. Move the logger.info statement inside the if block that
contains the subscriptionPlanDao.createMany call so the success message is only
logged when the plans are actually created.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f7e1bc97-d85b-4c5a-a84f-0fc0840707d6

📥 Commits

Reviewing files that changed from the base of the PR and between 0e607e3 and d6cbd3d.

⛔ Files ignored due to path filters (1)
  • portals/developer-portal/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (121)
  • docs/rest-apis/devportal/README.md
  • docs/rest-apis/devportal/api-content.md
  • docs/rest-apis/devportal/api-flows.md
  • docs/rest-apis/devportal/api-keys.md
  • docs/rest-apis/devportal/apis.md
  • docs/rest-apis/devportal/application-keys.md
  • docs/rest-apis/devportal/applications.md
  • docs/rest-apis/devportal/key-managers.md
  • docs/rest-apis/devportal/labels.md
  • docs/rest-apis/devportal/organization-content.md
  • docs/rest-apis/devportal/organizations.md
  • docs/rest-apis/devportal/providers.md
  • docs/rest-apis/devportal/schemas.md
  • docs/rest-apis/devportal/subscription-plans.md
  • docs/rest-apis/devportal/subscriptions.md
  • docs/rest-apis/devportal/utilities.md
  • docs/rest-apis/devportal/views.md
  • docs/rest-apis/devportal/webhook-events.md
  • docs/rest-apis/devportal/webhook-subscribers.md
  • portals/developer-portal/README.md
  • portals/developer-portal/configs/config-platform-api.toml.example
  • portals/developer-portal/database/queries/search-apis.postgres.sql
  • portals/developer-portal/database/schema.postgres.sql
  • portals/developer-portal/distribution/docker-compose.yaml
  • portals/developer-portal/docker-compose.yaml
  • portals/developer-portal/docs/administer/design-mode.md
  • portals/developer-portal/docs/administer/gateway-integration.md
  • portals/developer-portal/docs/administer/subscription-plans.md
  • portals/developer-portal/docs/devportal-openapi-spec-v1.yaml
  • portals/developer-portal/docs/introduction/concepts.md
  • portals/developer-portal/docs/introduction/quick-start.md
  • portals/developer-portal/docs/publish-apis/publishing-apis.md
  • portals/developer-portal/it/docker-compose.test.postgres.yaml
  • portals/developer-portal/it/docker-compose.test.yaml
  • portals/developer-portal/production/scripts/register_asgardeo_scopes.sh
  • portals/developer-portal/samples/apis-backup/BookingAPI/api.yaml
  • portals/developer-portal/samples/apis-backup/CatalogAPI/api.yaml
  • portals/developer-portal/samples/apis-backup/PingAPI/api.yaml
  • portals/developer-portal/samples/apis/booking-api/api.yaml
  • portals/developer-portal/samples/apis/catalog-api/api.yaml
  • portals/developer-portal/samples/apis/countries-graphql-v1.0/api.yaml
  • portals/developer-portal/samples/apis/leisure-soap-v1.0/api.yaml
  • portals/developer-portal/samples/apis/navigation-ws-v1.0/api.yaml
  • portals/developer-portal/samples/apis/ping-api/api.yaml
  • portals/developer-portal/samples/apis/swagger-petstore-v1.0.7/api.yaml
  • portals/developer-portal/samples/mcps/travel-assistant-mcp-v1/api.yaml
  • portals/developer-portal/samples/subscriptionPlans.yaml
  • portals/developer-portal/scripts/drift_check.js
  • portals/developer-portal/src/adapters/keyManager/index.js
  • portals/developer-portal/src/config/configLoader.js
  • portals/developer-portal/src/controllers/apiContentController.js
  • portals/developer-portal/src/controllers/apiKeyController.js
  • portals/developer-portal/src/controllers/devportalController.js
  • portals/developer-portal/src/controllers/subscriptionsContentController.js
  • portals/developer-portal/src/controllers/viewConfigureController.js
  • portals/developer-portal/src/controllers/webhookAdminController.js
  • portals/developer-portal/src/dao/admin.js
  • portals/developer-portal/src/dao/apiDao.js
  • portals/developer-portal/src/dao/apiImageDao.js
  • portals/developer-portal/src/dao/keyManagerDao.js
  • portals/developer-portal/src/dao/organizationDao.js
  • portals/developer-portal/src/dao/subscriptionDao.js
  • portals/developer-portal/src/dao/subscriptionPlanDao.js
  • portals/developer-portal/src/dao/webhookSubscriberDao.js
  • portals/developer-portal/src/db/betterSqlite3Compat.js
  • portals/developer-portal/src/defaultContent/pages/api-landing/partials/api-subscription-plans.hbs
  • portals/developer-portal/src/defaultContent/pages/apis/partials/api-listing.hbs
  • portals/developer-portal/src/defaultContent/pages/apis/partials/subscription-modal.hbs
  • portals/developer-portal/src/defaultContent/pages/mcp/partials/mcp-listing.hbs
  • portals/developer-portal/src/dto/apiDto.js
  • portals/developer-portal/src/dto/applicationDto.js
  • portals/developer-portal/src/dto/subscriptionPlanDto.js
  • portals/developer-portal/src/dto/webhookSubscriberDto.js
  • portals/developer-portal/src/helpers/handlebarsHelpers.js
  • portals/developer-portal/src/middlewares/ensureAuthenticated.js
  • portals/developer-portal/src/models/apiImage.js
  • portals/developer-portal/src/models/apiKey.js
  • portals/developer-portal/src/models/apiMetadata.js
  • portals/developer-portal/src/models/apiSubscriptionPlan.js
  • portals/developer-portal/src/models/application.js
  • portals/developer-portal/src/models/event.js
  • portals/developer-portal/src/models/eventDelivery.js
  • portals/developer-portal/src/models/keyManager.js
  • portals/developer-portal/src/models/label.js
  • portals/developer-portal/src/models/organization.js
  • portals/developer-portal/src/models/provider.js
  • portals/developer-portal/src/models/subscriptionPlan.js
  • portals/developer-portal/src/models/view.js
  • portals/developer-portal/src/models/viewLabel.js
  • portals/developer-portal/src/models/webhookSubscriber.js
  • portals/developer-portal/src/pages/api-flows/page.hbs
  • portals/developer-portal/src/pages/application/partials/apis.hbs
  • portals/developer-portal/src/pages/application/partials/application-modal.hbs
  • portals/developer-portal/src/pages/application/partials/subscriptions.hbs
  • portals/developer-portal/src/pages/partials/tech-side-common-banner.hbs
  • portals/developer-portal/src/routes/api/handlers/keyManagersHandler.js
  • portals/developer-portal/src/routes/api/handlers/subscriptionPlansHandler.js
  • portals/developer-portal/src/routes/api/handlers/webhookSubscribersHandler.js
  • portals/developer-portal/src/scripts/api-key-generation.js
  • portals/developer-portal/src/scripts/oauth2-key-generation.js
  • portals/developer-portal/src/scripts/subscription-modal.js
  • portals/developer-portal/src/scripts/subscription.js
  • portals/developer-portal/src/services/adminService.js
  • portals/developer-portal/src/services/apiFlowService.js
  • portals/developer-portal/src/services/apiKeyService.js
  • portals/developer-portal/src/services/apiMetadataService.js
  • portals/developer-portal/src/services/devportalService.js
  • portals/developer-portal/src/services/keyManagerService.js
  • portals/developer-portal/src/services/sampleSeederService.js
  • portals/developer-portal/src/services/seederService.js
  • portals/developer-portal/src/services/subscriptionService.js
  • portals/developer-portal/src/services/webhookSubscriberService.js
  • portals/developer-portal/src/services/webhooks/deliveryWorker.js
  • portals/developer-portal/src/services/webhooks/dispatcher.js
  • portals/developer-portal/src/services/webhooks/eventPublisher.js
  • portals/developer-portal/src/services/webhooks/subscriberRegistry.js
  • portals/developer-portal/src/styles/application.css
  • portals/developer-portal/src/styles/settings-layout.css
  • portals/developer-portal/src/utils/constants.js
  • portals/developer-portal/src/utils/sampleApiLoader.js
  • portals/developer-portal/src/utils/util.js
💤 Files with no reviewable changes (4)
  • portals/developer-portal/src/services/devportalService.js
  • portals/developer-portal/src/config/configLoader.js
  • portals/developer-portal/src/middlewares/ensureAuthenticated.js
  • portals/developer-portal/src/dao/organizationDao.js

Comment thread docs/rest-apis/devportal/api-content.md
Comment thread docs/rest-apis/devportal/key-managers.md Outdated
Comment thread docs/rest-apis/devportal/subscription-plans.md Outdated
Comment thread docs/rest-apis/devportal/webhook-subscribers.md Outdated
Comment thread portals/developer-portal/configs/config-platform-api.toml.example Outdated
Comment thread portals/developer-portal/src/services/apiMetadataService.js
Comment thread portals/developer-portal/src/services/apiMetadataService.js
Comment thread portals/developer-portal/src/services/webhooks/dispatcher.js Outdated
Comment thread portals/developer-portal/src/services/webhookSubscriberService.js
Comment thread portals/developer-portal/src/utils/util.js Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
docs/rest-apis/devportal/applications.md (2)

241-246: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix duplicate enumerated values in response schema tables.

The Enumerated Values sections for POST (lines 245–246) and PUT (lines 399–400) both list status|error twice. Each value should appear only once in the enumeration table.

Suggested fix

Replace duplicate entries with a single entry:

|Property|Value|
|---|---|
|status|error|

Also applies to: 395-400

🤖 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 `@docs/rest-apis/devportal/applications.md` around lines 241 - 246, Remove
duplicate enumerated values from the API documentation schema tables. In both
the POST and PUT endpoint Enumerated Values sections, the entry status|error is
listed twice. Delete the duplicate row in each table so that each enumerated
value appears only once, keeping a single status|error entry in each Enumerated
Values table.

204-208: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove non-standardized error response examples.

Lines 204–208 and 347–351 show error payloads that do not follow the standardized { status: "error", code, message } envelope established elsewhere in this document. These examples should either be removed or updated to use the standard error format for consistency with the API contract.

Suggested fix

Remove the non-standardized examples:

  • Lines 204–208 (POST 400 response)
  • Lines 347–351 (PUT 400 response)

Or update them to use the standardized format:

{
  "status": "error",
  "code": "INVALID_PAYLOAD",
  "message": "Missing or invalid fields in the request payload"
}

Also applies to: 347-351

🤖 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 `@docs/rest-apis/devportal/applications.md` around lines 204 - 208, The error
response examples for the POST 400 and PUT 400 responses in the applications.md
documentation contain non-standardized JSON payloads that only include a message
field, which is inconsistent with the standardized error envelope format
established elsewhere in the document. Update both of these error response
examples to follow the standard format by adding a status field set to error and
a code field with an appropriate error code such as INVALID_PAYLOAD to ensure
consistency with the established API contract.
portals/developer-portal/src/dao/apiFileDao.js (1)

79-98: 🗄️ Data Integrity & Integration | 🟠 Major

Ensure update operations run inside the intended transaction.

APIContent.update calls at lines 79-98 and 224-244 have transaction placement issues:

  • Lines 79-98: Missing transaction: t entirely in the options object.
  • Lines 224-244: Transaction passed as a third argument; Sequelize requires it inside the options object.

Both patterns break atomicity when mixed with other transactional writes. Move transaction: t into the second argument's options object for both calls.

Suggested fix
@@
-                const updateResponse = await APIContent.update(
-                    {
-                        FILE_CONTENT: file.content,
-                    },
-                    {
-                        where: {
-                            API_ID: apiID,
-                            FILE_NAME: apiFileResponse.FILE_NAME,
-                            TYPE: file.type,
-                        },
-                        include: [
-                            {
-                                model: APIMetadata,
-                                where: {
-                                    ORG_ID: orgID
-                                }
-                            }
-                        ]
-                    }
-                );
+                const updateResponse = await APIContent.update(
+                    {
+                        FILE_CONTENT: file.content,
+                    },
+                    {
+                        where: {
+                            API_ID: apiID,
+                            FILE_NAME: apiFileResponse.FILE_NAME,
+                            TYPE: file.type,
+                        },
+                        include: [
+                            {
+                                model: APIMetadata,
+                                where: {
+                                    ORG_ID: orgID
+                                }
+                            }
+                        ],
+                        transaction: t
+                    }
+                );
@@
-            fileUpdateResponse = await APIContent.update({
-                FILE_CONTENT: apiFile,
-                FILE_NAME: fileName
-            },
-                {
-                    where: {
-                        API_ID: apiID,
-                        FILE_NAME: fileName,
-                        TYPE: type
-                    },
-                    include: [
-                        {
-                            model: APIMetadata,
-                            where: {
-                                ORG_ID: orgID
-                            }
-                        }
-                    ]
-                },
-                { transaction: t }
-            );
+            fileUpdateResponse = await APIContent.update({
+                FILE_CONTENT: apiFile,
+                FILE_NAME: fileName
+            },
+                {
+                    where: {
+                        API_ID: apiID,
+                        FILE_NAME: fileName,
+                        TYPE: type
+                    },
+                    include: [
+                        {
+                            model: APIMetadata,
+                            where: {
+                                ORG_ID: orgID
+                            }
+                        }
+                    ],
+                    transaction: t
+                }
+            );
🤖 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 `@portals/developer-portal/src/dao/apiFileDao.js` around lines 79 - 98, The
APIContent.update calls are not properly using transactions for atomicity. In
the update call at lines 79-98, the transaction parameter is missing entirely
from the options object (the second argument). Additionally, there is another
APIContent.update call around lines 224-244 where the transaction is incorrectly
passed as a third argument instead of being included in the options object. To
fix both issues, add transaction: t as a property within the second argument
(options object) of both APIContent.update calls, ensuring the transaction
parameter is placed alongside where, include, and other options rather than as a
separate argument or omitted entirely.
portals/developer-portal/src/models/apiMetadata.js (1)

39-43: 🗄️ Data Integrity & Integration | 🟡 Minor

STATUS is non-null ENUM without a model default; ensure all code paths supply a valid value.

STATUS is defined as non-null ENUM with no defaultValue in the model. Code paths that parse YAML (including artifact zips and sample seeding) apply a default of 'PUBLISHED' via parseApiMetadataFromYamlFile. However, the direct JSON.parse path (JSON.parse(req.body.apiMetadata)) does not apply a default; if apiStatus is omitted from the JSON payload, it will reach the database as undefined and fail the NOT NULL constraint. Ensure the JSON parsing path validates that apiStatus is present and valid before passing to the DAO, or apply a default consistently across all entry points.

🤖 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 `@portals/developer-portal/src/models/apiMetadata.js` around lines 39 - 43, The
STATUS ENUM field in the apiMetadata model has no defaultValue, and while the
YAML parsing path through parseApiMetadataFromYamlFile applies a default of
'PUBLISHED', the direct JSON.parse(req.body.apiMetadata) code path does not.
This means if apiStatus is omitted from a JSON payload, it will reach the
database as undefined and violate the NOT NULL constraint. Ensure the JSON
parsing code path either validates that apiStatus is present and valid before
passing to the DAO, or applies a consistent default value of 'PUBLISHED'
(matching the YAML parsing behavior) to handle the omitted field case.
🤖 Prompt for all review comments with 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.

Inline comments:
In `@docs/rest-apis/devportal/schemas.md`:
- Line 825: The heading "### Properties" on line 825 is duplicated elsewhere in
the document, violating markdownlint rule MD024. Rename this heading to include
a unique identifier, such as "### ApplicationKeyMappingSummary Properties", to
make it distinct from other Properties headings in the document and resolve the
lint error.

In `@portals/developer-portal/configs/config.yaml.example`:
- Around line 208-214: The subscriptionPlansPath configuration in the designMode
example section does not match the actual sample filename in the repository.
Update the subscriptionPlansPath value from its current kebab-case name
(subscription-plans.yaml) to the actual camelCase filename
(subscriptionPlans.yaml) used in the samples directory to ensure the example
configuration matches the real file that exists in the repo.

---

Outside diff comments:
In `@docs/rest-apis/devportal/applications.md`:
- Around line 241-246: Remove duplicate enumerated values from the API
documentation schema tables. In both the POST and PUT endpoint Enumerated Values
sections, the entry status|error is listed twice. Delete the duplicate row in
each table so that each enumerated value appears only once, keeping a single
status|error entry in each Enumerated Values table.
- Around line 204-208: The error response examples for the POST 400 and PUT 400
responses in the applications.md documentation contain non-standardized JSON
payloads that only include a message field, which is inconsistent with the
standardized error envelope format established elsewhere in the document. Update
both of these error response examples to follow the standard format by adding a
status field set to error and a code field with an appropriate error code such
as INVALID_PAYLOAD to ensure consistency with the established API contract.

In `@portals/developer-portal/src/dao/apiFileDao.js`:
- Around line 79-98: The APIContent.update calls are not properly using
transactions for atomicity. In the update call at lines 79-98, the transaction
parameter is missing entirely from the options object (the second argument).
Additionally, there is another APIContent.update call around lines 224-244 where
the transaction is incorrectly passed as a third argument instead of being
included in the options object. To fix both issues, add transaction: t as a
property within the second argument (options object) of both APIContent.update
calls, ensuring the transaction parameter is placed alongside where, include,
and other options rather than as a separate argument or omitted entirely.

In `@portals/developer-portal/src/models/apiMetadata.js`:
- Around line 39-43: The STATUS ENUM field in the apiMetadata model has no
defaultValue, and while the YAML parsing path through
parseApiMetadataFromYamlFile applies a default of 'PUBLISHED', the direct
JSON.parse(req.body.apiMetadata) code path does not. This means if apiStatus is
omitted from a JSON payload, it will reach the database as undefined and violate
the NOT NULL constraint. Ensure the JSON parsing code path either validates that
apiStatus is present and valid before passing to the DAO, or applies a
consistent default value of 'PUBLISHED' (matching the YAML parsing behavior) to
handle the omitted field case.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c89c8a6a-d213-4fa0-bf99-24423cb75ba3

📥 Commits

Reviewing files that changed from the base of the PR and between d6cbd3d and 5d89908.

📒 Files selected for processing (29)
  • docs/rest-apis/devportal/api-keys.md
  • docs/rest-apis/devportal/apis.md
  • docs/rest-apis/devportal/applications.md
  • docs/rest-apis/devportal/schemas.md
  • docs/rest-apis/devportal/subscription-plans.md
  • portals/developer-portal/configs/config.yaml.example
  • portals/developer-portal/database/schema.postgres.sql
  • portals/developer-portal/docs/devportal-openapi-spec-v1.yaml
  • portals/developer-portal/production/scripts/register_asgardeo_scopes.sh
  • portals/developer-portal/samples/apis/booking-api/api.yaml
  • portals/developer-portal/samples/apis/ping-api/api.yaml
  • portals/developer-portal/src/controllers/apiContentController.js
  • portals/developer-portal/src/controllers/apiKeysPageController.js
  • portals/developer-portal/src/controllers/subscriptionsContentController.js
  • portals/developer-portal/src/dao/apiDao.js
  • portals/developer-portal/src/dao/apiFileDao.js
  • portals/developer-portal/src/defaultContent/partials/sidebar.hbs
  • portals/developer-portal/src/dto/apiDto.js
  • portals/developer-portal/src/helpers/handlebarsHelpers.js
  • portals/developer-portal/src/middlewares/ensureAuthenticated.js
  • portals/developer-portal/src/middlewares/passportConfig.js
  • portals/developer-portal/src/middlewares/registerPartials.js
  • portals/developer-portal/src/models/apiContent.js
  • portals/developer-portal/src/models/apiMetadata.js
  • portals/developer-portal/src/services/apiMetadataService.js
  • portals/developer-portal/src/services/mcpRegistryService.js
  • portals/developer-portal/src/utils/constants.js
  • portals/developer-portal/src/utils/sampleApiLoader.js
  • portals/developer-portal/src/utils/util.js
💤 Files with no reviewable changes (6)
  • portals/developer-portal/src/helpers/handlebarsHelpers.js
  • portals/developer-portal/src/utils/util.js
  • portals/developer-portal/src/utils/constants.js
  • portals/developer-portal/src/utils/sampleApiLoader.js
  • portals/developer-portal/src/dto/apiDto.js
  • docs/rest-apis/devportal/api-keys.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • portals/developer-portal/src/controllers/subscriptionsContentController.js
  • portals/developer-portal/src/services/apiMetadataService.js
  • docs/rest-apis/devportal/subscription-plans.md
  • portals/developer-portal/database/schema.postgres.sql

Comment thread docs/rest-apis/devportal/schemas.md
Comment thread portals/developer-portal/configs/config.yaml.example
@Piumal1999

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/rest-apis/devportal/applications.md (1)

180-208: 🎯 Functional Correctness | 🟠 Major

Update 400 response examples to match actual handler behavior.

The documented 400 response formats do not match the actual implementation. The handlers use util.handleError() which returns a single error object with format {status: 'error', code: 'COMMON_VALIDATION_ERROR', message: 'Bad Request', errors: [{message}]}. Remove the array format example, the MISSING_REQUIRED_PARAMETER code example, and the legacy format example. Update to show only the format actually returned by the error handler.

🤖 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 `@docs/rest-apis/devportal/applications.md` around lines 180 - 208, The 400
response examples in the applications.md documentation include three different
error response formats that do not match the actual implementation behavior of
util.handleError(). Remove the array-wrapped error object example, the
MISSING_REQUIRED_PARAMETER code example, and the legacy single-message format
example. Replace all three with a single example showing the actual error
response format that util.handleError() returns, which is a single error object
with the structure {status: 'error', code: 'COMMON_VALIDATION_ERROR', message:
'Bad Request', errors: [{message}]}.
🤖 Prompt for all review comments with 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.

Outside diff comments:
In `@docs/rest-apis/devportal/applications.md`:
- Around line 180-208: The 400 response examples in the applications.md
documentation include three different error response formats that do not match
the actual implementation behavior of util.handleError(). Remove the
array-wrapped error object example, the MISSING_REQUIRED_PARAMETER code example,
and the legacy single-message format example. Replace all three with a single
example showing the actual error response format that util.handleError()
returns, which is a single error object with the structure {status: 'error',
code: 'COMMON_VALIDATION_ERROR', message: 'Bad Request', errors: [{message}]}.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b8ea2c19-a965-418f-a214-222ee6b609c0

📥 Commits

Reviewing files that changed from the base of the PR and between 7c27961 and 1daf3a1.

📒 Files selected for processing (18)
  • docs/rest-apis/devportal/api-content.md
  • docs/rest-apis/devportal/apis.md
  • docs/rest-apis/devportal/application-keys.md
  • docs/rest-apis/devportal/applications.md
  • docs/rest-apis/devportal/key-managers.md
  • docs/rest-apis/devportal/labels.md
  • docs/rest-apis/devportal/organization-content.md
  • docs/rest-apis/devportal/organizations.md
  • docs/rest-apis/devportal/providers.md
  • docs/rest-apis/devportal/schemas.md
  • docs/rest-apis/devportal/subscription-plans.md
  • docs/rest-apis/devportal/views.md
  • docs/rest-apis/devportal/webhook-subscribers.md
  • portals/developer-portal/configs/config-platform-api.toml.example
  • portals/developer-portal/docs/devportal-openapi-spec-v1.yaml
  • portals/developer-portal/samples/subscription-plans.yaml
  • portals/developer-portal/src/scripts/oauth2-key-generation.js
  • portals/developer-portal/src/services/apiMetadataService.js
💤 Files with no reviewable changes (1)
  • portals/developer-portal/samples/subscription-plans.yaml
✅ Files skipped from review due to trivial changes (2)
  • docs/rest-apis/devportal/webhook-subscribers.md
  • docs/rest-apis/devportal/application-keys.md
🚧 Files skipped from review as they are similar to previous changes (11)
  • portals/developer-portal/configs/config-platform-api.toml.example
  • portals/developer-portal/src/scripts/oauth2-key-generation.js
  • docs/rest-apis/devportal/labels.md
  • docs/rest-apis/devportal/api-content.md
  • docs/rest-apis/devportal/views.md
  • docs/rest-apis/devportal/subscription-plans.md
  • docs/rest-apis/devportal/organizations.md
  • docs/rest-apis/devportal/apis.md
  • docs/rest-apis/devportal/organization-content.md
  • portals/developer-portal/src/services/apiMetadataService.js
  • docs/rest-apis/devportal/schemas.md

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