Skip to content

feat(org-lens): wire org projects page to live data - #1065

Merged
ahmedomosanya merged 15 commits into
mainfrom
feat/LFXV2-1883-integration
Jul 6, 2026
Merged

feat(org-lens): wire org projects page to live data#1065
ahmedomosanya merged 15 commits into
mainfrom
feat/LFXV2-1883-integration

Conversation

@ahmedomosanya

@ahmedomosanya ahmedomosanya commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add org-lens-projects BFF controller and service: project rows from Snowflake, workspace CRUD and project search from member-service/CDP
  • Wire the Org Projects Angular page to the new APIs with loading, no-access, empty-workspace, and error states
  • Extend lfx-multi-select for async search race-safety and inline dialog errors
  • Remove org-lens-projects.demo-data.ts; expand Playwright coverage for API stubbed flows

Copilot AI review requested due to automatic review settings July 3, 2026 15:40
@ahmedomosanya ahmedomosanya added ai-assisted A task or activity that was supported by AI, such as CoPilot, ChatGPT, or other AI technology. enhancement New feature or request WIP labels Jul 3, 2026

Copilot AI 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.

Pull request overview

Wires the Org Lens → Projects page from demo fixtures to live BFF endpoints backed by Snowflake + member-service workspace APIs, and updates the UI to handle real loading/error/empty states with improved add-project UX.

Changes:

  • Introduces new org-projects BFF routes (projects list, project search, workspace CRUD, workspace membership updates) with Snowflake + member-service integrations and Valkey caching.
  • Updates the Org Projects Angular page to call live APIs, support workspace management, and add richer empty/error states and trend UI.
  • Removes demo-data fixtures, extends shared contracts/constants, and expands Playwright coverage for stubbed API flows.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/shared/src/interfaces/org-lens-projects.interface.ts Extends shared contracts for live project/search/workspace APIs and UI view-model fields.
packages/shared/src/constants/org-lens-projects.constants.ts Adds new Org Projects constants (workspace defaults, search limits, Insights/warehouse-related constants).
apps/lfx-one/src/styles.scss Adds a dedicated tooltip style for the trend tooltip.
apps/lfx-one/src/server/services/org-lens-projects.service.ts New server-side service for Snowflake project rows, CDP/Insights enrichment, and member-service workspace operations.
apps/lfx-one/src/server/routes/orgs.route.ts Registers new /lens/projects and /lens/workspaces routes.
apps/lfx-one/src/server/controllers/org-lens-projects.controller.ts New controller implementing org projects/workspaces HTTP endpoints.
apps/lfx-one/src/app/shared/services/org-lens-projects.service.ts Replaces demo-data service with HttpClient-backed calls to the new BFF routes.
apps/lfx-one/src/app/shared/services/org-lens-projects.demo-data.ts Removes demo fixtures now that live APIs are wired.
apps/lfx-one/src/app/shared/components/multi-select/multi-select.component.ts Extends multi-select wrapper with filterBy/panelStyleClass/scrollHeight and emits filter events.
apps/lfx-one/src/app/shared/components/multi-select/multi-select.component.scss Adds panel styling hook for the Org Projects add-projects multi-select.
apps/lfx-one/src/app/shared/components/multi-select/multi-select.component.html Wires new inputs/outputs through to PrimeNG MultiSelect.
apps/lfx-one/src/app/modules/dashboards/org/org-projects/org-projects.component.ts Updates Org Projects page logic for live data, workspace CRUD, async search, and richer row view-models.
apps/lfx-one/src/app/modules/dashboards/org/org-projects/org-projects.component.html Updates UI for loading/no-access/error/empty states, workspace dialogs, and add-project flow.
apps/lfx-one/e2e/org-projects.spec.ts Expands Playwright tests for API-stubbed flows and new UI states.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/lfx-one/src/server/services/org-lens-projects.service.ts Outdated
Comment thread apps/lfx-one/e2e/org-projects.spec.ts Outdated
Comment thread packages/shared/src/interfaces/org-lens-projects.interface.ts Outdated
Replace client-side demo data with BFF routes that hydrate project rows
from platinum Snowflake models and workspace CRUD from member-service.

