[Devportal] Improve the db schemas and rest apis#2249
Conversation
📝 WalkthroughWalkthroughThis 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 Suggested reviewers
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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 | 🟠 MajorAdd uniqueness constraint or validation to prevent duplicate organization assets with null
VIEW_ID.The unique index
UQ_ORGANIZATION_ASSETS_TYPE_NAME_PATH_ORG_VIEWincludesVIEW_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 winUse 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 | 🟡 MinorType 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
KeyManagerRequestandKeyManagerResponseSchemadefinitions indevportal-openapi-spec-v1.yamlenforce an enum constraint:[ASGARDEO, WSO2IS, KEYCLOAK, GENERIC_OIDC]. However, no CHECK constraint or ENUM type exists at the database level, and the Sequelize model usesDataTypes.STRINGwithout 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 | 🔴 CriticalFix field name mismatch between organization create and update operations.
createOrganization(line 41) readsorgData.orgConfig, butupdateOrganization(line 133) readsorgData.orgConfiguration. Additionally, the update service layer does not populate this field when preparing the payload, causingORG_CONFIGto be set asundefinedwhen 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 winAdd a stable
planIDto design-mode plan objects.Line 65-72 constructs plans without
planID, but the subscription card/template now readsplanIDfor 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 winUse the correct field name in validation error examples.
These examples use
field: "orgName"while the endpoint path parameter isorgId. 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 winClamp pagination query values to non-negative bounds.
Line 286-287 accepts negative
limit/offsetvalues 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 winFix 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 winRemove duplicate
status=errorrows in enumerated-value tables.Each of these sections lists the same
status | errorrow 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 winFix 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 winFix 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 winDeduplicate repeated
statusenum rows in Enumerated Values tables.The changed sections repeat
status | errortwice. 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 winRemove duplicated
statusenum rows in the response-schema tables.Each Enumerated Values table repeats
status | errortwice. 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 winFix 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 winRemove duplicated
statusentries from Enumerated Values tables.Several updated tables list
status | errortwice. 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 | 🟡 MinorConfirm:
DP_KEY_MANAGER.TYPElacks 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_TYPEor allowable-types definition exists- Database schema uses
VARCHAR(255)with no enum typeAny 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 winAlign 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 winKeep 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 winUse 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 winStandardize 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 winStandardize 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 winAlign 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 winAvoid silently swallowing subscriber lookup errors.
Returning
nullfor 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 winRemove duplicate heading in the list response section.
Line 297 introduces a second
#### Enumerated Valuesheading 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 winResolve 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 winUse 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 winAlign error examples to webhook-subscriber semantics.
Lines 87/88 and 422/423 use
orgNamevalidation 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 | 🟡 MinorCasing inconsistency across ecosystem is documented but this template path is correctly aligned.
The page.hbs template uses
planId(camelCase), andviewConfigureController.js(line 89-96) explicitly maps DAO fieldPLAN_IDto this key. The subscription plan DAO (line 44) defensively accepts bothplanIdandplanIDforms. However, the broader codebase exhibits inconsistent naming—some DTOs exposeplanID(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 winRemove the duplicated enumerated-value row for
status.The table repeats the same
status = errorentry 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 winRemove stray template output and close the list markup.
Line 8 renders
subscribedPlan.lengthdirectly 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 winFix 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 winRemove duplicate
status=errorentries 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 winAlign 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 winMake the default-subscription-plan success log conditional.
Line 162 currently reports success even when
config.generateDefaultSubPlansis 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
⛔ Files ignored due to path filters (1)
portals/developer-portal/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (121)
docs/rest-apis/devportal/README.mddocs/rest-apis/devportal/api-content.mddocs/rest-apis/devportal/api-flows.mddocs/rest-apis/devportal/api-keys.mddocs/rest-apis/devportal/apis.mddocs/rest-apis/devportal/application-keys.mddocs/rest-apis/devportal/applications.mddocs/rest-apis/devportal/key-managers.mddocs/rest-apis/devportal/labels.mddocs/rest-apis/devportal/organization-content.mddocs/rest-apis/devportal/organizations.mddocs/rest-apis/devportal/providers.mddocs/rest-apis/devportal/schemas.mddocs/rest-apis/devportal/subscription-plans.mddocs/rest-apis/devportal/subscriptions.mddocs/rest-apis/devportal/utilities.mddocs/rest-apis/devportal/views.mddocs/rest-apis/devportal/webhook-events.mddocs/rest-apis/devportal/webhook-subscribers.mdportals/developer-portal/README.mdportals/developer-portal/configs/config-platform-api.toml.exampleportals/developer-portal/database/queries/search-apis.postgres.sqlportals/developer-portal/database/schema.postgres.sqlportals/developer-portal/distribution/docker-compose.yamlportals/developer-portal/docker-compose.yamlportals/developer-portal/docs/administer/design-mode.mdportals/developer-portal/docs/administer/gateway-integration.mdportals/developer-portal/docs/administer/subscription-plans.mdportals/developer-portal/docs/devportal-openapi-spec-v1.yamlportals/developer-portal/docs/introduction/concepts.mdportals/developer-portal/docs/introduction/quick-start.mdportals/developer-portal/docs/publish-apis/publishing-apis.mdportals/developer-portal/it/docker-compose.test.postgres.yamlportals/developer-portal/it/docker-compose.test.yamlportals/developer-portal/production/scripts/register_asgardeo_scopes.shportals/developer-portal/samples/apis-backup/BookingAPI/api.yamlportals/developer-portal/samples/apis-backup/CatalogAPI/api.yamlportals/developer-portal/samples/apis-backup/PingAPI/api.yamlportals/developer-portal/samples/apis/booking-api/api.yamlportals/developer-portal/samples/apis/catalog-api/api.yamlportals/developer-portal/samples/apis/countries-graphql-v1.0/api.yamlportals/developer-portal/samples/apis/leisure-soap-v1.0/api.yamlportals/developer-portal/samples/apis/navigation-ws-v1.0/api.yamlportals/developer-portal/samples/apis/ping-api/api.yamlportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/api.yamlportals/developer-portal/samples/mcps/travel-assistant-mcp-v1/api.yamlportals/developer-portal/samples/subscriptionPlans.yamlportals/developer-portal/scripts/drift_check.jsportals/developer-portal/src/adapters/keyManager/index.jsportals/developer-portal/src/config/configLoader.jsportals/developer-portal/src/controllers/apiContentController.jsportals/developer-portal/src/controllers/apiKeyController.jsportals/developer-portal/src/controllers/devportalController.jsportals/developer-portal/src/controllers/subscriptionsContentController.jsportals/developer-portal/src/controllers/viewConfigureController.jsportals/developer-portal/src/controllers/webhookAdminController.jsportals/developer-portal/src/dao/admin.jsportals/developer-portal/src/dao/apiDao.jsportals/developer-portal/src/dao/apiImageDao.jsportals/developer-portal/src/dao/keyManagerDao.jsportals/developer-portal/src/dao/organizationDao.jsportals/developer-portal/src/dao/subscriptionDao.jsportals/developer-portal/src/dao/subscriptionPlanDao.jsportals/developer-portal/src/dao/webhookSubscriberDao.jsportals/developer-portal/src/db/betterSqlite3Compat.jsportals/developer-portal/src/defaultContent/pages/api-landing/partials/api-subscription-plans.hbsportals/developer-portal/src/defaultContent/pages/apis/partials/api-listing.hbsportals/developer-portal/src/defaultContent/pages/apis/partials/subscription-modal.hbsportals/developer-portal/src/defaultContent/pages/mcp/partials/mcp-listing.hbsportals/developer-portal/src/dto/apiDto.jsportals/developer-portal/src/dto/applicationDto.jsportals/developer-portal/src/dto/subscriptionPlanDto.jsportals/developer-portal/src/dto/webhookSubscriberDto.jsportals/developer-portal/src/helpers/handlebarsHelpers.jsportals/developer-portal/src/middlewares/ensureAuthenticated.jsportals/developer-portal/src/models/apiImage.jsportals/developer-portal/src/models/apiKey.jsportals/developer-portal/src/models/apiMetadata.jsportals/developer-portal/src/models/apiSubscriptionPlan.jsportals/developer-portal/src/models/application.jsportals/developer-portal/src/models/event.jsportals/developer-portal/src/models/eventDelivery.jsportals/developer-portal/src/models/keyManager.jsportals/developer-portal/src/models/label.jsportals/developer-portal/src/models/organization.jsportals/developer-portal/src/models/provider.jsportals/developer-portal/src/models/subscriptionPlan.jsportals/developer-portal/src/models/view.jsportals/developer-portal/src/models/viewLabel.jsportals/developer-portal/src/models/webhookSubscriber.jsportals/developer-portal/src/pages/api-flows/page.hbsportals/developer-portal/src/pages/application/partials/apis.hbsportals/developer-portal/src/pages/application/partials/application-modal.hbsportals/developer-portal/src/pages/application/partials/subscriptions.hbsportals/developer-portal/src/pages/partials/tech-side-common-banner.hbsportals/developer-portal/src/routes/api/handlers/keyManagersHandler.jsportals/developer-portal/src/routes/api/handlers/subscriptionPlansHandler.jsportals/developer-portal/src/routes/api/handlers/webhookSubscribersHandler.jsportals/developer-portal/src/scripts/api-key-generation.jsportals/developer-portal/src/scripts/oauth2-key-generation.jsportals/developer-portal/src/scripts/subscription-modal.jsportals/developer-portal/src/scripts/subscription.jsportals/developer-portal/src/services/adminService.jsportals/developer-portal/src/services/apiFlowService.jsportals/developer-portal/src/services/apiKeyService.jsportals/developer-portal/src/services/apiMetadataService.jsportals/developer-portal/src/services/devportalService.jsportals/developer-portal/src/services/keyManagerService.jsportals/developer-portal/src/services/sampleSeederService.jsportals/developer-portal/src/services/seederService.jsportals/developer-portal/src/services/subscriptionService.jsportals/developer-portal/src/services/webhookSubscriberService.jsportals/developer-portal/src/services/webhooks/deliveryWorker.jsportals/developer-portal/src/services/webhooks/dispatcher.jsportals/developer-portal/src/services/webhooks/eventPublisher.jsportals/developer-portal/src/services/webhooks/subscriberRegistry.jsportals/developer-portal/src/styles/application.cssportals/developer-portal/src/styles/settings-layout.cssportals/developer-portal/src/utils/constants.jsportals/developer-portal/src/utils/sampleApiLoader.jsportals/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
There was a problem hiding this comment.
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 winFix duplicate enumerated values in response schema tables.
The Enumerated Values sections for POST (lines 245–246) and PUT (lines 399–400) both list
status|errortwice. 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 winRemove 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 | 🟠 MajorEnsure update operations run inside the intended transaction.
APIContent.updatecalls at lines 79-98 and 224-244 have transaction placement issues:
- Lines 79-98: Missing
transaction: tentirely 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: tinto 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 | 🟡 MinorSTATUS is non-null ENUM without a model default; ensure all code paths supply a valid value.
STATUSis defined as non-null ENUM with nodefaultValuein the model. Code paths that parse YAML (including artifact zips and sample seeding) apply a default of'PUBLISHED'viaparseApiMetadataFromYamlFile. However, the direct JSON.parse path (JSON.parse(req.body.apiMetadata)) does not apply a default; ifapiStatusis omitted from the JSON payload, it will reach the database asundefinedand fail the NOT NULL constraint. Ensure the JSON parsing path validates thatapiStatusis 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
📒 Files selected for processing (29)
docs/rest-apis/devportal/api-keys.mddocs/rest-apis/devportal/apis.mddocs/rest-apis/devportal/applications.mddocs/rest-apis/devportal/schemas.mddocs/rest-apis/devportal/subscription-plans.mdportals/developer-portal/configs/config.yaml.exampleportals/developer-portal/database/schema.postgres.sqlportals/developer-portal/docs/devportal-openapi-spec-v1.yamlportals/developer-portal/production/scripts/register_asgardeo_scopes.shportals/developer-portal/samples/apis/booking-api/api.yamlportals/developer-portal/samples/apis/ping-api/api.yamlportals/developer-portal/src/controllers/apiContentController.jsportals/developer-portal/src/controllers/apiKeysPageController.jsportals/developer-portal/src/controllers/subscriptionsContentController.jsportals/developer-portal/src/dao/apiDao.jsportals/developer-portal/src/dao/apiFileDao.jsportals/developer-portal/src/defaultContent/partials/sidebar.hbsportals/developer-portal/src/dto/apiDto.jsportals/developer-portal/src/helpers/handlebarsHelpers.jsportals/developer-portal/src/middlewares/ensureAuthenticated.jsportals/developer-portal/src/middlewares/passportConfig.jsportals/developer-portal/src/middlewares/registerPartials.jsportals/developer-portal/src/models/apiContent.jsportals/developer-portal/src/models/apiMetadata.jsportals/developer-portal/src/services/apiMetadataService.jsportals/developer-portal/src/services/mcpRegistryService.jsportals/developer-portal/src/utils/constants.jsportals/developer-portal/src/utils/sampleApiLoader.jsportals/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
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
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 | 🟠 MajorUpdate 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, theMISSING_REQUIRED_PARAMETERcode 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
📒 Files selected for processing (18)
docs/rest-apis/devportal/api-content.mddocs/rest-apis/devportal/apis.mddocs/rest-apis/devportal/application-keys.mddocs/rest-apis/devportal/applications.mddocs/rest-apis/devportal/key-managers.mddocs/rest-apis/devportal/labels.mddocs/rest-apis/devportal/organization-content.mddocs/rest-apis/devportal/organizations.mddocs/rest-apis/devportal/providers.mddocs/rest-apis/devportal/schemas.mddocs/rest-apis/devportal/subscription-plans.mddocs/rest-apis/devportal/views.mddocs/rest-apis/devportal/webhook-subscribers.mdportals/developer-portal/configs/config-platform-api.toml.exampleportals/developer-portal/docs/devportal-openapi-spec-v1.yamlportals/developer-portal/samples/subscription-plans.yamlportals/developer-portal/src/scripts/oauth2-key-generation.jsportals/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
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