Add cloud extension seam for routing and navigation integration#2863
Add cloud extension seam for routing and navigation integration#2863dakshina99 wants to merge 1 commit into
Conversation
Introduce a no-op extension seam (@Cloud-Extensions) so a cloud build can contribute routes, nav items, providers, and an optional Add Gateway field without changing the standalone app, which resolves the alias to a no-op stub. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe AI Workspace adds a typed cloud extension seam with configurable module aliases. Cloud builds can contribute routes, sidebar items, providers, and Add Gateway fields while standalone builds use no-op defaults. ChangesCloud extension integration
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant App
participant CloudExtensions
participant AppShell
participant AddGateway
App->>CloudExtensions: load providers, routes, navItems, and gatewayCreate
CloudExtensions-->>App: extension contributions
App->>AppShell: render provider-wrapped shell and scoped routes
AppShell->>CloudExtensions: filter navigation by scope and permission
CloudExtensions-->>AppShell: navigation entries and active ids
AddGateway->>CloudExtensions: render optional field
AddGateway->>CloudExtensions: persist gateway association after creation
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.12.2)level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain modules listed in go.work or their selected dependencies" 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: 2
🤖 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 `@portals/ai-workspace/src/cloud/extensions.stub.ts`:
- Around line 39-43: Cloud route access is not enforced consistently because
route rendering and sidebar visibility use separate permission metadata. In
portals/ai-workspace/src/cloud/extensions.stub.ts lines 39-43, add shared
required-scope metadata or bind each CloudRoute to a centralized policy; in
portals/ai-workspace/src/App.tsx lines 603-612 and 824-833, guard organization-
and project-scoped route rendering with that policy; in
portals/ai-workspace/src/pages/appShell/AppSidebar.tsx lines 134-138, derive
navigation visibility from the same policy rather than treating sidebar
filtering as access control.
In
`@portals/ai-workspace/src/pages/appShell/appShellPages/gateways/AddGateway.tsx`:
- Around line 150-158: Update the gateway creation flow around
gatewayCreate.onGatewayCreated so association failures cannot be reported as
failed gateway submissions after createdGateway.id exists. Prefer making gateway
creation and cloud association atomic server-side; otherwise retain the created
gateway ID and handle association failure separately with an appropriate retry
or compensation path, preventing the form from retrying gateway creation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: e2589751-d51e-47ee-93b7-c71033ba35db
📒 Files selected for processing (10)
portals/ai-workspace/.gitignoreportals/ai-workspace/bff/internal/config/runtime_config.goportals/ai-workspace/src/App.tsxportals/ai-workspace/src/cloud/extensions.stub.tsportals/ai-workspace/src/config.env.tsportals/ai-workspace/src/pages/appShell/AppSidebar.tsxportals/ai-workspace/src/pages/appShell/appShellMain.tsxportals/ai-workspace/src/pages/appShell/appShellPages/gateways/AddGateway.tsxportals/ai-workspace/tsconfig.jsonportals/ai-workspace/vite.config.ts
| export interface CloudRoute { | ||
| path: string; | ||
| element: ReactNode; | ||
| scope: CloudScope; | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Enforce cloud permissions on routes, not only sidebar links.
requiredScope exists only on CloudNavItem; both route loops render every contributed route, so an authenticated user can directly open a cloud URL that the sidebar hides.
portals/ai-workspace/src/cloud/extensions.stub.ts#L39-L43: add shared route-level permission metadata, or bind each route to a centrally defined policy.portals/ai-workspace/src/App.tsx#L603-L612: deny rendering org-scoped routes when the caller lacks the route’s required scope.portals/ai-workspace/src/App.tsx#L824-L833: apply the same guard to project-scoped routes.portals/ai-workspace/src/pages/appShell/AppSidebar.tsx#L134-L138: derive visibility from that same shared policy rather than treating navigation filtering as access control.
📍 Affects 3 files
portals/ai-workspace/src/cloud/extensions.stub.ts#L39-L43(this comment)portals/ai-workspace/src/App.tsx#L603-L612portals/ai-workspace/src/App.tsx#L824-L833portals/ai-workspace/src/pages/appShell/AppSidebar.tsx#L134-L138
🤖 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/ai-workspace/src/cloud/extensions.stub.ts` around lines 39 - 43,
Cloud route access is not enforced consistently because route rendering and
sidebar visibility use separate permission metadata. In
portals/ai-workspace/src/cloud/extensions.stub.ts lines 39-43, add shared
required-scope metadata or bind each CloudRoute to a centralized policy; in
portals/ai-workspace/src/App.tsx lines 603-612 and 824-833, guard organization-
and project-scoped route rendering with that policy; in
portals/ai-workspace/src/pages/appShell/AppSidebar.tsx lines 134-138, derive
navigation visibility from the same policy rather than treating sidebar
filtering as access control.
| // Persist any cloud-only association tied to the new gateway. No-op in the | ||
| // standalone build. | ||
| if (gatewayCreate) { | ||
| await gatewayCreate.onGatewayCreated({ | ||
| orgId: currentOrganization?.uuid ?? "", | ||
| gatewayId: createdGateway.id, | ||
| value: cloudFieldValue, | ||
| }); | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Do not report a successful gateway creation as a failed submission.
If onGatewayCreated throws, the gateway has already been created, but the catch displays failure and leaves the form retryable; a retry can create another gateway. Make creation and association atomic server-side, or retain the created ID and handle association failure separately with retry/compensation.
🤖 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/ai-workspace/src/pages/appShell/appShellPages/gateways/AddGateway.tsx`
around lines 150 - 158, Update the gateway creation flow around
gatewayCreate.onGatewayCreated so association failures cannot be reported as
failed gateway submissions after createdGateway.id exists. Prefer making gateway
creation and cloud association atomic server-side; otherwise retain the created
gateway ID and handle association failure separately with an appropriate retry
or compensation path, preventing the form from retrying gateway creation.
This pull request introduces a flexible "cloud extension seam" to the AI Workspace portal, allowing cloud-only features (such as routes, navigation items, and form fields) to be contributed by external modules in SaaS builds, while leaving the open-source/standalone build unchanged. The extension seam is implemented via a TypeScript interface and a stub module, with build-time and runtime toggles to enable or disable cloud features. The main codebase is updated to dynamically consume contributed routes, nav items, and form fields if present.
The most important changes are:
Cloud Extension Infrastructure:
src/cloud/extensions.stub.tsdescribing the contract for cloud extension modules, including routes, nav items, providers, and form fields. The app importscloudExtensionsfrom the@cloud-extensionsalias, which resolves to the stub by default and to a real module in cloud builds.tsconfig.jsonandvite.config.tsto define and resolve the@cloud-extensionsand@cloud-uimodule aliases, with@cloud-extensionspointing to either the stub or a real extension module based on the build environment. [1] [2]CLOUD_FEATURES/APIP_AIW_CLOUD_FEATURES) to gate cloud-only features, and exposed it to the SPA and build system. [1] [2] [3]Dynamic Cloud Feature Integration:
App.tsx) to wrap the shell with optional cloud-provided providers, and to inject cloud-contributed routes into the org and project route trees. [1] [2] [3] [4]AppSidebar.tsx) to dynamically render cloud-contributed nav items, filtered by scope and user permissions, and to compute their navigation paths. [1] [2] [3]appShellMain.tsxto highlight the correct sidebar item for cloud-contributed routes. [1] [2] [3]Cloud Extension Points in Forms:
Build and Ignore Rules:
.gitignoreto exclude cloud extension overlay/vendor targets, ensuring OSS and SaaS builds remain cleanly separated.