- Add org-lens-projects controller and service with workspace/search endpoints
- Update org-projects UI for loading, no-access, and error states
- Extend multi-select for async search race-safety and dialog error surfaces
- Remove org-lens-projects.demo-data.ts; expand Playwright coverage

Signed-off-by: ahmedomosanya <aopeyemi@contractor.linuxfoundation.org>
- Correct double-negative bulk-add failure message
- Seed default e2e workspace with project slugs so /lens/projects is called
- Document trendTooltipHtml XSS constraint on the shared interface

Signed-off-by: ahmedomosanya <aopeyemi@contractor.linuxfoundation.org>
@ahmedomosanya
ahmedomosanya force-pushed the feat/LFXV2-1883-integration branch from fd954af to d7d2a79 Compare July 3, 2026 16:04
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Org Projects moves from static demo data to a fully backend-driven implementation. New shared contracts and constants support project search, workspace CRUD, and CDP health enrichment. A server controller/routes/service integrate Snowflake and member-service. The client service, component, and template are reworked around async signals and dialog states. Multi-select and e2e tests are extended accordingly.

Changes

Org Projects Workspace Backend Integration

Layer / File(s) Summary
Shared contracts and constants
packages/shared/src/interfaces/org-lens-projects.interface.ts, packages/shared/src/constants/org-lens-projects.constants.ts
Adds search/workspace/empty-state/row/CDP interfaces, unavailable health state, influence trend UI class constants, and default workspace/search/batch configuration constants.
Server-side org lens projects service
apps/lfx-one/src/server/services/org-lens-projects.service.ts
Implements Snowflake-backed project retrieval/search with Valkey caching, CDP health enrichment, and member-service-backed workspace CRUD, add/remove project membership, and default workspace bootstrapping.
Controller and route wiring
apps/lfx-one/src/server/controllers/org-lens-projects.controller.ts, apps/lfx-one/src/server/routes/orgs.route.ts
Adds OrgLensProjectsController with validated handlers for projects/search/workspaces and registers corresponding Express routes.
Client HTTP service
apps/lfx-one/src/app/shared/services/org-lens-projects.service.ts, apps/lfx-one/src/app/shared/services/org-lens-projects.demo-data.ts
Replaces demo-data fixtures with HttpClient-based calls for projects, search, and full workspace lifecycle/membership operations; removes the demo-data module.
Org projects component state and async flows
apps/lfx-one/src/app/modules/dashboards/org/org-projects/org-projects.component.ts
Reworks component around signals for workspace/project loading, debounced add-project search with request cancellation, async workspace rename/create/delete/remove mutations, and response-driven filtering/row enrichment.
Org projects template states and dialogs
apps/lfx-one/src/app/modules/dashboards/org/org-projects/org-projects.component.html, .scss, apps/lfx-one/src/styles.scss
Adds conditional access/loading/empty/error rendering, gates workspace and add-project dialogs on pending state, updates insights link, and adds trend tooltip/multiselect panel styling.
Multi-select filter enhancements
apps/lfx-one/src/app/shared/components/multi-select/multi-select.component.ts, .html
Adds filterBy, panelStyleClass, scrollHeight inputs and a filterChange output wired to the PrimeNG multiselect filter event.
E2E test coverage
apps/lfx-one/e2e/org-projects.spec.ts
Replaces static demo stubs with parameterized API stubbing and adds tests for access states, workspace creation, search ordering, save failure handling, and post-add table reload.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant OrgProjectsComponent
  participant OrgLensProjectsService as ClientService
  participant OrgLensProjectsController
  participant OrgLensProjectsService_S as ServerService
  participant MemberService

  OrgProjectsComponent->>ClientService: getWorkspaces(orgUid)
  ClientService->>OrgLensProjectsController: GET /lens/workspaces
  OrgLensProjectsController->>ServerService: getWorkspaces(req, accountId)
  ServerService->>MemberService: fetch/bootstrap workspace metadata
  MemberService-->>ServerService: workspace resources
  ServerService-->>OrgLensProjectsController: OrgProjectsWorkspacesResponse
  OrgLensProjectsController-->>ClientService: workspaces JSON
  ClientService-->>OrgProjectsComponent: workspaces signal updated

  OrgProjectsComponent->>ClientService: confirmAddProjects(slugs)
  ClientService->>OrgLensProjectsController: POST /lens/workspaces/:id/projects
  OrgLensProjectsController->>ServerService: addProjectsToWorkspace(workspaceId, slugs)
  ServerService->>MemberService: bulk add project slugs
  MemberService-->>ServerService: succeeded/failed slugs
  ServerService-->>OrgLensProjectsController: updated OrgProjectsWorkspace
  OrgLensProjectsController-->>ClientService: 200 workspace JSON
  ClientService-->>OrgProjectsComponent: merge workspace, trigger reload
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: wiring the org projects page to live data.
Description check ✅ Passed The description is directly related to the changeset and matches the live-data integration work.
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
  • Commit unit tests in branch feat/LFXV2-1883-integration

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

