Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
4.2 KiB
4.2 KiB
Plan: Client Portal Extension Support
Objective
Extend the existing extension system to support the Client Portal. This involves adding a new hook for the client portal menu, implementing the discovery logic, adding the navigation UI, and creating the runtime page for client portal extensions.
Status update (2025-11-21):
- Manifest schema includes
ui.hooks.clientPortalMenu; backend discovery and client portal menu rendering are implemented (server/src/app/client-portal/extensions/[id]/page.tsx,ClientPortalLayout, menu component). - Runtime iframe uses
buildExtUiSrcandbootstrapIframeto load Runner-hosted UI; client portal page exists and matches MSP flow. - Follow-up: add automated verification/tests and doc links from client portal docs.
Context
The current extension system works for the MSP portal (/msp/*). We need to replicate/adapt this for the Client Portal (/client-portal/*).
- Manifest: Extensions declare
ui.hooks.appMenufor MSP. We will addui.hooks.clientPortalMenufor Client Portal. - Discovery:
listAppMenuItemsForTenantfinds MSP extensions. We needlistClientPortalMenuItemsForTenant. - Navigation: MSP has a dynamic sidebar. Client Portal has a top navbar with hardcoded links.
- Runtime: Extensions run in iframes (
/msp/extensions/[id]). We need/client-portal/extensions/[id].
Phase 1: Manifest & Schema Updates
- Update Manifest Schema:
- Modify
ee/server/src/lib/extensions/schemas/manifest-v2.schema.ts. - Add
clientPortalMenutouiHooksSchema. - Structure:
{ label: string }.
- Modify
Phase 2: Backend Discovery Logic
- Create Server Action:
- Create
ee/server/src/lib/actions/clientPortalExtActions.ts(or similar). - Implement
listClientPortalMenuItemsForTenant():- Query
tenant_extension_install+extension_version+extension_registry. - Filter by
is_enabledandui.hooks.clientPortalMenu. - Return
{ id, label }.
- Query
- Ensure strictly typed return values.
- Create
Phase 3: Frontend Navigation
- Create Menu Component:
- Create
server/src/components/client-portal/ClientExtensionsMenu.tsx. - Fetch items using
listClientPortalMenuItemsForTenant. - Render as a dropdown or list of links in the top navbar.
- Use
ClientPortalLayoutstyling (Tailwind).
- Create
- Integrate into Layout:
- Modify
server/src/components/layout/ClientPortalLayout.tsx. - Add
ClientExtensionsMenuto the navigation bar (e.g., next to "Appointments" or in a "More" dropdown if needed, or just append to the list).
- Modify
Phase 4: Runtime Implementation
- Create Extension Page:
- Create
server/src/app/client-portal/extensions/[id]/page.tsx. - Auth Check: Ensure the user is a valid client portal user.
- Extension Info: Fetch extension install info (reuse
getInstallInfoif compatible, or create client-specific version if permissions differ). - Render: Use
DockerExtensionIframe(or a wrapped version) to render the extension. - URL Construction: Use
buildExtUiSrcwith appropriate paths.
- Create
- Verify Iframe Context:
- Ensure the extension receives appropriate context (if any) for the client portal.
- Note: Current
bootstrapIframeis minimal. If the extension needs to know it's in "Client Mode", we might need to pass query params or handle it in the extension itself. For now, we assume the extension uses theclientPortalMenuhook implies it knows how to behave.
Phase 5: Verification
- Test Case 1: Extension with
clientPortalMenu.- Verify it appears in the menu.
- Verify clicking loads the iframe.
- Test Case 2: Extension with
appMenuONLY.- Verify it does NOT appear in the client portal menu.
- Test Case 3: Extension with BOTH.
- Verify it appears in both (if logged in as appropriate user).
- Security: Verify a client user cannot access an MSP-only extension by guessing the ID (if we implement permission checks in the page loader).
Technical Details
- Directories:
ee/server/src/lib/extensions/server/src/components/layout/server/src/app/client-portal/
- Key Files:
manifest-v2.schema.tsClientPortalLayout.tsxDockerExtensionIframe.tsx