-
Notifications
You must be signed in to change notification settings - Fork 0
feat(meetings): enhance meeting registrants and committee management #213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Add meeting committee manager component with multi-select dropdown - Enhance meeting registrants display with search and filtering - Add feature toggle shared component for form configurations - Update committee module UI with table and member card improvements - Add server API enhancements for meeting registrants - Update dashboard and shared components with avatar/header improvements LFXV2-926 LFXV2-927 LFXV2-928 LFXV2-929 LFXV2-930 LFXV2-931 Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Asitha de Silva <asithade@gmail.com>
|
Note Other AI code review bot(s) detectedCodeRabbit 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. WalkthroughAdds "Show Attendees" meeting feature across frontend and backend, a new MeetingCommitteeManager UI, reusable FeatureToggle component, LinkedIn profile support for registrants, committee settings persistence, and a new backend endpoint to return enriched, access-controlled registrants. Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (4)**/*.{ts,tsx,js,jsx,css,scss}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
apps/lfx-one/src/**/*.ts📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🔇 Additional comments (2)
Comment |
Signed-off-by: Asitha de Silva <asithade@gmail.com>
There was a problem hiding this 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 PR enhances meeting management capabilities by adding comprehensive registrant display features, committee integration, and improved UI components. The changes enable meeting organizers to better manage attendees through search, filtering, and role-based access control while introducing a new feature toggle component for consistent configuration across the application.
Key Changes
- Meeting Registrants Enhancement: Added search functionality, RSVP filtering (accepted/declined/pending), and role-based filtering with enriched committee member information including LinkedIn profiles
- Committee Integration: New meeting committee manager component with multi-select dropdown for associating committees with meetings, including voting status filtering
- Access Control: Implemented
/my-meeting-registrantsendpoint with access control based onshow_meeting_attendeessetting, ensuring only invited users can view attendee lists
Reviewed changes
Copilot reviewed 47 out of 47 changed files in this pull request and generated 17 comments.
Show a summary per file
| File | Description |
|---|---|
packages/shared/src/interfaces/meeting.interface.ts |
Added show_meeting_attendees field and committee-related fields for meeting registrants (committee_name, committee_role, committee_category, etc.) |
packages/shared/src/interfaces/components.interface.ts |
Added FeatureConfig interface for the new feature toggle component |
packages/shared/src/constants/validation.constants.ts |
Added LinkedIn profile URL validation pattern |
packages/shared/src/constants/meeting.constants.ts |
Added feature toggle configurations for recurring meetings, restricted meetings, and show attendees |
apps/lfx-one/src/server/services/meeting.service.ts |
Enhanced registrant fetching to support both V1 and V2 meetings with proper type detection |
apps/lfx-one/src/server/services/committee.service.ts |
Added committee settings fetch/update methods with support for new show_meeting_attendees and member_visibility fields |
apps/lfx-one/src/server/routes/meetings.route.ts |
Added new /my-meeting-registrants endpoint for access-controlled registrant viewing |
apps/lfx-one/src/server/middleware/auth.middleware.ts |
Reduced authentication logging verbosity from success to debug level |
apps/lfx-one/src/server/controllers/meeting.controller.ts |
Implemented getMyMeetingRegistrants with access control and enrichCommitteeRegistrants for committee data enrichment |
apps/lfx-one/src/app/shared/services/meeting.service.ts |
Added getMyMeetingRegistrants method and LinkedIn profile validation to registrant forms |
apps/lfx-one/src/app/shared/components/header/header.component.ts |
Fixed profile loading to only fetch when user is authenticated |
apps/lfx-one/src/app/shared/components/feature-toggle/* |
New reusable feature toggle component for consistent feature configuration UI |
apps/lfx-one/src/app/shared/components/avatar/avatar.component.ts |
Cleaned up deprecated customClass property, now uses styleClass consistently |
apps/lfx-one/src/app/modules/meetings/meeting-manage/* |
Added show_meeting_attendees field to meeting form and updated navigation flow after creation |
apps/lfx-one/src/app/modules/meetings/meeting-join/* |
Implemented drawer for registrants display with "Show Members" button for invited users |
apps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/* |
New component for selecting committees and managing committee member invitations with voting status filtering |
apps/lfx-one/src/app/modules/meetings/components/meeting-registrants-manager/* |
Integrated committee manager and show attendees toggle, updated to hide committee-type registrants from direct guest list |
apps/lfx-one/src/app/modules/meetings/components/meeting-registrants-display/* |
Added search, RSVP filtering, role filtering, and group filtering with enhanced card-based registrant display |
apps/lfx-one/src/app/modules/meetings/components/registrant-form/* |
Added LinkedIn profile field with validation |
apps/lfx-one/src/app/modules/meetings/components/meeting-type-selection/* |
Refactored to use new feature toggle component |
apps/lfx-one/src/app/modules/meetings/components/meeting-details/* |
Moved recurring meeting toggle to use feature toggle component, reorganized form layout |
apps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/* |
Refactored to use feature toggle component for all platform features |
apps/lfx-one/src/app/modules/dashboards/components/* |
Updated dashboard components with icon improvements and show attendees indicator |
apps/lfx-one/src/app/modules/committees/components/committee-table/* |
Migrated from custom table to lfx-table component with pagination support |
apps/lfx-one/src/app/modules/committees/components/member-card/* |
Simplified avatar property usage |
apps/lfx-one/src/app/modules/committees/components/member-form/* |
Updated to use shared LinkedIn validation pattern |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
apps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.ts
Show resolved
Hide resolved
...les/meetings/components/meeting-registrants-manager/meeting-registrants-manager.component.ts
Show resolved
Hide resolved
...les/meetings/components/meeting-registrants-display/meeting-registrants-display.component.ts
Show resolved
Hide resolved
...modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.ts
Outdated
Show resolved
Hide resolved
...modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.ts
Show resolved
Hide resolved
...modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.ts
Show resolved
Hide resolved
...modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
apps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.html (1)
33-38: Inconsistent header padding.The "Non-Code Activities" header uses
py-2while all other headers usepy-4. This appears to be an oversight that creates uneven vertical padding in the header row.🔎 Proposed fix
- <th class="text-left py-2 px-4 text-xs font-medium text-gray-500 w-1/4"> + <th class="text-left py-4 px-4 text-xs font-medium text-gray-500 w-1/4">apps/lfx-one/src/server/middleware/auth.middleware.ts (3)
112-134: Critical: Undefined variableisOptionalRoutecauses ReferenceError.The function parameter was renamed from
isOptionalRoutetoattemptRefresh(line 87), but lines 116, 120, and 127 still reference the oldisOptionalRoutevariable. This will throw aReferenceErrorat runtime whenever token refresh fails.🔎 Proposed fix
You need to either derive
isOptionalRoutefromattemptRefreshor use the parameter directly. Based on the intended semantics (lines 94-101),attemptRefresh = falsecorresponds to optional routes:} catch (refreshError) { // Different handling based on route type: // - Optional routes: Log warning and continue without token (no logout) // - Required routes: Log error and force logout to re-authenticate + const isOptionalRoute = !attemptRefresh; if (isOptionalRoute) { logger.warning(req, 'token_extraction', 'Token refresh failed on optional route - continuing without token', {
82-86: Update JSDoc to reflect parameter rename.The JSDoc comment still references the old parameter name
isOptionalRoute, but the parameter was renamed toattemptRefreshon line 87.🔎 Proposed fix
/** * Extracts bearer token from OIDC session if available * @param req - Express request object - * @param isOptionalRoute - Whether this is an optional auth route (affects logout behavior on refresh failure) + * @param attemptRefresh - Whether to attempt token refresh if expired (default true) */
365-369: Critical:extractBearerTokenhas undefined variable references and inverted token refresh logic.The function parameter is named
attemptRefresh, but the implementation references undefined variableisOptionalRoutein the error handler (lines 115-127), which will cause a ReferenceError at runtime. Additionally, the call at line 366 passesisOptionalRoutedirectly, inverting the intended refresh behavior:
- For optional routes:
isOptionalRoute=true→attemptRefresh=true→!attemptRefresh=false→ refresh IS attempted (contradicts the skip path at line 95)- For required routes:
isOptionalRoute=false→attemptRefresh=false→!attemptRefresh=true→ refresh IS skipped (opposite of intention)Fix: Either rename the parameter to
isOptionalRouteand update the skip condition toif (isOptionalRoute), or pass!isOptionalRouteat the call site and ensure the error handler uses the correct parameter name.
🧹 Nitpick comments (10)
apps/lfx-one/src/app/modules/dashboards/components/recent-progress/recent-progress.component.html (1)
7-10: Nice improvement – emoji replaced with Font Awesome icon.The change from emoji to Font Awesome icon improves visual consistency with other icons in the component.
Consider adding
aria-hidden="true"to the icon element for better accessibility, since it's decorative and the adjacent text provides the meaning.🔎 Optional accessibility enhancement
<h2> - <i class="fa-light fa-chart-line text-lg"></i> + <i class="fa-light fa-chart-line text-lg" aria-hidden="true"></i> Recent Progress </h2>packages/shared/src/interfaces/components.interface.ts (1)
6-27: Well-documentedFeatureConfiginterface for the feature toggle component.The interface provides a clean configuration structure. One minor consideration:
Optional type improvement: The
trueValueandfalseValueproperties useanytype. Consider using a generic or a union type for better type safety if the value types are known (e.g.,boolean | string).export interface FeatureConfig<T = boolean> { // ...existing fields... trueValue?: T; falseValue?: T; }However,
anyis acceptable here for maximum configuration flexibility.packages/shared/src/constants/validation.constants.ts (1)
29-29: Consider refining the LinkedIn profile pattern for robustness.The current regex has several considerations:
Case sensitivity: The subdomain pattern
[a-z]{2,3}only matches lowercase letters, which may reject valid URLs likeUK.linkedin.comor mixed-case variations that browsers accept.Protocol security: The pattern allows
http://which is less secure thanhttps://. Modern LinkedIn always uses HTTPS, so consider enforcing it or at least documenting why HTTP is permitted.Path validation: The wildcard
.*$is permissive and allows any characters including spaces or special characters. Consider using[^\\s]+or.+to prevent empty paths and ensure at least one valid character.Empty path edge case: The pattern technically matches
linkedin.com/with nothing after the slash due to.*(zero or more). The documentation states "must have content after the domain," but the regex allows zero-length content.Proposed refinement
-export const LINKEDIN_PROFILE_PATTERN = /^(https?:\/\/)?([a-z]{2,3}\.)?linkedin\.com\/.*$/; +export const LINKEDIN_PROFILE_PATTERN = /^(https?:\/\/)?([a-zA-Z]{2,3}\.)?linkedin\.com\/.+$/i;Changes:
[a-zA-Z]accepts both cases for subdomains.+requires at least one character after the domain/iflag for case-insensitive matching (optional, but makes the pattern more forgiving)Or, if you want to enforce HTTPS:
-export const LINKEDIN_PROFILE_PATTERN = /^(https?:\/\/)?([a-z]{2,3}\.)?linkedin\.com\/.*$/; +export const LINKEDIN_PROFILE_PATTERN = /^(https:\/\/)?([a-zA-Z]{2,3}\.)?linkedin\.com\/.+$/i;apps/lfx-one/src/app/modules/dashboards/components/dashboard-meeting-card/dashboard-meeting-card.component.html (1)
67-75: Consider using a distinct icon to avoid confusion.The "Show Attendees" feature uses the
fa-usersicon (line 73), which is identical to the "Public Meeting" icon (line 82). This creates visual ambiguity when both features are enabled, making it difficult for users to distinguish between the two at a glance.Suggested icon alternatives
Consider using a more distinct icon for "Show Attendees", such as:
fa-eyeorfa-eye-slashto represent visibility/showingfa-user-groupfor a slight visual distinctionfa-users-viewfinderto emphasize the "view attendees" aspectfa-list-checkto represent an attendee listExample:
- <i class="fa-light fa-users text-xs text-gray-700"></i> + <i class="fa-light fa-eye text-xs text-gray-700"></i>apps/lfx-one/src/app/modules/meetings/components/registrant-form/registrant-form.component.html (1)
127-138: Consider adding validation error messages for LinkedIn profile field.The LinkedIn Profile field is correctly structured and follows the pattern of other form fields. However, unlike the email field (lines 92-97), it lacks validation error messages. If the
LINKEDIN_PROFILE_PATTERNvalidation is applied in the TypeScript component, users won't receive feedback when they enter an invalid URL.Add validation error display
<lfx-input-text size="small" [form]="form()" control="linkedin_profile" label="LinkedIn Profile" placeholder="Enter LinkedIn profile URL" data-testid="registrant-form-linkedin-profile-input"> </lfx-input-text> + @if (form().get('linkedin_profile')?.errors?.['pattern'] && form().get('linkedin_profile')?.touched && form().get('linkedin_profile')?.dirty) { + <p class="text-sm text-red-500">Please enter a valid LinkedIn profile URL</p> + } </div>packages/shared/src/constants/meeting.constants.ts (1)
431-489: Well-structured feature toggle configurations with good documentation.The new constants follow the established patterns and include appropriate JSDoc comments. The color references correctly use
lfxColorsfrom the shared constants.One consideration:
MEETING_DURATION_OPTIONSmixesnumbervalues with astringvalue ('custom'). This is intentional for UI handling but consider adding a TypeScript type annotation for clarity.🔎 Optional: Add explicit type annotation
+interface DurationOption { + label: string; + value: number | 'custom'; +} + -export const MEETING_DURATION_OPTIONS = [ +export const MEETING_DURATION_OPTIONS: DurationOption[] = [ { label: '15 minutes', value: 15 }, { label: '30 minutes', value: 30 }, { label: '60 minutes', value: 60 }, { label: '90 minutes', value: 90 }, { label: '120 minutes', value: 120 }, { label: 'Custom...', value: 'custom' }, ];apps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.html (1)
95-99: Consider defensive check for committees array access.Accessing
committeeForm.value.committees.lengthdirectly could throw if the control value is null/undefined.🔎 Suggested defensive access
- @if (committeeForm.value.committees.length > 1) { + @if (committeeForm.value.committees?.length > 1) {Apply the same pattern at line 121:
- @if (committeeForm.value.committees.length > 1) { + @if (committeeForm.value.committees?.length > 1) {apps/lfx-one/src/server/services/committee.service.ts (1)
381-391: Consider logging the error details for debugging.The catch block discards the error details. While returning an empty object is the right fallback, logging the actual error (even at debug level) would help with troubleshooting.
🔎 Optional: Include error details in log
- } catch { + } catch (error) { logger.debug(req, 'get_committee_settings', 'Failed to fetch committee settings, returning empty', { committee_uid: committeeId, + error: error instanceof Error ? error.message : String(error), }); return {}; }apps/lfx-one/src/app/modules/meetings/components/meeting-registrants-display/meeting-registrants-display.component.ts (1)
214-257: Consider extracting RSVP status logic to a shared utility.The RSVP matching logic (lines 232-246) duplicates what likely exists in the template. Consider extracting the status determination to a shared utility function for consistency and reusability.
apps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.ts (1)
123-123: Remove empty ngOnInit and OnInit implementation.The
ngOnInitmethod is empty and can be removed along with theOnInitimplementation from the class declaration.🔎 Proposed fix
-import { Component, computed, DestroyRef, inject, input, InputSignal, OnInit, output, OutputEmitterRef, signal, Signal, WritableSignal } from '@angular/core'; +import { Component, computed, DestroyRef, inject, input, InputSignal, output, OutputEmitterRef, signal, Signal, WritableSignal } from '@angular/core'; ... -export class MeetingCommitteeManagerComponent implements OnInit { +export class MeetingCommitteeManagerComponent { ... - public ngOnInit(): void {}
📜 Review details
Configuration used: Organization 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.
📒 Files selected for processing (47)
.vscode/settings.jsonapps/lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.htmlapps/lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.tsapps/lfx-one/src/app/modules/committees/components/member-card/member-card.component.htmlapps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.tsapps/lfx-one/src/app/modules/dashboards/components/dashboard-meeting-card/dashboard-meeting-card.component.htmlapps/lfx-one/src/app/modules/dashboards/components/dashboard-meeting-card/dashboard-meeting-card.component.tsapps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.htmlapps/lfx-one/src/app/modules/dashboards/components/recent-progress/recent-progress.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-card/meeting-card.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-card/meeting-card.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-display/meeting-registrants-display.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-display/meeting-registrants-display.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-manager/meeting-registrants-manager.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-manager/meeting-registrants-manager.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-resources-summary/meeting-resources-summary.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-type-selection/meeting-type-selection.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-type-selection/meeting-type-selection.component.tsapps/lfx-one/src/app/modules/meetings/components/registrant-card/registrant-card.component.tsapps/lfx-one/src/app/modules/meetings/components/registrant-form/registrant-form.component.htmlapps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.htmlapps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.tsapps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.htmlapps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.tsapps/lfx-one/src/app/shared/components/avatar/avatar.component.htmlapps/lfx-one/src/app/shared/components/avatar/avatar.component.tsapps/lfx-one/src/app/shared/components/feature-toggle/feature-toggle.component.htmlapps/lfx-one/src/app/shared/components/feature-toggle/feature-toggle.component.tsapps/lfx-one/src/app/shared/components/header/header.component.tsapps/lfx-one/src/app/shared/services/meeting.service.tsapps/lfx-one/src/server/controllers/meeting.controller.tsapps/lfx-one/src/server/middleware/auth.middleware.tsapps/lfx-one/src/server/routes/meetings.route.tsapps/lfx-one/src/server/services/committee.service.tsapps/lfx-one/src/server/services/meeting.service.tspackages/shared/src/constants/index.tspackages/shared/src/constants/meeting.constants.tspackages/shared/src/constants/validation.constants.tspackages/shared/src/interfaces/components.interface.tspackages/shared/src/interfaces/meeting.interface.tspackages/shared/src/utils/meeting.utils.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx,js,jsx,css,scss}
📄 CodeRabbit inference engine (CLAUDE.md)
Always include license headers on all source files - run ./check-headers.sh to verify
Files:
packages/shared/src/interfaces/components.interface.tsapps/lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.tspackages/shared/src/constants/validation.constants.tsapps/lfx-one/src/app/modules/meetings/components/meeting-card/meeting-card.component.tsapps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.tspackages/shared/src/constants/meeting.constants.tsapps/lfx-one/src/server/services/meeting.service.tsapps/lfx-one/src/app/modules/dashboards/components/dashboard-meeting-card/dashboard-meeting-card.component.tsapps/lfx-one/src/app/shared/components/feature-toggle/feature-toggle.component.tsapps/lfx-one/src/server/routes/meetings.route.tsapps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.tspackages/shared/src/interfaces/meeting.interface.tspackages/shared/src/constants/index.tsapps/lfx-one/src/app/shared/components/header/header.component.tsapps/lfx-one/src/server/controllers/meeting.controller.tsapps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.tsapps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-manager/meeting-registrants-manager.component.tsapps/lfx-one/src/server/middleware/auth.middleware.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-display/meeting-registrants-display.component.tspackages/shared/src/utils/meeting.utils.tsapps/lfx-one/src/app/modules/meetings/components/registrant-card/registrant-card.component.tsapps/lfx-one/src/server/services/committee.service.tsapps/lfx-one/src/app/modules/meetings/components/meeting-type-selection/meeting-type-selection.component.tsapps/lfx-one/src/app/shared/components/avatar/avatar.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-resources-summary/meeting-resources-summary.component.tsapps/lfx-one/src/app/shared/services/meeting.service.tsapps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.tsapps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Always use async/await for promises instead of .then() chains in TypeScript services
Use TypeScript interfaces instead of union types for better maintainability
Files:
packages/shared/src/interfaces/components.interface.tsapps/lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.tspackages/shared/src/constants/validation.constants.tsapps/lfx-one/src/app/modules/meetings/components/meeting-card/meeting-card.component.tsapps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.tspackages/shared/src/constants/meeting.constants.tsapps/lfx-one/src/server/services/meeting.service.tsapps/lfx-one/src/app/modules/dashboards/components/dashboard-meeting-card/dashboard-meeting-card.component.tsapps/lfx-one/src/app/shared/components/feature-toggle/feature-toggle.component.tsapps/lfx-one/src/server/routes/meetings.route.tsapps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.tspackages/shared/src/interfaces/meeting.interface.tspackages/shared/src/constants/index.tsapps/lfx-one/src/app/shared/components/header/header.component.tsapps/lfx-one/src/server/controllers/meeting.controller.tsapps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.tsapps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-manager/meeting-registrants-manager.component.tsapps/lfx-one/src/server/middleware/auth.middleware.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-display/meeting-registrants-display.component.tspackages/shared/src/utils/meeting.utils.tsapps/lfx-one/src/app/modules/meetings/components/registrant-card/registrant-card.component.tsapps/lfx-one/src/server/services/committee.service.tsapps/lfx-one/src/app/modules/meetings/components/meeting-type-selection/meeting-type-selection.component.tsapps/lfx-one/src/app/shared/components/avatar/avatar.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-resources-summary/meeting-resources-summary.component.tsapps/lfx-one/src/app/shared/services/meeting.service.tsapps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.tsapps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Do not nest ternary expressions
Files:
packages/shared/src/interfaces/components.interface.tsapps/lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.tspackages/shared/src/constants/validation.constants.tsapps/lfx-one/src/app/modules/meetings/components/meeting-card/meeting-card.component.tsapps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.tspackages/shared/src/constants/meeting.constants.tsapps/lfx-one/src/server/services/meeting.service.tsapps/lfx-one/src/app/modules/dashboards/components/dashboard-meeting-card/dashboard-meeting-card.component.tsapps/lfx-one/src/app/shared/components/feature-toggle/feature-toggle.component.tsapps/lfx-one/src/server/routes/meetings.route.tsapps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.tspackages/shared/src/interfaces/meeting.interface.tspackages/shared/src/constants/index.tsapps/lfx-one/src/app/shared/components/header/header.component.tsapps/lfx-one/src/server/controllers/meeting.controller.tsapps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.tsapps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-manager/meeting-registrants-manager.component.tsapps/lfx-one/src/server/middleware/auth.middleware.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-display/meeting-registrants-display.component.tspackages/shared/src/utils/meeting.utils.tsapps/lfx-one/src/app/modules/meetings/components/registrant-card/registrant-card.component.tsapps/lfx-one/src/server/services/committee.service.tsapps/lfx-one/src/app/modules/meetings/components/meeting-type-selection/meeting-type-selection.component.tsapps/lfx-one/src/app/shared/components/avatar/avatar.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-resources-summary/meeting-resources-summary.component.tsapps/lfx-one/src/app/shared/services/meeting.service.tsapps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.tsapps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.ts
packages/shared/src/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
All shared types, interfaces, and constants must be centralized in @lfx-one/shared package
Files:
packages/shared/src/interfaces/components.interface.tspackages/shared/src/constants/validation.constants.tspackages/shared/src/constants/meeting.constants.tspackages/shared/src/interfaces/meeting.interface.tspackages/shared/src/constants/index.tspackages/shared/src/utils/meeting.utils.ts
apps/lfx-one/src/**/*.component.ts
📄 CodeRabbit inference engine (CLAUDE.md)
apps/lfx-one/src/**/*.component.ts: Use zoneless change detection and signals in Angular 19 components instead of zone.js
Use direct imports for standalone components - no barrel exports
Files:
apps/lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-card/meeting-card.component.tsapps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.tsapps/lfx-one/src/app/modules/dashboards/components/dashboard-meeting-card/dashboard-meeting-card.component.tsapps/lfx-one/src/app/shared/components/feature-toggle/feature-toggle.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.tsapps/lfx-one/src/app/shared/components/header/header.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.tsapps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-manager/meeting-registrants-manager.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-display/meeting-registrants-display.component.tsapps/lfx-one/src/app/modules/meetings/components/registrant-card/registrant-card.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-type-selection/meeting-type-selection.component.tsapps/lfx-one/src/app/shared/components/avatar/avatar.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-resources-summary/meeting-resources-summary.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.tsapps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.ts
apps/lfx-one/src/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Shared package uses direct source imports during development for hot reloading
Files:
apps/lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-card/meeting-card.component.tsapps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.tsapps/lfx-one/src/server/services/meeting.service.tsapps/lfx-one/src/app/modules/dashboards/components/dashboard-meeting-card/dashboard-meeting-card.component.tsapps/lfx-one/src/app/shared/components/feature-toggle/feature-toggle.component.tsapps/lfx-one/src/server/routes/meetings.route.tsapps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.tsapps/lfx-one/src/app/shared/components/header/header.component.tsapps/lfx-one/src/server/controllers/meeting.controller.tsapps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.tsapps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-manager/meeting-registrants-manager.component.tsapps/lfx-one/src/server/middleware/auth.middleware.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-display/meeting-registrants-display.component.tsapps/lfx-one/src/app/modules/meetings/components/registrant-card/registrant-card.component.tsapps/lfx-one/src/server/services/committee.service.tsapps/lfx-one/src/app/modules/meetings/components/meeting-type-selection/meeting-type-selection.component.tsapps/lfx-one/src/app/shared/components/avatar/avatar.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-resources-summary/meeting-resources-summary.component.tsapps/lfx-one/src/app/shared/services/meeting.service.tsapps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.tsapps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.ts
apps/lfx-one/src/**/*.component.html
📄 CodeRabbit inference engine (CLAUDE.md)
Add data-testid attributes with naming convention [section]-[component]-[element] when creating new components
Files:
apps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.htmlapps/lfx-one/src/app/shared/components/feature-toggle/feature-toggle.component.htmlapps/lfx-one/src/app/modules/committees/components/member-card/member-card.component.htmlapps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.htmlapps/lfx-one/src/app/modules/meetings/components/registrant-form/registrant-form.component.htmlapps/lfx-one/src/app/modules/dashboards/components/recent-progress/recent-progress.component.htmlapps/lfx-one/src/app/modules/dashboards/components/dashboard-meeting-card/dashboard-meeting-card.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-manager/meeting-registrants-manager.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-card/meeting-card.component.htmlapps/lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.htmlapps/lfx-one/src/app/shared/components/avatar/avatar.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-type-selection/meeting-type-selection.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-display/meeting-registrants-display.component.htmlapps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.htmlapps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.html
🧠 Learnings (1)
📚 Learning: 2025-12-10T23:20:29.281Z
Learnt from: asithade
Repo: linuxfoundation/lfx-v2-ui PR: 206
File: apps/lfx-one/src/app/modules/meetings/components/agenda-template-selector/agenda-template-selector.component.ts:11-15
Timestamp: 2025-12-10T23:20:29.281Z
Learning: For Angular 19+ projects, standalone defaults to true for components, directives, and pipes when not explicitly declared. Therefore, components with an imports array in the Component decorator do not require an explicit standalone: true declaration to be standalone. In reviews, verify that a component without an explicit standalone flag and with an imports array will behave as a standalone component according to Angular 19+ defaults. If you need to enforce explicit standalone behavior for clarity or consistency, you can still add standalone: true, but it is not required by default in Angular 19+. Ensure this guidance is considered when reviewing any component.ts files across the codebase.
Applied to files:
apps/lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-card/meeting-card.component.tsapps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.tsapps/lfx-one/src/app/modules/dashboards/components/dashboard-meeting-card/dashboard-meeting-card.component.tsapps/lfx-one/src/app/shared/components/feature-toggle/feature-toggle.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.tsapps/lfx-one/src/app/shared/components/header/header.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-platform-features/meeting-platform-features.component.tsapps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-manager/meeting-registrants-manager.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-registrants-display/meeting-registrants-display.component.tsapps/lfx-one/src/app/modules/meetings/components/registrant-card/registrant-card.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-type-selection/meeting-type-selection.component.tsapps/lfx-one/src/app/shared/components/avatar/avatar.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-resources-summary/meeting-resources-summary.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.tsapps/lfx-one/src/app/modules/meetings/meeting-manage/meeting-manage.component.ts
🧬 Code graph analysis (14)
apps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.ts (1)
packages/shared/src/constants/validation.constants.ts (1)
LINKEDIN_PROFILE_PATTERN(29-29)
packages/shared/src/constants/meeting.constants.ts (1)
packages/shared/src/constants/colors.constants.ts (1)
lfxColors(9-106)
apps/lfx-one/src/server/services/meeting.service.ts (4)
packages/shared/src/utils/string.utils.ts (1)
isUuid(9-11)apps/lfx-one/src/server/services/logger.service.ts (1)
logger(485-485)packages/shared/src/interfaces/api.interface.ts (1)
QueryServiceResponse(58-63)packages/shared/src/interfaces/meeting.interface.ts (1)
MeetingRegistrant(523-578)
apps/lfx-one/src/app/shared/components/feature-toggle/feature-toggle.component.ts (1)
packages/shared/src/interfaces/components.interface.ts (1)
FeatureConfig(10-27)
apps/lfx-one/src/app/modules/meetings/components/meeting-details/meeting-details.component.ts (1)
packages/shared/src/constants/meeting.constants.ts (2)
MEETING_DURATION_OPTIONS(482-489)RECURRING_MEETING_FEATURE(439-446)
apps/lfx-one/src/server/controllers/meeting.controller.ts (5)
apps/lfx-one/src/server/services/meeting.service.ts (1)
MeetingService(38-974)apps/lfx-one/src/server/services/committee.service.ts (1)
CommitteeService(25-429)packages/shared/src/utils/string.utils.ts (1)
isUuid(9-11)apps/lfx-one/src/server/helpers/validation.helper.ts (1)
validateUidParameter(30-49)apps/lfx-one/src/server/utils/m2m-token.util.ts (1)
generateM2MToken(16-108)
apps/lfx-one/src/app/modules/meetings/components/meeting-registrants-manager/meeting-registrants-manager.component.ts (2)
packages/shared/src/interfaces/meeting.interface.ts (2)
RegistrantPendingChanges(677-684)MeetingRegistrantWithState(645-654)packages/shared/src/constants/meeting.constants.ts (1)
SHOW_MEETING_ATTENDEES_FEATURE(465-472)
apps/lfx-one/src/server/middleware/auth.middleware.ts (2)
packages/shared/src/interfaces/auth.interface.ts (1)
TokenExtractionResult(139-144)apps/lfx-one/src/server/services/logger.service.ts (1)
logger(485-485)
apps/lfx-one/src/app/modules/meetings/components/meeting-registrants-display/meeting-registrants-display.component.ts (2)
apps/lfx-one/src/app/modules/meetings/components/meeting-registrants-manager/meeting-registrants-manager.component.ts (1)
Component(25-353)apps/lfx-one/src/app/modules/meetings/components/registrant-card/registrant-card.component.ts (1)
Component(14-90)
apps/lfx-one/src/server/services/committee.service.ts (2)
packages/shared/src/interfaces/committee.interface.ts (3)
CommitteeCreateData(68-101)Committee(10-62)CommitteeSettingsData(113-122)apps/lfx-one/src/server/services/logger.service.ts (2)
logger(485-485)etag(289-324)
apps/lfx-one/src/app/modules/meetings/components/meeting-type-selection/meeting-type-selection.component.ts (1)
packages/shared/src/constants/meeting.constants.ts (1)
RESTRICTED_MEETING_FEATURE(452-459)
apps/lfx-one/src/app/shared/components/avatar/avatar.component.ts (1)
packages/shared/src/interfaces/components.interface.ts (1)
AvatarProps(257-274)
apps/lfx-one/src/app/shared/services/meeting.service.ts (2)
packages/shared/src/interfaces/meeting.interface.ts (1)
MeetingRegistrant(523-578)packages/shared/src/constants/validation.constants.ts (1)
LINKEDIN_PROFILE_PATTERN(29-29)
apps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.ts (3)
packages/shared/src/interfaces/meeting.interface.ts (1)
MeetingCommittee(300-307)packages/shared/src/interfaces/committee.interface.ts (1)
Committee(10-62)packages/shared/src/constants/committees.constants.ts (2)
VOTING_STATUSES(231-237)COMMITTEE_LABEL(17-20)
...lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.html
Show resolved
Hide resolved
...modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.ts
Show resolved
Hide resolved
- Use case-insensitive email comparison for member deduplication - Add explicit null check for voting status filtering - Fix token restoration when original token was undefined - Reduce auth middleware log verbosity (success → debug) LFXV2-928 Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Asitha de Silva <asithade@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (4)
apps/lfx-one/src/server/controllers/meeting.controller.ts (4)
439-444: Avoid spreading entire meeting object into logs.Spreading the full meeting object into debug logs could inadvertently log sensitive data. Log only the necessary fields.
460-464: Consider redacting user email in debug logs for privacy.Logging the raw email address may raise privacy/compliance concerns. Consider logging only
has_emailor a redacted version.
529-533: Token restoration may leave stale token when original was undefined.The restoration logic should use
delete req.bearerTokenwhen the original token was undefined to avoid leaving the M2M token in place.
1524-1607: Error handling continues on partial failures without client indication.The method catches errors when fetching committee details or members and logs warnings but continues processing. This could result in incomplete data being returned without any indication that some data is missing.
🧹 Nitpick comments (1)
apps/lfx-one/src/server/controllers/meeting.controller.ts (1)
476-533: Consider using try-finally for token restoration.The current token restoration logic works correctly, but using a try-finally block would more explicitly guarantee cleanup even if errors occur during registrant fetching or enrichment. This is a defensive programming best practice.
🔎 Proposed refactor using try-finally
// Save original token and setup M2M token for privileged access const originalToken = req.bearerToken; - const m2mToken = await generateM2MToken(req); - req.bearerToken = m2mToken; - - // Use tags_all to filter by both meeting_uid and email - logger.debug(req, 'get_my_meeting_registrants', 'Checking if user is a registrant', { - meeting_uid: uid, - user_email: userEmail, - }); - const userRegistrantCheck = await this.meetingService.getMeetingRegistrantsByEmail(req, uid, userEmail); - - logger.debug(req, 'get_my_meeting_registrants', 'User registrant check complete', { - meeting_uid: uid, - user_email: userEmail, - registrant_count: userRegistrantCheck.resources?.length || 0, - }); - - // Step 6: If user is not a registrant, return empty array - if (!userRegistrantCheck.resources || userRegistrantCheck.resources.length === 0) { - logger.success(req, 'get_my_meeting_registrants', startTime, { + try { + const m2mToken = await generateM2MToken(req); + req.bearerToken = m2mToken; + + // Use tags_all to filter by both meeting_uid and email + logger.debug(req, 'get_my_meeting_registrants', 'Checking if user is a registrant', { meeting_uid: uid, user_email: userEmail, - is_registrant: false, - registrant_count: 0, }); - res.json([]); - return; - } - - // Step 7: User is a registrant, fetch all registrants using M2M token - logger.debug(req, 'get_my_meeting_registrants', 'User is a registrant, setting up M2M token', { - meeting_uid: uid, - user_email: userEmail, - include_rsvp: includeRsvp, - }); - - logger.debug(req, 'get_my_meeting_registrants', 'M2M token generated, fetching all registrants', { - meeting_uid: uid, - has_m2m_token: !!m2mToken, - }); - - const registrants = await this.meetingService.getMeetingRegistrants(req, uid, includeRsvp); - - logger.debug(req, 'get_my_meeting_registrants', 'Fetched all registrants, enriching committee data', { - meeting_uid: uid, - registrant_count: registrants.length, - }); - - // Enrich committee registrant data with committee details and member info - const enrichedRegistrants = await this.enrichCommitteeRegistrants(req, registrants); - - // Restore original token (delete if it was undefined to avoid leaving M2M token) + const userRegistrantCheck = await this.meetingService.getMeetingRegistrantsByEmail(req, uid, userEmail); + + logger.debug(req, 'get_my_meeting_registrants', 'User registrant check complete', { + meeting_uid: uid, + user_email: userEmail, + registrant_count: userRegistrantCheck.resources?.length || 0, + }); + + // Step 6: If user is not a registrant, return empty array + if (!userRegistrantCheck.resources || userRegistrantCheck.resources.length === 0) { + logger.success(req, 'get_my_meeting_registrants', startTime, { + meeting_uid: uid, + user_email: userEmail, + is_registrant: false, + registrant_count: 0, + }); + res.json([]); + return; + } + + // Step 7: User is a registrant, fetch all registrants using M2M token + logger.debug(req, 'get_my_meeting_registrants', 'User is a registrant, setting up M2M token', { + meeting_uid: uid, + user_email: userEmail, + include_rsvp: includeRsvp, + }); + + logger.debug(req, 'get_my_meeting_registrants', 'M2M token generated, fetching all registrants', { + meeting_uid: uid, + has_m2m_token: !!m2mToken, + }); + + const registrants = await this.meetingService.getMeetingRegistrants(req, uid, includeRsvp); + + logger.debug(req, 'get_my_meeting_registrants', 'Fetched all registrants, enriching committee data', { + meeting_uid: uid, + registrant_count: registrants.length, + }); + + // Enrich committee registrant data with committee details and member info + const enrichedRegistrants = await this.enrichCommitteeRegistrants(req, registrants); + + logger.success(req, 'get_my_meeting_registrants', startTime, { + meeting_uid: uid, + user_email: userEmail, + is_registrant: true, + registrant_count: enrichedRegistrants.length, + include_rsvp: includeRsvp, + }); + + // Send the registrants data to the client + res.json(enrichedRegistrants); + } finally { + // Restore original token (delete if it was undefined to avoid leaving M2M token) - if (originalToken !== undefined) { - req.bearerToken = originalToken; - } else { - delete req.bearerToken; + if (originalToken !== undefined) { + req.bearerToken = originalToken; + } else { + delete req.bearerToken; + } } - - logger.success(req, 'get_my_meeting_registrants', startTime, { - meeting_uid: uid, - user_email: userEmail, - is_registrant: true, - registrant_count: enrichedRegistrants.length, - include_rsvp: includeRsvp, - }); - - // Send the registrants data to the client - res.json(enrichedRegistrants); } catch (error) {
📜 Review details
Configuration used: Organization 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.
📒 Files selected for processing (5)
apps/lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.tsapps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.tsapps/lfx-one/src/server/controllers/meeting.controller.tsapps/lfx-one/src/server/middleware/auth.middleware.tsapps/lfx-one/src/server/server.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/lfx-one/src/app/modules/meetings/components/meeting-committee-manager/meeting-committee-manager.component.ts
- apps/lfx-one/src/app/modules/committees/components/committee-table/committee-table.component.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx,css,scss}
📄 CodeRabbit inference engine (CLAUDE.md)
Always include license headers on all source files - run ./check-headers.sh to verify
Files:
apps/lfx-one/src/server/controllers/meeting.controller.tsapps/lfx-one/src/server/server.tsapps/lfx-one/src/server/middleware/auth.middleware.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Always use async/await for promises instead of .then() chains in TypeScript services
Use TypeScript interfaces instead of union types for better maintainability
Files:
apps/lfx-one/src/server/controllers/meeting.controller.tsapps/lfx-one/src/server/server.tsapps/lfx-one/src/server/middleware/auth.middleware.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Do not nest ternary expressions
Files:
apps/lfx-one/src/server/controllers/meeting.controller.tsapps/lfx-one/src/server/server.tsapps/lfx-one/src/server/middleware/auth.middleware.ts
apps/lfx-one/src/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Shared package uses direct source imports during development for hot reloading
Files:
apps/lfx-one/src/server/controllers/meeting.controller.tsapps/lfx-one/src/server/server.tsapps/lfx-one/src/server/middleware/auth.middleware.ts
🧬 Code graph analysis (1)
apps/lfx-one/src/server/controllers/meeting.controller.ts (5)
packages/shared/src/utils/string.utils.ts (1)
isUuid(9-11)apps/lfx-one/src/server/helpers/validation.helper.ts (1)
validateUidParameter(30-49)apps/lfx-one/src/server/utils/m2m-token.util.ts (1)
generateM2MToken(16-108)packages/shared/src/interfaces/meeting.interface.ts (1)
MeetingRegistrant(523-578)packages/shared/src/interfaces/committee.interface.ts (1)
Committee(10-62)
🔇 Additional comments (3)
apps/lfx-one/src/server/controllers/meeting.controller.ts (1)
1593-1594: LGTM: Case-insensitive email comparison.Using case-insensitive email comparison when matching committee members to registrants is the correct approach, as email addresses are case-insensitive per RFC 5321.
apps/lfx-one/src/server/server.ts (1)
130-130: LGTM: Silent login enabled.Enabling
attemptSilentLoginallows the application to attempt authentication without user interaction when possible, improving the user experience. This aligns with the PR objectives to enhance the authentication flow.apps/lfx-one/src/server/middleware/auth.middleware.ts (1)
88-88: LGTM: Logging improvements.The logging changes simplify the authentication flow logging by:
- Using
Date.now()directly instead oflogger.startOperationfor consistency- Changing routine token operations from success-level to debug-level logs to reduce noise
- Clarifying log messages for better readability
These changes improve observability without altering authentication behavior.
Also applies to: 100-100, 131-131, 144-147, 332-332, 378-383
Add attemptSilentLogin middleware specifically for /meetings/ routes to enable SSO session detection from other LFX applications. This allows users who are already logged into another LFX app to be automatically authenticated when accessing meeting join pages. LFXV2-928 Signed-off-by: Asitha de Silva <asithade@gmail.com>
Summary
Related Tickets
Generated with Claude Code