@ahmedomosanya
ahmedomosanya marked this pull request as ready for review July 3, 2026 16:05
@ahmedomosanya
ahmedomosanya requested a review from a team as a code owner July 3, 2026 16:05
Copilot AI review requested due to automatic review settings July 3, 2026 16:05
@ahmedomosanya ahmedomosanya self-assigned this Jul 3, 2026

Copilot AI 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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Comment thread apps/lfx-one/src/server/controllers/org-lens-projects.controller.ts

@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: 4

🧹 Nitpick comments (3)
apps/lfx-one/src/app/shared/services/org-lens-projects.service.ts (1)

15-21: 🚀 Performance & Scalability | 🔵 Trivial

slugs query param may grow unbounded for large workspaces.

getProjects serializes the full workspace.projectSlugs list into a comma-joined query string. For workspaces with many projects this can approach browser/proxy URL-length limits (~2–8 KB) and silently truncate or 414. Since the backend getProjects already validates the array server-side, consider moving the slug list into a request body (e.g., POST /lens/projects with { slugs }) if workspaces are expected to hold large project counts.

🤖 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 `@apps/lfx-one/src/app/shared/services/org-lens-projects.service.ts` around
lines 15 - 21, The current getProjects method in OrgLensProjectsService sends
every slug through the query string, which can hit URL length limits for large
workspaces. Update this API call to avoid serializing workspace.projectSlugs
into HttpParams, and instead move the slug list into a request body (for
example, switch the call in getProjects to POST while keeping orgUid/orgName
context) so large slug sets can be handled safely.
apps/lfx-one/src/server/services/org-lens-projects.service.ts (2)

547-562: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Fixed 1s retry delay can add multi-second latency to write-triggering requests.

fetchWorkspaceProjectSlugsWithRetry blocks for up to (attempts - 1) * 1000ms on the request thread when the query-service index hasn't caught up yet (used by getWorkspaces, renameWorkspace, addProjectsToWorkspace). Consider a shorter initial delay with backoff, or making this async/non-blocking to the caller where the eventual value isn't immediately needed.

🤖 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 `@apps/lfx-one/src/server/services/org-lens-projects.service.ts` around lines
547 - 562, The retry loop in fetchWorkspaceProjectSlugsWithRetry currently
sleeps a fixed 1s between attempts, which can add unnecessary latency to callers
like getWorkspaces, renameWorkspace, and addProjectsToWorkspace. Update this
helper to use a shorter initial delay with backoff or otherwise avoid blocking
the request path when the slugs are not immediately required, while keeping the
retry behavior in fetchWorkspaceProjectSlugs and
fetchWorkspaceProjectSlugsWithRetry intact.

182-275: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated error-construction logic across four branches.

