Skip to content

Add cloud extension seam for routing and navigation integration#2863

Open
dakshina99 wants to merge 1 commit into
wso2:mainfrom
dakshina99:apip-aiw-cloud-env-ui
Open

Add cloud extension seam for routing and navigation integration#2863
dakshina99 wants to merge 1 commit into
wso2:mainfrom
dakshina99:apip-aiw-cloud-env-ui

Conversation

@dakshina99

Copy link
Copy Markdown

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:

  • Added a TypeScript interface and stub implementation in src/cloud/extensions.stub.ts describing the contract for cloud extension modules, including routes, nav items, providers, and form fields. The app imports cloudExtensions from the @cloud-extensions alias, which resolves to the stub by default and to a real module in cloud builds.
  • Updated tsconfig.json and vite.config.ts to define and resolve the @cloud-extensions and @cloud-ui module aliases, with @cloud-extensions pointing to either the stub or a real extension module based on the build environment. [1] [2]
  • Added a runtime configuration flag (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:

  • Updated the main app shell (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]
  • Enhanced the sidebar (AppSidebar.tsx) to dynamically render cloud-contributed nav items, filtered by scope and user permissions, and to compute their navigation paths. [1] [2] [3]
  • Updated active menu item logic in appShellMain.tsx to highlight the correct sidebar item for cloud-contributed routes. [1] [2] [3]

Cloud Extension Points in Forms:

  • Extended the Add Gateway form to render a cloud-contributed field (if present), enforce its requiredness, and call a cloud-provided persistence hook after gateway creation. This is a no-op in the standalone build. [1] [2] [3] [4] [5]

Build and Ignore Rules:

  • Updated .gitignore to exclude cloud extension overlay/vendor targets, ensuring OSS and SaaS builds remain cleanly separated.

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>
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The 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.

Changes

Cloud extension integration

Layer / File(s) Summary
Extension contract and build wiring
portals/ai-workspace/src/cloud/extensions.stub.ts, portals/ai-workspace/tsconfig.json, portals/ai-workspace/vite.config.ts, portals/ai-workspace/src/config.env.ts, portals/ai-workspace/bff/internal/config/runtime_config.go, portals/ai-workspace/.gitignore
Defines cloud contribution contracts and standalone defaults, configures replaceable module aliases, exposes the cloud feature runtime setting, and ignores cloud overlay targets.
Workspace shell integration
portals/ai-workspace/src/App.tsx, portals/ai-workspace/src/pages/appShell/AppSidebar.tsx, portals/ai-workspace/src/pages/appShell/appShellMain.tsx
Wraps the app shell with optional providers, mounts scoped extension routes, renders filtered cloud navigation entries, and maps cloud routes to active sidebar items.
Gateway creation extension
portals/ai-workspace/src/pages/appShell/appShellPages/gateways/AddGateway.tsx
Renders an optional cloud field, validates required values, and invokes the cloud callback after gateway creation.

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
Loading

Possibly related PRs

  • wso2/api-platform#2813: Updates the same runtime configuration allowlist used to expose configuration values to the SPA.

Suggested reviewers: renuka-fernando, thivindu, ashera96, anugayan, tharsanan1

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the core feature, but it omits most required template sections like Purpose, Tests, Security checks, and Test environment. Reformat the PR description to match the template and add the missing sections, including purpose, goals, approach, tests, security checks, related PRs, and test environment.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding a cloud extension seam for routing and navigation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3864bef and 741bed2.

📒 Files selected for processing (10)
  • portals/ai-workspace/.gitignore
  • portals/ai-workspace/bff/internal/config/runtime_config.go
  • portals/ai-workspace/src/App.tsx
  • portals/ai-workspace/src/cloud/extensions.stub.ts
  • portals/ai-workspace/src/config.env.ts
  • portals/ai-workspace/src/pages/appShell/AppSidebar.tsx
  • portals/ai-workspace/src/pages/appShell/appShellMain.tsx
  • portals/ai-workspace/src/pages/appShell/appShellPages/gateways/AddGateway.tsx
  • portals/ai-workspace/tsconfig.json
  • portals/ai-workspace/vite.config.ts

Comment on lines +39 to +43
export interface CloudRoute {
path: string;
element: ReactNode;
scope: CloudScope;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 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-L612
  • portals/ai-workspace/src/App.tsx#L824-L833
  • portals/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.

Comment on lines +150 to +158
// 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,
});
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant