Feat/marketplace pull aaas#1089
Conversation
|
Warning Review limit reached
Next review available in: 44 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughPlatform profile metadata now includes URL, logo URL, and category across five services. The marketplace server retrieves active platform profiles from AaaS, exposes them through ChangesPlatform profile metadata
AaaS platform API
Marketplace live data integration
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Visitor
participant HomePage
participant MarketplaceServer
participant AaaS
Visitor->>HomePage: Open marketplace
HomePage->>MarketplaceServer: GET /api/platforms
MarketplaceServer->>AaaS: Fetch paginated platform packets
AaaS-->>MarketplaceServer: Active platform profiles
MarketplaceServer-->>HomePage: Platform cards and count
HomePage-->>Visitor: Merged static and live marketplace entries
Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ 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: 1
🧹 Nitpick comments (4)
platforms/marketplace/client/client/src/pages/app-detail.tsx (2)
141-163: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove unnecessary
anycasts.Once
appis properly typed asApp, these explicitanycasts can be cleanly removed.♻️ Proposed refactor
- {(app as any).appStoreUrl && (app as any).playStoreUrl ? ( + {app.appStoreUrl && app.playStoreUrl ? ( <> - <a href={(app as any).appStoreUrl} target="_blank" rel="noopener noreferrer" className="flex-1"> + <a href={app.appStoreUrl} target="_blank" rel="noopener noreferrer" className="flex-1"> <Button className="w-full text-black font-bold px-8 py-4 rounded-full hover:scale-105 transition-all duration-200" style={{ backgroundColor: 'hsl(85, 100%, 85%)' }}> <ExternalLink className="w-5 h-5 mr-3" /> App Store </Button> </a> - <a href={(app as any).playStoreUrl} target="_blank" rel="noopener noreferrer" className="flex-1"> + <a href={app.playStoreUrl} target="_blank" rel="noopener noreferrer" className="flex-1"> <Button className="w-full text-black font-bold px-8 py-4 rounded-full hover:scale-105 transition-all duration-200" style={{ backgroundColor: 'hsl(270, 100%, 85%)' }}> <ExternalLink className="w-5 h-5 mr-3" /> Play Store </Button> </a> </> ) : ( - <a href={(app as any).url} target="_blank" rel="noopener noreferrer" className="flex-1"> + <a href={app.url} target="_blank" rel="noopener noreferrer" className="flex-1"> <Button className="w-full text-black font-bold px-8 py-4 rounded-full hover:scale-105 transition-all duration-200" style={{ backgroundColor: 'hsl(85, 100%, 85%)' }}> <ExternalLink className="w-5 h-5 mr-3" /> Visit Website </Button> </a> )}🤖 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 `@platforms/marketplace/client/client/src/pages/app-detail.tsx` around lines 141 - 163, Remove the unnecessary any casts from the appStoreUrl, playStoreUrl, and url references in the app detail rendering block. Use the existing App typing for app directly, preserving the current conditional logic and link behavior.
65-67: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDefine and use the
Apptype instead ofany.Typing
appasanyremoves type safety for the rest of the component and leads to unnecessary type casts later in the file. Consider exporting theAppinterface fromhome-page.tsx(or extracting it to a shared types file) and using it here.♻️ Proposed refactor
- const staticApp = appsData.find(a => a.id === appId); - const dynamicApp = platformsData?.platforms?.find((p: any) => p.id === appId); - const app: any = staticApp ?? dynamicApp; + const staticApp = appsData.find(a => a.id === appId); + const dynamicApp = platformsData?.platforms?.find((p: App) => p.id === appId); + const app: App | undefined = staticApp ?? dynamicApp;🤖 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 `@platforms/marketplace/client/client/src/pages/app-detail.tsx` around lines 65 - 67, Replace the any typing in the app selection flow with a shared App type: export or extract the existing App interface from home-page.tsx, import it into app-detail.tsx, and type staticApp, dynamicApp, and app consistently. Remove downstream casts that are only needed because app is typed as any.platforms/marketplace/client/client/src/pages/home-page.tsx (1)
174-210: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove unnecessary
anycasts.Since
appis strongly typed asApp(and theAppinterface includesappStoreUrlandplayStoreUrl), castingapptoanybypasses TypeScript's safety checks unnecessarily and introduces code smell.♻️ Proposed refactor
- {(app as any).appStoreUrl && (app as any).playStoreUrl ? ( + {app.appStoreUrl && app.playStoreUrl ? ( <> <a - href={(app as any).appStoreUrl} + href={app.appStoreUrl} target="_blank" rel="noopener noreferrer" className="flex-1" onClick={(e) => e.stopPropagation()} > <Button className="w-full text-black font-bold px-4 py-3 rounded-full hover:opacity-90" style={{ backgroundColor: 'hsl(85, 100%, 85%)' }}> App Store </Button> </a> <a - href={(app as any).playStoreUrl} + href={app.playStoreUrl} target="_blank" rel="noopener noreferrer" className="flex-1" onClick={(e) => e.stopPropagation()} > <Button className="w-full text-black font-bold px-4 py-3 rounded-full hover:opacity-90" style={{ backgroundColor: 'hsl(270, 100%, 85%)' }}> Play Store </Button> </a> </> ) : ( <a - href={(app as any).url || '#'} + href={app.url || '#'} target="_blank" rel="noopener noreferrer" onClick={(e) => e.stopPropagation()} >🤖 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 `@platforms/marketplace/client/client/src/pages/home-page.tsx` around lines 174 - 210, Remove the unnecessary `(app as any)` casts throughout the store-link conditional and anchor hrefs in the app rendering block. Access `app.appStoreUrl`, `app.playStoreUrl`, and `app.url` directly using the existing `App` type, preserving the current conditional and fallback behavior.platforms/cerberus/client/src/services/PlatformEVaultService.ts (1)
138-141: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftExtract duplicated
PlatformEVaultServiceinto a shared library.The
PlatformEVaultServiceclass implementation is completely duplicated across these service packages. The only variations are the hardcoded platform names and profile metadata (e.g., URL, logo, category). To drastically improve maintainability and enforce DRY principles, consider extracting this logic into a shared core library and parameterizing it with the platform-specific metadata during initialization.
platforms/cerberus/client/src/services/PlatformEVaultService.ts#L138-L141: extract the duplicated service logic into a shared package, taking this platform-specific metadata as configuration.platforms/dreamsync/api/src/services/PlatformEVaultService.ts#L138-L141: replace the duplicated class with the shared service implementation.platforms/ecurrency/api/src/services/PlatformEVaultService.ts#L138-L141: replace the duplicated class with the shared service implementation.platforms/esigner/api/src/services/PlatformEVaultService.ts#L138-L141: replace the duplicated class with the shared service implementation.🤖 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 `@platforms/cerberus/client/src/services/PlatformEVaultService.ts` around lines 138 - 141, Extract the duplicated PlatformEVaultService implementation into a shared library and parameterize initialization with each platform’s name and profile metadata. Update platforms/cerberus/client/src/services/PlatformEVaultService.ts:138-141, platforms/dreamsync/api/src/services/PlatformEVaultService.ts:138-141, platforms/ecurrency/api/src/services/PlatformEVaultService.ts:138-141, and platforms/esigner/api/src/services/PlatformEVaultService.ts:138-141 to use the shared implementation while preserving their platform-specific URL, logo, and category values.
🤖 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 `@platforms/marketplace/client/client/src/pages/home-page.tsx`:
- Around line 38-46: Update the dynamic platform processing around the platforms
filter and category construction to safely handle missing id, name, description,
and category fields from the external payload. Guard lowercase operations in the
search-related logic, exclude or safely handle incomplete platform records
without crashing rendering, and only add defined category values to the
categories list so no "undefined" entry is produced.
---
Nitpick comments:
In `@platforms/cerberus/client/src/services/PlatformEVaultService.ts`:
- Around line 138-141: Extract the duplicated PlatformEVaultService
implementation into a shared library and parameterize initialization with each
platform’s name and profile metadata. Update
platforms/cerberus/client/src/services/PlatformEVaultService.ts:138-141,
platforms/dreamsync/api/src/services/PlatformEVaultService.ts:138-141,
platforms/ecurrency/api/src/services/PlatformEVaultService.ts:138-141, and
platforms/esigner/api/src/services/PlatformEVaultService.ts:138-141 to use the
shared implementation while preserving their platform-specific URL, logo, and
category values.
In `@platforms/marketplace/client/client/src/pages/app-detail.tsx`:
- Around line 141-163: Remove the unnecessary any casts from the appStoreUrl,
playStoreUrl, and url references in the app detail rendering block. Use the
existing App typing for app directly, preserving the current conditional logic
and link behavior.
- Around line 65-67: Replace the any typing in the app selection flow with a
shared App type: export or extract the existing App interface from
home-page.tsx, import it into app-detail.tsx, and type staticApp, dynamicApp,
and app consistently. Remove downstream casts that are only needed because app
is typed as any.
In `@platforms/marketplace/client/client/src/pages/home-page.tsx`:
- Around line 174-210: Remove the unnecessary `(app as any)` casts throughout
the store-link conditional and anchor hrefs in the app rendering block. Access
`app.appStoreUrl`, `app.playStoreUrl`, and `app.url` directly using the existing
`App` type, preserving the current conditional and fallback behavior.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: ab9d4aad-82a6-4bca-a9aa-1d8c7edd5f8d
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (12)
platforms/cerberus/client/src/services/PlatformEVaultService.tsplatforms/dreamsync/api/src/services/PlatformEVaultService.tsplatforms/ecurrency/api/src/services/PlatformEVaultService.tsplatforms/esigner/api/src/services/PlatformEVaultService.tsplatforms/file-manager/api/src/services/PlatformEVaultService.tsplatforms/marketplace/client/client/src/pages/app-detail.tsxplatforms/marketplace/client/client/src/pages/home-page.tsxplatforms/marketplace/client/package.jsonplatforms/marketplace/client/server/aaas.tsplatforms/marketplace/client/server/env.tsplatforms/marketplace/client/server/index.tsplatforms/marketplace/client/server/routes.ts
| const dynamicApps = (platformsData?.platforms ?? []).filter( | ||
| (p) => !staticIds.has(p.id.toLowerCase()) && !staticNames.has(p.name.toLowerCase()), | ||
| ); | ||
| const apps: App[] = [...staticApps, ...dynamicApps]; | ||
|
|
||
| const categories = ["All Apps", "Identity", "Social", "Governance", "Wellness", "Finance", "Storage", "Productivity"]; | ||
| const categories = [ | ||
| "All Apps", | ||
| ...Array.from(new Set([...BASE_CATEGORIES, ...apps.map((a) => a.category)])), | ||
| ]; |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Add defensive checks for external API payload fields.
Data retrieved from external APIs may be missing expected fields. If an item in platformsData.platforms lacks an id, name, or description (used in the search filter logic later), calling .toLowerCase() on them will crash the React render cycle. Additionally, undefined categories will be added as "undefined" string literals to the filter list.
🛡️ Proposed defensive guards
- const dynamicApps = (platformsData?.platforms ?? []).filter(
- (p) => !staticIds.has(p.id.toLowerCase()) && !staticNames.has(p.name.toLowerCase()),
- );
+ const dynamicApps = (platformsData?.platforms ?? []).filter(
+ (p) => p?.id && p?.name && p?.description && !staticIds.has(p.id.toLowerCase()) && !staticNames.has(p.name.toLowerCase()),
+ );
const apps: App[] = [...staticApps, ...dynamicApps];
const categories = [
"All Apps",
- ...Array.from(new Set([...BASE_CATEGORIES, ...apps.map((a) => a.category)])),
+ ...Array.from(new Set([...BASE_CATEGORIES, ...apps.map((a) => a.category).filter(Boolean)])),
];📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const dynamicApps = (platformsData?.platforms ?? []).filter( | |
| (p) => !staticIds.has(p.id.toLowerCase()) && !staticNames.has(p.name.toLowerCase()), | |
| ); | |
| const apps: App[] = [...staticApps, ...dynamicApps]; | |
| const categories = ["All Apps", "Identity", "Social", "Governance", "Wellness", "Finance", "Storage", "Productivity"]; | |
| const categories = [ | |
| "All Apps", | |
| ...Array.from(new Set([...BASE_CATEGORIES, ...apps.map((a) => a.category)])), | |
| ]; | |
| const dynamicApps = (platformsData?.platforms ?? []).filter( | |
| (p) => p?.id && p?.name && p?.description && !staticIds.has(p.id.toLowerCase()) && !staticNames.has(p.name.toLowerCase()), | |
| ); | |
| const apps: App[] = [...staticApps, ...dynamicApps]; | |
| const categories = [ | |
| "All Apps", | |
| ...Array.from(new Set([...BASE_CATEGORIES, ...apps.map((a) => a.category).filter(Boolean)])), | |
| ]; |
🤖 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 `@platforms/marketplace/client/client/src/pages/home-page.tsx` around lines 38
- 46, Update the dynamic platform processing around the platforms filter and
category construction to safely handle missing id, name, description, and
category fields from the external payload. Guard lowercase operations in the
search-related logic, exclude or safely handle incomplete platform records
without crashing rendering, and only add defined category values to the
categories list so no "undefined" entry is produced.
Description of change
Issue Number
Type of change
How the change has been tested
Change checklist
Summary by CodeRabbit
New Features
Bug Fixes