The WORKSPACE_PROJECTS_ADD_PARTIAL/WORKSPACE_PROJECTS_ADD_FAILED MicroserviceError blocks are nearly identical and repeated 4 times (inside the loop's catch, inside the loop's chunkMissing check, after the loop's missingRequested check, and the final responseSlugs check). Note the post-loop missingRequested check (Line 243) also appears unreachable, since any chunkMissing already throws inside the loop before it can be reached.

♻️ Extract a shared error-throwing helper
+  private throwWorkspaceAddError(accountId: string, workspaceId: string, latestResponse: unknown, partialSlugs: string[]): never {
+    if (partialSlugs.length > 0) {
+      throw new MicroserviceError('Some of the selected projects could not be added to this workspace.', 400, 'WORKSPACE_PROJECTS_ADD_PARTIAL', {
+        operation: 'add_org_lens_workspace_projects',
+        service: 'LFX_V2_MEMBER_SERVICE',
+        path: `/b2b_orgs/${accountId}/workspaces/${workspaceId}/projects/bulk`,
+        errorBody: { response: latestResponse, partialSlugs },
+      });
+    }
+    throw new MicroserviceError('None of the selected projects could be added to this workspace.', 400, 'WORKSPACE_PROJECTS_ADD_FAILED', {
+      operation: 'add_org_lens_workspace_projects',
+      service: 'LFX_V2_MEMBER_SERVICE',
+      path: `/b2b_orgs/${accountId}/workspaces/${workspaceId}/projects/bulk`,
+      errorBody: latestResponse,
+    });
+  }
🤖 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 `@apps/lfx-one/src/server/services/org-lens-projects.service.ts` around lines
182 - 275, The addProjectsToWorkspace flow repeats the same
WORKSPACE_PROJECTS_ADD_PARTIAL/WORKSPACE_PROJECTS_ADD_FAILED MicroserviceError
construction in multiple branches, making the logic hard to maintain. Extract a
shared helper in OrgLensProjectsService (or a private method near
addProjectsToWorkspace) that accepts the current context and throws the
appropriate partial/failed MicroserviceError, then replace the duplicate blocks
in the chunk catch, chunkMissing handling, missingRequested handling, and final
responseSlugs check with calls to that helper. While doing so, review the
missingRequested branch in addProjectsToWorkspace because it appears unreachable
after the per-chunk chunkMissing throw and should be removed or consolidated.
🤖 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 `@apps/lfx-one/src/server/services/org-lens-projects.service.ts`:
- Around line 365-397: The CDP fetch in fetchCdpProjects currently calls the
project API without auth, causing it to fail silently and return empty results.
Update the fetch request to include the same bearer Authorization header pattern
used elsewhere in org-lens-projects.service.ts, or otherwise propagate/log the
failure instead of swallowing it in the catch block. Keep the existing batch
logic and response parsing, but ensure the request is authenticated and failures
are visible.
- Around line 103-135: The default-workspace bootstrap path in getWorkspaces and
bootstrapDefaultWorkspace is still race-prone, so concurrent first loads can
create multiple default workspaces and deduplicateDefaultWorkspaces only hides
the duplicates after the fact. Make the bootstrap idempotent by using an atomic
create-or-return flow or a per-account lock in bootstrapDefaultWorkspace, and
ensure getWorkspaces reuses the same canonical workspace rather than relying on
query order; if duplicates already exist, reconcile them explicitly instead of
just filtering them out.
- Around line 590-645: The issue is that ensureDefaultWorkspaceProjects uses
fetchMemberServiceWorkspaceSlugs as if it were a read-only probe, but that
helper POSTs to /projects/bulk and can mutate workspace membership. Update the
flow in ensureDefaultWorkspaceProjects to either use a truly read-only
membership lookup for the probe path, or explicitly rename/document
fetchMemberServiceWorkspaceSlugs (and its call sites) to make the write side
effect clear; keep the existing probeSlug logic aligned with the intended
non-mutating vs mutating behavior.

In `@packages/shared/src/interfaces/org-lens-projects.interface.ts`:
- Around line 204-271: Move the server-only mapping types out of the shared
interfaces file and into org-lens-projects.service.ts, since OrgLensProjectRow,
OrgLensProjectPersonRow, OrgProjectsWorkspaceResource,
OrgProjectsWorkspaceProjectResource, OrgProjectsMemberServiceWorkspaceProject,
OrgProjectsCdpProject, OrgProjectsCdpHealthScore, and
OrgProjectsCdpProjectListResponse are raw/internal inputs used only by the
service. Keep the shared package limited to true BFF/client wire contracts, and
update org-lens-projects.service.ts to define or import these types locally so
the service remains self-contained.

---

Nitpick comments:
In `@apps/lfx-one/src/app/shared/services/org-lens-projects.service.ts`:
- Around line 15-21: The current getProjects method in OrgLensProjectsService
sends every slug through the query string, which can hit URL length limits for
large workspaces. Update this API call to avoid serializing
workspace.projectSlugs into HttpParams, and instead move the slug list into a
request body (for example, switch the call in getProjects to POST while keeping
orgUid/orgName context) so large slug sets can be handled safely.

In `@apps/lfx-one/src/server/services/org-lens-projects.service.ts`:
- Around line 547-562: The retry loop in fetchWorkspaceProjectSlugsWithRetry
currently sleeps a fixed 1s between attempts, which can add unnecessary latency
to callers like getWorkspaces, renameWorkspace, and addProjectsToWorkspace.
Update this helper to use a shorter initial delay with backoff or otherwise
avoid blocking the request path when the slugs are not immediately required,
while keeping the retry behavior in fetchWorkspaceProjectSlugs and
fetchWorkspaceProjectSlugsWithRetry intact.
- Around line 182-275: The addProjectsToWorkspace flow repeats the same
WORKSPACE_PROJECTS_ADD_PARTIAL/WORKSPACE_PROJECTS_ADD_FAILED MicroserviceError
construction in multiple branches, making the logic hard to maintain. Extract a
shared helper in OrgLensProjectsService (or a private method near
addProjectsToWorkspace) that accepts the current context and throws the
appropriate partial/failed MicroserviceError, then replace the duplicate blocks
in the chunk catch, chunkMissing handling, missingRequested handling, and final
responseSlugs check with calls to that helper. While doing so, review the
missingRequested branch in addProjectsToWorkspace because it appears unreachable
after the per-chunk chunkMissing throw and should be removed or consolidated.
🪄 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: 2bd017c2-b3d4-4cb5-9c7b-fb6496741e10

📥 Commits

Reviewing files that changed from the base of the PR and between 91cd354 and d7d2a79.

📒 Files selected for processing (14)
  • apps/lfx-one/e2e/org-projects.spec.ts
  • apps/lfx-one/src/app/modules/dashboards/org/org-projects/org-projects.component.html
  • apps/lfx-one/src/app/modules/dashboards/org/org-projects/org-projects.component.ts
  • apps/lfx-one/src/app/shared/components/multi-select/multi-select.component.html
  • apps/lfx-one/src/app/shared/components/multi-select/multi-select.component.scss
  • apps/lfx-one/src/app/shared/components/multi-select/multi-select.component.ts
  • apps/lfx-one/src/app/shared/services/org-lens-projects.demo-data.ts
  • apps/lfx-one/src/app/shared/services/org-lens-projects.service.ts
  • apps/lfx-one/src/server/controllers/org-lens-projects.controller.ts
  • apps/lfx-one/src/server/routes/orgs.route.ts
  • apps/lfx-one/src/server/services/org-lens-projects.service.ts
  • apps/lfx-one/src/styles.scss
  • packages/shared/src/constants/org-lens-projects.constants.ts
  • packages/shared/src/interfaces/org-lens-projects.interface.ts
💤 Files with no reviewable changes (1)
  • apps/lfx-one/src/app/shared/services/org-lens-projects.demo-data.ts

Comment thread apps/lfx-one/src/server/services/org-lens-projects.service.ts
Comment thread apps/lfx-one/src/server/services/org-lens-projects.service.ts Outdated
Comment thread apps/lfx-one/src/server/services/org-lens-projects.service.ts
Comment thread packages/shared/src/interfaces/org-lens-projects.interface.ts Outdated
- Sort normalized slug lists in parseSlugList for stable cache signatures
- Use ORG_PROJECTS_SEARCH_MIN_LENGTH in add-project search gating and copy

Reviewer feedback: PR #1065, Copilot round 2 (3 threads).

Signed-off-by: ahmedomosanya <aopeyemi@contractor.linuxfoundation.org>
Rename fetchMemberServiceWorkspaceSlugs to probeWorkspaceMembershipViaBulkUpsert
and document the intentional write used when query-service reads lag.

Reviewer feedback: PR #1065, CodeRabbit thread on membership probe.

Signed-off-by: ahmedomosanya <aopeyemi@contractor.linuxfoundation.org>
Copilot AI review requested due to automatic review settings July 3, 2026 16:25

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/lfx-one/src/app/modules/dashboards/org/org-projects/org-projects.component.ts (1)

531-556: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Invalidate in-flight searches as soon as the input changes.

Line 555 increments the request id only when the debounced request starts. If an older request resolves during the 300ms debounce window for a newer query, it can still publish stale options for the current input.

Proposed fix
-  protected searchAddableProjects(query: string): void {
+  protected searchAddableProjects(query: string): void {
+    const requestId = ++this.addableProjectsSearchRequestId;
     this.addProjectsSearchQuery.set(query);
     if (this.addableProjectsSearchDebounceTimer) {
       clearTimeout(this.addableProjectsSearchDebounceTimer);
     }
     this.addableProjectsSearchDebounceTimer = setTimeout(() => {
-      void this.runAddableProjectsSearch(query);
+      void this.runAddableProjectsSearch(query, requestId);
     }, 300);
   }
 
-  private async runAddableProjectsSearch(query: string): Promise<void> {
+  private async runAddableProjectsSearch(query: string, requestId: number): Promise<void> {
     const account = this.accountContext.selectedAccount();
     const trimmed = query.trim();
-    const requestId = ++this.addableProjectsSearchRequestId;

Also applies to: 568-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
`@apps/lfx-one/src/app/modules/dashboards/org/org-projects/org-projects.component.ts`
around lines 531 - 556, Invalidate stale addable-project searches immediately
when the query changes, not only when runAddableProjectsSearch starts. Update
searchAddableProjects and the request-id guard in runAddableProjectsSearch so
each new input bumps the in-flight request token before the 300ms debounce
delay, preventing older results from publishing over newer queries. Use the
existing addableProjectsSearchRequestId and addableProjectsSearchDebounceTimer
symbols to locate the change, and keep the final request-id check around the
async response handling.
🤖 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
`@apps/lfx-one/src/app/modules/dashboards/org/org-projects/org-projects.component.ts`:
- Around line 531-556: Invalidate stale addable-project searches immediately
when the query changes, not only when runAddableProjectsSearch starts. Update
searchAddableProjects and the request-id guard in runAddableProjectsSearch so
each new input bumps the in-flight request token before the 300ms debounce
delay, preventing older results from publishing over newer queries. Use the
existing addableProjectsSearchRequestId and addableProjectsSearchDebounceTimer
symbols to locate the change, and keep the final request-id check around the
async response handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4dc61b71-19bc-43c4-aed3-f9d2eac345f5

📥 Commits

Reviewing files that changed from the base of the PR and between d7d2a79 and 3fd2f22.

📒 Files selected for processing (2)
  • apps/lfx-one/src/app/modules/dashboards/org/org-projects/org-projects.component.ts
  • apps/lfx-one/src/server/controllers/org-lens-projects.controller.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/lfx-one/src/server/controllers/org-lens-projects.controller.ts

Copilot AI 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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Comment thread apps/lfx-one/src/server/services/org-lens-projects.service.ts Outdated
Comment thread apps/lfx-one/src/server/services/org-lens-projects.service.ts
Do not persist degraded health payloads when the Insights project API
errors; retry on the next request instead of caching for the full hour.

Reviewer feedback: PR #1065, Copilot round 3 (CDP cache thread).

Signed-off-by: ahmedomosanya <aopeyemi@contractor.linuxfoundation.org>
@ahmedomosanya ahmedomosanya removed the WIP label Jul 3, 2026

@audigregorie audigregorie 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.

Code Review Summary

Solid integration pass: three-file BFF wiring, thoughtful workspace bootstrap/retry logic, loading/error/empty states, and expanded Playwright coverage. Remaining findings are mostly convention gaps and one UX guard on the default workspace.

Several Copilot/CodeRabbit threads from earlier commits are already addressed (cache signature sort, search min-length constant, CDP cache skip, probe JSDoc).

Major — outside the diff

  • Inline <p-dialog> (checklist #3): Both workspace and add-project dialogs still use template <p-dialog> (pre-existing markup, unchanged hunks). Prefer DialogService.open() with extracted dialog components, matching add-access-user-modal / key-contacts patterns.
  • Default workspace delete: The settings dialog still exposes Delete workspace for the canonical All Projects with Activities preset (isCanonicalDefaultWorkspace is only used for empty-state copy). Hide/disable delete for that workspace or block in deleteWorkspace() before calling the API.
  • Frontend GET error logging: Component-level catchError/catch paths flip signals but never log (checklist 14.6).

What's done well

  • Workspace/project fetch pipeline with separate workspace vs. project error surfaces and targeted retry.
  • Async add-project search uses request IDs + debounce to avoid race conditions.
  • Backend skips Valkey caching when CDP enrichment fails so degraded health scores are not frozen for an hour.

Comment thread apps/lfx-one/src/app/shared/components/multi-select/multi-select.component.scss Outdated
Comment thread apps/lfx-one/src/server/services/org-lens-projects.service.ts Outdated
Comment thread apps/lfx-one/src/server/services/org-lens-projects.service.ts
Comment thread apps/lfx-one/src/server/services/org-lens-projects.service.ts Outdated
- Replace raw search input with lfx-input-text bound to addProjectsForm
- Move org-projects multi-select panel styles out of shared component
- Log catchError and CDP enrichment failures before graceful fallbacks
- Remove dead defaultOrgProjectsWorkspace static; stable @for track keys

Reviewer feedback: PR #1065, audigregorie review (7 threads).

Signed-off-by: ahmedomosanya <aopeyemi@contractor.linuxfoundation.org>

Copilot AI 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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment thread apps/lfx-one/src/server/services/org-lens-projects.service.ts Outdated
Reviewer feedback: PR #1065, Copilot — removeProjectFromWorkspace DELETE
now passes X-Sync: true like the other member-service write paths.

Signed-off-by: ahmedomosanya <aopeyemi@contractor.linuxfoundation.org>
Serve health scores and descriptions from ANALYTICS.PLATINUM_LFX_ONE
ORG_LENS_PROJECTS instead of the Insights CDP API. Removes the CDP
batch enrichment path and cache-skip-on-enrichment-failure logic now
that lf-dbt ships these columns (PR #2588).

Signed-off-by: ahmedomosanya <aopeyemi@contractor.linuxfoundation.org>
Copilot AI review requested due to automatic review settings July 3, 2026 20:10

Copilot AI 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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

@MRashad26 MRashad26 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.

Code Review — PR #1065 feat(org-lens): wire org projects page to live data

Overview

Large integration PR (2588+/995−, 14 files). Key changes:

  • New BFF controller + service: org-lens-projects.{controller,service}.ts — 8 REST endpoints (projects list, search, workspace CRUD + add/remove project)
  • Angular OrgProjectsComponent wired to live data: replaces demo-data fixture with real OrgLensProjectsService calls; adds access-guard states (no-org-access, no-company, loading skeleton), async project-search dialog with race-safety, and workspace save/delete with full error handling
  • lfx-multi-select extended with filterBy, panelStyleClass, scrollHeight inputs and filterChange output for async search
  • OrgLensProjectsService (Angular) gains getWorkspaces, createWorkspace, renameWorkspace, deleteWorkspace, addProjectsToWorkspace, removeProjectFromWorkspace, searchProjects
  • Demo-data file deleted; Playwright specs updated for API-stubbed flows

Secrets / critical-constants check ✅

No credentials, tokens, or secrets. DEFAULT_LFX_ONE_PLATINUM_SCHEMA = 'ANALYTICS.PLATINUM_LFX_ONE' is a Snowflake schema name used server-side only; schema names are not credentials (actual Snowflake auth is environment-variable gated). Consistent with existing BFF constants pattern (e.g. VALKEY_CACHE).

Code-standards audit

# Severity Finding
1 🔵 Info tableEmptyState() read 5× in consecutive property bindings — @let would compute once

Angular 20 patterns audit

  • No function calls in templates: all bindings use signal reads (sortIconMap(), loading(), etc.) or property accesses on the table-row view model. @for loops track on i and bar.x — no method calls. ✅
  • No effect(): reactive state wired via toSignal(toObservable(...).pipe(...)), subscribe() in constructor with takeUntilDestroyed(). ✅
  • No @ViewChild/@ViewChildren: not in imports or class. ✅
  • initX() pattern: private initSortField/SortIconMap/AriaSortMap/PageSize/PageFirst/SelectedWorkspaceId/TableEmptyState/WorkspaceDialogErrorMessage all called exclusively inside computed() — not in the template. ✅
  • Type and constant placement: new types (OrgProjectsAriaSort, OrgProjectsEmptyState, AddableProjectOption, Snowflake row shapes, member-service shapes) in org-lens-projects.interface.ts; new runtime constants (INFLUENCE_TREND_TEXT_CLASS, INFLUENCE_TREND_ARROW_BADGE_CLASS, INFLUENCE_TREND_ARROW_ICON, ORG_PROJECTS_SEARCH_MIN_LENGTH, etc.) in org-lens-projects.constants.ts with no export type. ✅
  • HealthScore: extended with 'unavailable'; HEALTH_SCORE_LABELS + HEALTH_SCORE_SEVERITY records updated to match — no missed cases. ✅

BFF security notes

  • assertOrgUid() called on all endpoints before service invocation. ✅
  • readRequiredStringBody / readStringArrayBody type-check all body fields before use. ✅
  • parseSlugList lowercases, deduplicates, and sorts the slug list — normalises user-supplied input before it reaches SQL/service. ✅
  • All mutations return Cache-Control: no-store. ✅
  • removeProjectFromWorkspace validates the :slug path param explicitly. ✅

Code quality notes

  • Race-safe project search via addableProjectsSearchRequestId counter — stale responses from superseded requests are silently discarded before updating state. ✅
  • orgUid$ observable with distinctUntilChanged() + skip(1) closes dialogs on org-context switch without re-triggering on the initial emission. ✅
  • isStillSelectedAccount(accountUid) guard in all async actions prevents stale mutations from updating state if the org changed mid-flight. ✅
  • concat(of(null), serviceCall$) inside initResponse emits null first (clears stale rows) then the real response — avoids briefly showing the previous workspace's rows for the new workspace. ✅
  • trendTooltipHtml rendered with [escape]="false" and annotated as component-authored only — the interface-level comment was strengthened to emphasize it must never be sourced from the wire. ✅

Verdict: PASS ✅ (1 info)

One @let cleanup suggested inline; no critical or warning findings.

Bind the org-projects empty-state block to a single @let-hoisted
tableEmptyState() read instead of evaluating the computed signal in
each of the six bindings.

Reviewer feedback: PR #1065, MRashad26 thread on repeated computed reads.

Signed-off-by: ahmedomosanya <aopeyemi@contractor.linuxfoundation.org>
Copilot AI review requested due to automatic review settings July 6, 2026 13:07
@ahmedomosanya
ahmedomosanya requested a review from MRashad26 July 6, 2026 13:13

Copilot AI 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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment thread packages/shared/src/constants/org-lens-projects.constants.ts
The influence trend text and badge color classes live in
INFLUENCE_TREND_TEXT_CLASS / INFLUENCE_TREND_ARROW_BADGE_CLASS in
@lfx-one/shared, which is outside the Tailwind content scan
(./src/**/*.{html,ts}). Safelist text-emerald-600, text-red-600,
bg-emerald-100, bg-red-100, and bg-gray-100 so they survive JIT
purge, matching the existing fill-* signal-bar safelist convention.

Reviewer feedback: PR #1065, Copilot thread on unsafelisted shared trend classes.

Signed-off-by: ahmedomosanya <aopeyemi@contractor.linuxfoundation.org>
MRashad26
MRashad26 previously approved these changes Jul 6, 2026
luismoriguerra
luismoriguerra previously approved these changes Jul 6, 2026
…ration

Signed-off-by: ahmedomosanya <aopeyemi@contractor.linuxfoundation.org>

# Conflicts:
#	apps/lfx-one/src/server/routes/orgs.route.ts
Copilot AI review requested due to automatic review settings July 6, 2026 15:54
@ahmedomosanya
ahmedomosanya dismissed stale reviews from luismoriguerra and MRashad26 via eac58ab July 6, 2026 15:54

Copilot AI 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.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated no new comments.

@ahmedomosanya
ahmedomosanya requested a review from MRashad26 July 6, 2026 16:22
@ahmedomosanya
ahmedomosanya merged commit 458ecd5 into main Jul 6, 2026
12 checks passed
@ahmedomosanya
ahmedomosanya deleted the feat/LFXV2-1883-integration branch July 6, 2026 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-assisted A task or activity that was supported by AI, such as CoPilot, ChatGPT, or other AI technology. enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants