Skip to content

Conversation

@asithade
Copy link
Contributor

Summary

  • Migrate committees functionality from project-scoped to global architecture
  • Remove project-specific committee routes and components (33 files deleted)
  • Add global committee routes with new view page
  • Update services and components for global committee context
  • Add committee type colors to Tailwind safelist

Related JIRA

LFXV2-765

Changes

Architecture

  • Removed all files from /modules/project/committees/
  • Migrated functionality to /modules/committees/ (global scope)
  • Updated routing to remove project-specific committee routes
  • Added new global committee view route (/:id)

Components

  • Migrated/Updated: committee-dashboard, committee-manage, committee-table, committee-form
  • Added: committee-view, committee-members, member-card, member-form, upcoming-committee-meeting

Services

  • Updated committee.service.ts, meeting.service.ts, project-context.service.ts
  • Modified analytics.service.ts, organization.service.ts, project.service.ts

Impact

  • 52 files changed, 372 insertions, 1130 deletions

Generated with Claude Code

Migrate committees functionality from project-scoped to global architecture:
- Remove project-specific committee routes and components
- Add global committee routes with new view page
- Migrate committee components to global scope
- Update services for global committee context
- Add committee type colors to Tailwind safelist
- Update related components and documentation

LFXV2-765

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <asithade@gmail.com>
Copilot AI review requested due to automatic review settings November 19, 2025 18:43
@asithade asithade requested a review from jordane as a code owner November 19, 2025 18:43
@coderabbitai
Copy link

coderabbitai bot commented Nov 19, 2025

Caution

Review failed

The pull request is closed.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This pull request performs a large-scale refactoring to migrate from projectId to uid as the project identifier across the codebase, restructure committee management routing from project-scoped to app-level standalone routes, and simplify the committee dashboard event model from multiple CRUD event bindings to a single refresh binding with route-based navigation.

Changes

Cohort / File(s) Summary
Committee Module (App-Level) - Dashboard & Routes
apps/lfx-one/src/app/modules/committees/committee-dashboard/committee-dashboard.component.html, committee-dashboard.component.ts, committees.routes.ts
Replaced multiple event bindings (viewCommittee, editCommittee, deleteCommittee, addMember) with single (refresh) binding; updated empty-state condition from projectId to uid; made refreshCommittees() public; removed confirmation dialog markup; simplified category label from pluralized to generic "All Types".
Committee Module (App-Level) - Table Component
apps/lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.html, committee-table.component.ts
Converted view/edit actions to route-based navigation via routerLink (e.g., /groups/{uid}, /groups/{uid}/edit); removed multiple event outputs (viewCommittee, editCommittee, deleteCommittee, addMember) and added single refresh output; implemented dialog-based member addition and confirmation-based deletion; converted isDeleting from input to internal signal.
Committee Module (App-Level) - Supporting Components
apps/lfx-one/src/app/modules/committees/components/committee-form/committee-form.component.ts, member-form/member-form.component.ts, upcoming-committee-meeting/upcoming-committee-meeting.component.ts, committee-manage/committee-manage.component.ts, committee-view/committee-view.component.ts
Updated to use getProjectUid() instead of getProjectId(); added HTTP 409 error handling in member-form; replaced ProjectService with ProjectContextService in committee-view; added route for viewing specific committee.
Committee Module (Project-Level) - Removed
apps/lfx-one/src/app/modules/project/committees/committee-dashboard/committee-dashboard.component.html, committee-dashboard.component.ts, committees.routes.ts, components/committee-table/committee-table.component.html, committee-table.component.ts, apps/lfx-one/src/app/modules/project/project.routes.ts
Deleted entire project-scoped committee dashboard and table components; removed committees route from project routes.
Meeting Components
apps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.html, meetings-dashboard/meetings-dashboard.component.html, meetings-dashboard.component.ts, meeting-manage/meeting-manage.component.ts, meeting-committee-modal/meeting-committee-modal.component.ts, meeting-type-selection/meeting-type-selection.component.ts, components/meeting-card/meeting-card.component.ts
Updated to use uid instead of projectId in project context checks and API calls; gated join button behind authentication; conditioned recording/summary initialization to past meetings only.
Dashboard Components
apps/lfx-one/src/app/modules/dashboards/components/my-meetings/my-meetings.component.ts, organization-involvement/organization-involvement.component.ts, my-projects/my-projects.component.html
Refactored my-meetings with ProjectContextService integration and reactive loading with initializer methods; updated project identifier from projectId to uid in default data; changed spinner color class.
Settings Components
apps/lfx-one/src/app/modules/settings/components/user-form/user-form.component.ts, user-permissions-table/user-permissions-table.component.ts, settings-dashboard/settings-dashboard.component.ts
Updated permissions service calls to use uid instead of projectId; enhanced error handling in settings-dashboard to return empty array on error.
Shared Components
apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts, persona-selector/persona-selector.component.ts
Updated project context construction to use uid instead of projectId in project selection and foundation handling.
Services (Client)
apps/lfx-one/src/app/shared/services/committee.service.ts, meeting.service.ts, project-context.service.ts, analytics.service.ts
Updated method signatures: getProjectId()getProjectUid(); committee service methods now use uid parameter; meeting service methods use uid and updated HTTP params to project_uid; added error handling to getMeetingsCountByProject; updated analytics fallback response to use uid.
Services (Backend)
apps/lfx-one/src/server/services/organization.service.ts, project.service.ts
Updated method signatures to use uid instead of projectId in getProjectById, getProjectSettings, updateProjectPermissions; changed public data shapes to expose uid field; updated slug-resolution to use uid.
Shared Interfaces & Constants
packages/shared/src/interfaces/analytics-data.interface.ts, project.interface.ts, packages/shared/src/constants/committees.constants.ts
Updated BoardMemberDashboardResponse and ProjectsListResponse interfaces to use uid instead of projectId; updated ProjectSlugToIdResponse and ProjectContext interfaces to use uid; changed committee "finance" category color from amber to emerald.
Documentation & Configuration
apps/lfx-one/tailwind.config.js, docs/architecture/backend/logging-monitoring.md, docs/architecture/backend/nats-integration.md
Extended Tailwind safelist with committee color utilities; updated example logs and NATS integration docs to use uid instead of projectId.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CommitteeDashboard
    participant CommitteeTable
    participant Router
    participant CommitteeService
    
    Note over User,CommitteeService: Old Flow (Event Emitters)
    User->>CommitteeTable: Click View
    CommitteeTable->>CommitteeTable: onViewCommittee()
    CommitteeTable->>CommitteeDashboard: emit viewCommittee
    CommitteeDashboard->>CommitteeDashboard: onViewCommittee()
    CommitteeDashboard->>Router: navigate()
    
    User->>CommitteeTable: Click Edit
    CommitteeTable->>CommitteeTable: onEditCommittee()
    CommitteeTable->>CommitteeDashboard: emit editCommittee
    CommitteeDashboard->>CommitteeDashboard: onEditCommittee()
    CommitteeDashboard->>Router: navigate()
    
    User->>CommitteeTable: Click Delete
    CommitteeTable->>CommitteeDashboard: emit deleteCommittee
    CommitteeDashboard->>CommitteeDashboard: onDeleteCommittee()
    CommitteeDashboard->>CommitteeService: deleteCommittee()
    CommitteeDashboard->>CommitteeDashboard: refreshCommittees()
Loading
sequenceDiagram
    participant User
    participant CommitteeTable
    participant Router
    participant ConfirmationService
    participant CommitteeService
    participant CommitteeTable2 as CommitteeTable<br/>(refresh)
    
    Note over User,CommitteeTable2: New Flow (Route-Based Navigation & Refresh)
    User->>CommitteeTable: Click View (anchor)
    CommitteeTable->>Router: routerLink /groups/{uid}
    Router->>Router: navigate
    
    User->>CommitteeTable: Click Edit (routerLink)
    CommitteeTable->>Router: routerLink /groups/{uid}/edit
    Router->>Router: navigate
    
    User->>CommitteeTable: Click Delete (button)
    CommitteeTable->>ConfirmationService: confirm()
    ConfirmationService->>User: Show confirmation dialog
    User->>ConfirmationService: Accept
    ConfirmationService->>CommitteeService: deleteCommittee()
    CommitteeService->>CommitteeTable2: success
    CommitteeTable2->>CommitteeTable2: refresh()
    CommitteeTable2->>CommitteeDashboard: emit refresh
    CommitteeDashboard->>CommitteeDashboard: refreshCommittees()
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Systematic parameter renaming (projectIduid): While repetitive across 40+ files, the renaming requires verification that all call sites and consumers are updated consistently across frontend services, backend services, and interfaces.
  • Committee module restructuring: The migration from project-scoped to app-level standalone routes with removal of old components and event-based refactoring to route-based navigation requires careful verification of routing integrity and component state management.
  • My-meetings component refactoring: The introduction of reactive loading with initializer methods and ProjectContextService integration introduces new signal-based state management patterns that require review.
  • Service API changes: Multiple service methods have signature changes (method names and parameters); all call sites must be verified for consistency.
  • Verification of edge cases: Confirmation dialog behavior, error handling paths (e.g., HTTP 409 in member-form, empty array fallback in settings-dashboard), and loading state management in new reactive patterns.

Possibly related PRs

Suggested labels

deploy-preview

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely captures the main architectural change: migrating committees from project-scoped to global architecture, which is the primary objective of this large refactoring PR.
Description check ✅ Passed The description is well-related to the changeset, providing a clear summary of the architectural migration, listing affected files, components, services, and measurable impact. It directly describes the scope and nature of changes.
Linked Issues check ✅ Passed The PR successfully implements all major objectives from LFXV2-765: removes 33 files from project-scoped committees, migrates to global architecture, updates routing with new /:id view route, migrates and adds required components, updates services for global context, and adds Tailwind styling.
Out of Scope Changes check ✅ Passed All changes appear directly aligned with LFXV2-765 objectives. The refactoring systematically migrates committees to global scope, updates identifier usage from projectId to uid throughout codebase and services, and includes necessary documentation and styling updates that support the architectural change.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fcdd879 and 1dc1636.

📒 Files selected for processing (5)
  • apps/lfx-one/src/app/modules/committees/committee-dashboard/committee-dashboard.component.html (2 hunks)
  • apps/lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.html (4 hunks)
  • apps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.html (2 hunks)
  • apps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.html (2 hunks)
  • apps/lfx-one/src/app/modules/meetings/meetings-dashboard/meetings-dashboard.component.ts (2 hunks)

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

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This pull request migrates committees functionality from project-scoped to global architecture. The main changes include renaming projectId to uid across interfaces and services for consistency, removing 33 project-specific committee files, and adding new global committee routes and components.

Key Changes:

  • Renamed projectId to uid across interfaces, services, and components for consistency
  • Removed project-specific committee routes (/project/:slug/committees)
  • Added global committee routes (/groups/:id) with new view page
  • Updated committee components to work in global context
  • Added committee type colors to Tailwind safelist for dynamic styling

Reviewed Changes

Copilot reviewed 42 out of 52 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/shared/src/interfaces/project.interface.ts Renamed projectId to uid in ProjectSlugToIdResponse and ProjectContext interfaces
packages/shared/src/interfaces/analytics-data.interface.ts Renamed projectId to uid in analytics interfaces
packages/shared/src/constants/committees.constants.ts Changed finance committee color from amber to emerald
docs/architecture/backend/*.md Updated documentation to reflect uid naming
apps/lfx-one/tailwind.config.js Added committee type colors (emerald, pink, orange) to safelist
apps/lfx-one/src/server/services/*.ts Updated services to use uid parameter name
apps/lfx-one/src/app/shared/services/*.service.ts Renamed methods and parameters from projectId to uid
apps/lfx-one/src/app/modules/meetings/*.ts Updated meeting components to use uid and improved SSR handling
apps/lfx-one/src/app/modules/committees/* Major refactor of committee components for global scope
apps/lfx-one/src/app/modules/project/committees/* Removed 33 project-scoped committee files
apps/lfx-one/src/app/modules/project/project.routes.ts Removed project-specific committee routes
Comments suppressed due to low confidence (1)

apps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.ts:127

  • [nitpick] The error message 'Member already exists' could be more helpful by indicating what action the user should take. Consider changing to 'This member is already part of the committee' or 'A member with this email already exists in the committee' for better clarity.

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

Remove afterNextRender wrapper from meeting-join component as toSignal
already handles SSR properly with initialValue options.

LFXV2-765

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <asithade@gmail.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (2)
apps/lfx-one/src/server/services/project.service.ts (1)

69-103: Critical bug: getProjectById uses incorrect tags format

The code at line 72 passes a bare uid to the query service, but the rest of the codebase—including other calls in the same controller—uses the namespaced format project_uid:${uid}:

project.service.ts:72         tags: uid                           ← BARE UUID (WRONG)
project.controller.ts:36-37   tags: `project_uid:${project.uid}` ← NAMESPACED (CORRECT)
project.controller.ts:87-88   tags: `project_uid:${project.uid}` ← NAMESPACED (CORRECT)

Consistent pattern across all services:
- committee.service.ts:84      tags: `committee_uid:${committeeId}`
- meeting.service.ts:261       tags: `meeting_uid:${meetingUid}`
- meeting.service.ts:333       tags: `email:${email}`

The query service expects namespaced tags. The bare uid format will not match the indexing and likely causes silent failures or empty results.

Fix: Change line 72 to tags: \project_uid:${uid}``

apps/lfx-one/src/app/modules/committees/committees.routes.ts (1)

20-29: Critical route ordering issue: :id/edit must come before :id.

Angular's router matches routes sequentially. With the current order, a navigation to /committees/<uid>/edit will incorrectly match the :id route (treating 'edit' as the id parameter) before reaching :id/edit. This breaks the edit functionality.

Apply this diff to fix the route order:

   {
     path: 'create',
     loadComponent: () => import('./committee-manage/committee-manage.component').then((m) => m.CommitteeManageComponent),
     canActivate: [authGuard],
   },
+  {
+    path: ':id/edit',
+    loadComponent: () => import('./committee-manage/committee-manage.component').then((m) => m.CommitteeManageComponent),
+    canActivate: [authGuard],
+  },
   {
     path: ':id',
     loadComponent: () => import('./committee-view/committee-view.component').then((m) => m.CommitteeViewComponent),
     canActivate: [authGuard],
   },
-  {
-    path: ':id/edit',
-    loadComponent: () => import('./committee-manage/committee-manage.component').then((m) => m.CommitteeManageComponent),
-    canActivate: [authGuard],
-  },
🧹 Nitpick comments (5)
apps/lfx-one/src/app/modules/meetings/components/meeting-committee-modal/meeting-committee-modal.component.ts (1)

61-77: <!-- [scratchpad_start]
[task verify_modal_opening_context 6/7]
Final key evidence gathered:

ProjectContextService analysis:

  • selectedProject and selectedFoundation are WritableSignals (can change at any time)
  • No mechanism to lock context while modal is open
  • Can be changed via setProject() or setFoundation() methods

Dashboard validation:

  • Checks !project?.uid before loading meetings (lines 88-89)
  • Meetings only shown when valid project exists
  • BUT: Nothing prevents context from changing after modal opens

Route structure:

  • Only authGuard, no project context guard
  • Project context is globally mutable, not route-protected

[observations]

  • Modal opens from meeting-card component (which is rendered by dashboard)
  • toSignal subscribes immediately on MeetingCommitteeModalComponent init
  • If projectContextService.getProjectUid() becomes falsy after modal opens, API will be called with empty UID
  • This is an edge case but technically possible: user could clear project context while modal is opening
  • Meeting data passed to modal (line 209 in meeting-card) could theoretically be used as fallback

[analysis]

  • Original review concern is VALID but describes an edge case
  • In normal UX flow, unlikely to occur (modal is blocking)
  • However, projectContextService is globally mutable with no guards
  • Suggestion to guard against empty UID is reasonable defensive programming
  • Alternative: Could extract projectUid from meeting data if meeting is tied to project

[conclusion]
Original review is accurate. The suggestion to guard against missing project context is valid and represents reasonable defensive programming. This is an OPTIONAL refactoring (not critical bug, but good practice).

[done]
Verification complete. Original review is correct and justified.

Remove redundant loading.set(false) calls in catchError blocks and rely
on finalize as the single cleanup point for both upcoming and past
meetings initialization.

LFXV2-765

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <asithade@gmail.com>
@asithade asithade merged commit 7829da9 into main Nov 19, 2025
6 of 7 checks passed
@asithade asithade deleted the refactor/LFXV2-765 branch November 19, 2025 19:12
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.

3 participants