Skip to content
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

Feature/77 userstory enterprise #135

Merged
merged 6 commits into from
Feb 16, 2025
Merged

Conversation

nganntqe170236
Copy link
Collaborator

@nganntqe170236 nganntqe170236 commented Feb 15, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced building management by replacing legacy attributes with a unified device count metric.
    • Introduced an API endpoint to fetch detailed building information using unique identifiers.
    • Added new components for dashboard, pricing, sidebar, and improved error handling for a smoother experience.
    • Implemented a new user interface for managing building details, including forms and validation.
    • Introduced a new template for displaying user-friendly messages in tables when no data is available.
    • Added sorting capabilities to the payment component for better data management.
  • Style

    • Updated layouts, CSS rules, and card structures to improve the visual consistency and responsiveness of the interface.
  • Refactor

    • Refined routing and component naming for clearer navigation and feature accessibility.
    • Improved user data handling and role management capabilities in the application service.
    • Streamlined JWT authentication and error handling processes in the application.

Copy link

coderabbitai bot commented Feb 15, 2025

Walkthrough

This pull request revises the building-related data model and functionality across both backend and frontend codebases. The changes remove the existing floors and squareMeters fields in favor of a new numberOfDevices metric across DTOs, entities, SQL migrations, and tests. Additionally, new endpoints, services, and components have been introduced for retrieving and managing building details. The update also includes adjustments to Angular layouts, routing, localization strings, and even a minor SQL filter fix in the user entity.

Changes

File(s) Change Summary
.../enterprise/dtos/BuildingDTO.java
.../enterprise/entities/BuildingEntity.java
Removed fields floors and squareMeters; added field numberOfDevices (with validations removed in the Entity).
.../enterprise/rest/BuildingController.java Added new GET endpoint getBuildingById and renamed getEnterpriseBuildings to searchEnterpriseBuildings.
.../enterprise/services/BuildingService.java
.../enterprise/services/impl/BuildingServiceImpl.java
Added method findById(UUID id) to retrieve building entities by ID.
.../enterprise/resources/db/migration/V0.0.1.5__CorrectBuilding.sql Dropped columns floors and square_meters; added column number_of_devices BIGINT NOT NULL default 0.
.../enterprise/rest/BuildingControllerTest.java Updated test to construct BuildingDTO with numberOfDevices instead of floors/squareMeters; removed unused BigDecimal import.
.../app/app.component.html
.../app/app.component.scss
Modified layout classes: changed height constraints from min-h-screen to max-h-dvh and adjusted host element styling.
.../app/app.module.ts Added new components (DashboardComponent, PricingComponent, SidebarComponent) and interceptor (HttpErrorHandlerInterceptor); updated declarations and providers.
.../modules/authorization/authorization.component.css
.../modules/authorization/authorization.module.ts
.../modules/authorization/components/users/users.component.html
Introduced new CSS padding rule; removed unused PrimeNG Message import; updated icon class in users component.
.../modules/core/services/http-error-handler.interceptor.ts Introduced a new HTTP interceptor to handle technical and business errors using Message and Translate services.
.../modules/dev/components/toolbox/toolbox.component.html Replaced commented-out button sections with a new <card-template> layout and adjusted button attributes.
.../modules/emissions/emissions.component.css
.../modules/enterprise/components/building-details/building-details.component.css
Added new CSS rules for padding and flex layout enhancements.
.../modules/enterprise/components/building-details/building-details.component.{html,ts} Added BuildingDetailsComponent with a reactive form for managing building details, including back navigation and reset/submit functionality.
.../modules/enterprise/components/buildings/buildings.component.{css,html,ts} Restructured UI with a new header section, dynamic card rendering using <ng-template>, and added navigation methods (addBuilding, viewBuildingDetails); component now extends SubscriptionAwareComponent.
.../modules/enterprise/components/subscription/subscription.component.ts Renamed PlanComponent to SubscriptionComponent with corresponding template and style URL updates.
.../modules/enterprise/enterprise-routing.module.ts
.../modules/enterprise/enterprise.module.ts
Updated routing: added route for BuildingDetailsComponent; replaced PlanComponent with SubscriptionComponent in the module.
.../modules/enterprise/models/building-details.dto.ts
.../modules/enterprise/models/building.dto.ts
Introduced new interfaces BuildingDetails and Building to standardize building data structures.
.../modules/shared/components/table-template/table-template.component.html
.../modules/shared/shared.module.ts
Added an empty message <ng-template> for <p-table>; included additional PrimeNG modules (DividerModule, MessageModule, MessagesModule) in SharedModule exports.
.../services/building.service.ts Added BuildingService with methods to construct the create URL, retrieve building details (getBuildingDetails), and search buildings (searchBuildings).
.../assets/i18n/en.json
.../assets/i18n/vi.json
.../assets/i18n/zh.json
Updated localization files with new keys for "back", comprehensive error messages, and building-specific text entries for overview and details.
.../idp/.../UserEntity.java Fixed SQL filter condition by appending a missing closing parenthesis in the @Filter annotation.

Possibly related PRs

  • Feature/i dont know what is this #126: The changes in the main PR, specifically the modifications to the BuildingDTO and BuildingEntity classes, are related to the changes in the retrieved PR, which also involves updates to the PaymentDTO and PaymentEntity classes that include similar import modifications for the StatusPayment enum, indicating a structural alignment in the codebase.
  • feature: Use hibernate filter to add condition to query #121: The changes in the main PR, which involve modifications to the BuildingDTO and BuildingEntity classes by removing fields and adding a new one, are related to the changes in the retrieved PR that also modifies the UserEntity class to introduce new filtering capabilities, as both involve structural changes to entity classes in the context of managing data attributes.

Suggested labels

task

Suggested reviewers

  • GiaBaorr
  • huynhlephcvinh

Poem

In a field of code I hop,
Leaving floors and meters to stop.
Now devices count the beat,
As I race through endpoints neat.
Bugs beware, I’m on the run,
Hopping to a brighter, cleaner code sun! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 10

🧹 Nitpick comments (10)
sep490-frontend/src/app/modules/core/services/http-error-handler.interceptor.ts (4)

26-31: Use else if for exclusive error handling
Currently, the code checks both the 'TECHNICAL' and 'BUSINESS' error types with separate if blocks. If an error were to inadvertently contain both types, both handlers would be invoked. Using else if for the second condition can help ensure only one handler is triggered.

       if (error.error && error.error.errorType === 'TECHNICAL') {
         this.handleTechnicalErrorException(error);
       }
-      if (error.error && error.error.errorType === 'BUSINESS') {
+      else if (error.error && error.error.errorType === 'BUSINESS') {
         this.handleBusinessErrorException(error);
       }

37-49: Avoid mutating the error object
By storing errorNotified directly in error.error, you risk altering the original error payload. This can create issues if upstream or other interceptors rely on the unchanged error object. Consider creating a clone or using auxiliary state to track notification.

  private handleTechnicalErrorException(error: any): void {
    ...
-    error.error.errorNotified = true;
+    const clonedError = { ...error, error: { ...error.error, errorNotified: true } };
+    // Use clonedError for any further processing if needed
  }

51-64: Handle missing i18n keys gracefully
When error.error.i18nKey is undefined, the translateService.instant(...) might not produce a meaningful message. Consider a fallback mechanism to avoid displaying confusing or missing translations.

if (!error.error.field) {
  this.messageService.add({
    severity: 'error',
    summary: 'Error',
-    detail: this.translateService.instant(
-      `validation.${error.error.i18nKey}`,
-      this.convertErrorParams(error.error.args)
-    ),
+    detail: error.error.i18nKey
+      ? this.translateService.instant(
+          `validation.${error.error.i18nKey}`,
+          this.convertErrorParams(error.error.args)
+        )
+      : 'An unexpected business error occurred.',
    sticky: true
  });
}

66-76: Validate params content
While convertErrorParams gracefully handles null or undefined params by returning {}, it does not guard against invalid array content (e.g., missing key or value). If you expect well-formed data, at least log or handle unexpected param entries.

private convertErrorParams(params: BusinessErrorParam[]): {
  [key: string]: string;
} {
-  return params?.reduce(
+  return (params ?? []).reduce(
    (result, arg: BusinessErrorParam) => {
      // Optionally validate arg.key and arg.value here
      result[arg.key] = arg.value;
      return result;
    },
    {} as {[key: string]: string}
  );
}
sep490-frontend/src/app/modules/enterprise/models/building-details.dto.ts (1)

3-6: Add docstring to clarify property usage
Providing short doc comments on these properties would help future contributors understand their purposes, constraints, and possible edge cases (e.g., whether name is guaranteed to be unique).

export interface BuildingDetails extends BaseDTO {
  /**
   * The unique name of the building.
   */
  name: string;
  /**
   * The number of devices installed in the building.
   */
  numberOfDevices: number;
}
sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.ts (2)

77-89: Configure pagination size through environment variables.

The page size is hardcoded to 100 which might not be optimal for all scenarios.

Consider moving the pagination configuration to environment:

-          pageSize: 100
+          pageSize: environment.defaultPageSize

117-128: Extract map configuration to environment variables.

The map center coordinates are hardcoded which makes it difficult to configure for different regions.

Consider this approach:

-        center: [10.841394, 106.810052],
-        zoom: 20
+        center: [environment.mapDefaultLat, environment.mapDefaultLng],
+        zoom: environment.mapDefaultZoom
sep490-frontend/src/app/modules/enterprise/components/building-details/building-details.component.html (1)

68-73: Floating Label Input Template

The <ng-template> for a floating label input (using <p-floatlabel>) is a neat addition. However, it appears to replicate the "name" input already defined earlier. Confirm whether this is intentional (e.g., for handling a different UI state) or if the template should be refactored or removed.

sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.html (1)

24-30: Map Container Setup

The map container is conditionally shown based on listView and set to a fixed height of 600px. Consider the responsiveness of this container on different devices and whether a fixed height is optimal.

sep490-frontend/src/app/modules/dev/components/toolbox/toolbox.component.html (1)

81-89: Rounded, Text, and Raised Icon Buttons Group
This section combines multiple stylistic attributes ([rounded], [text], and [raised]) to create a layered button appearance. While the markup is clear, consider refactoring repetitive button definitions into a dynamic construct (e.g., using an *ngFor directive) to improve maintainability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e3e609 and 75415bc.

📒 Files selected for processing (36)
  • sep490-enterprise/src/main/java/enterprise/dtos/BuildingDTO.java (1 hunks)
  • sep490-enterprise/src/main/java/enterprise/entities/BuildingEntity.java (1 hunks)
  • sep490-enterprise/src/main/java/enterprise/rest/BuildingController.java (2 hunks)
  • sep490-enterprise/src/main/java/enterprise/services/BuildingService.java (1 hunks)
  • sep490-enterprise/src/main/java/enterprise/services/impl/BuildingServiceImpl.java (2 hunks)
  • sep490-enterprise/src/main/resources/db/migration/V0.0.1.5__CorrectBuilding.sql (1 hunks)
  • sep490-enterprise/src/test/java/enterprise/rest/BuildingControllerTest.java (1 hunks)
  • sep490-frontend/src/app/app.component.html (1 hunks)
  • sep490-frontend/src/app/app.component.scss (1 hunks)
  • sep490-frontend/src/app/app.module.ts (2 hunks)
  • sep490-frontend/src/app/components/sidebar/sidebar.component.css (1 hunks)
  • sep490-frontend/src/app/modules/authorization/authorization.component.css (1 hunks)
  • sep490-frontend/src/app/modules/authorization/authorization.module.ts (1 hunks)
  • sep490-frontend/src/app/modules/authorization/components/users/users.component.html (2 hunks)
  • sep490-frontend/src/app/modules/core/services/http-error-handler.interceptor.ts (1 hunks)
  • sep490-frontend/src/app/modules/dev/components/toolbox/toolbox.component.html (1 hunks)
  • sep490-frontend/src/app/modules/emissions/emissions.component.css (1 hunks)
  • sep490-frontend/src/app/modules/enterprise/components/building-details/building-details.component.css (1 hunks)
  • sep490-frontend/src/app/modules/enterprise/components/building-details/building-details.component.html (1 hunks)
  • sep490-frontend/src/app/modules/enterprise/components/building-details/building-details.component.ts (1 hunks)
  • sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.css (1 hunks)
  • sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.html (1 hunks)
  • sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.ts (4 hunks)
  • sep490-frontend/src/app/modules/enterprise/components/subscription/subscription.component.ts (1 hunks)
  • sep490-frontend/src/app/modules/enterprise/enterprise-routing.module.ts (1 hunks)
  • sep490-frontend/src/app/modules/enterprise/enterprise.component.css (1 hunks)
  • sep490-frontend/src/app/modules/enterprise/enterprise.module.ts (2 hunks)
  • sep490-frontend/src/app/modules/enterprise/models/building-details.dto.ts (1 hunks)
  • sep490-frontend/src/app/modules/enterprise/models/building.dto.ts (1 hunks)
  • sep490-frontend/src/app/modules/shared/components/table-template/table-template.component.html (1 hunks)
  • sep490-frontend/src/app/modules/shared/shared.module.ts (3 hunks)
  • sep490-frontend/src/app/services/building.service.ts (1 hunks)
  • sep490-frontend/src/assets/i18n/en.json (6 hunks)
  • sep490-frontend/src/assets/i18n/vi.json (5 hunks)
  • sep490-frontend/src/assets/i18n/zh.json (5 hunks)
  • sep490-idp/src/main/java/green_buildings/idp/entity/UserEntity.java (1 hunks)
✅ Files skipped from review due to trivial changes (8)
  • sep490-frontend/src/app/modules/authorization/authorization.component.css
  • sep490-frontend/src/app/components/sidebar/sidebar.component.css
  • sep490-frontend/src/app/modules/emissions/emissions.component.css
  • sep490-frontend/src/app/modules/enterprise/enterprise.component.css
  • sep490-frontend/src/app/modules/enterprise/components/building-details/building-details.component.css
  • sep490-frontend/src/app/app.component.html
  • sep490-idp/src/main/java/green_buildings/idp/entity/UserEntity.java
  • sep490-frontend/src/app/modules/enterprise/components/subscription/subscription.component.ts
🧰 Additional context used
🪛 Biome (1.9.4)
sep490-frontend/src/app/modules/enterprise/components/building-details/building-details.component.ts

[error] 60-60: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build Java Modules (sep490-enterprise)
  • GitHub Check: Build Java Modules (sep490-idp)
🔇 Additional comments (43)
sep490-frontend/src/app/app.component.scss (1)

2-2: Responsive Layout Improvement: Use of min-h-dvh

The update from a fixed height (h-dvh) to a minimum height (min-h-dvh) is a good move to allow the host element to expand as necessary, improving responsiveness. Please verify that this change aligns with the overall design and behavior expectations across different screens.

sep490-frontend/src/app/modules/authorization/components/users/users.component.html (2)

1-3: Header Enhancement: Added text-primary Class

The <h1> element now includes the text-primary class along with the other utility classes. This enhancement should help enforce theme consistency by applying the primary color styling without altering the displayed title text.


31-33: Search Button Icon Update

The search button’s icon has been updated to pi pi-search, which more clearly conveys its functionality as a search trigger compared to the previous icon. Please confirm that this change aligns with the design language across the application.

sep490-frontend/src/app/modules/shared/shared.module.ts (1)

14-14:

❓ Verification inconclusive

LGTM! Verify the usage of new PrimeNG modules.

The addition of DividerModule, MessageModule, and MessagesModule from PrimeNG is well-structured and follows the module's existing patterns. The modules are correctly imported and added to the shared module's configuration.

Let's verify that these modules are being used in the codebase:

Also applies to: 24-25, 57-57, 63-64


🏁 Script executed:

#!/bin/bash
# Description: Search for usage of the newly added PrimeNG components
# Expected: Find component usage in templates

echo "Searching for p-divider usage..."
rg -t html "p-divider"

echo "Searching for p-message usage..."
rg -t html "p-message"

echo "Searching for p-messages usage..."
rg -t html "p-messages"

Length of output: 589


Review Approved – Please Verify Module Usage

The update in the shared module is well structured and follows the existing patterns. We confirmed that <p-message> in enterprise-user-details.component.html reflects usage of the new MessageModule. However, our automated search did not return any matches for DividerModule (i.e. p-divider) or MessagesModule (i.e. p-messages).

  • Verify whether these two modules are utilized in other parts of the codebase (e.g., inline templates or upcoming features).
  • If these modules are not used, consider removing them to keep the shared module lean.
sep490-frontend/src/app/modules/authorization/authorization.module.ts (1)

16-16:

❓ Verification inconclusive

LGTM! Removal of unused Message component.

The simplified imports array improves module cleanliness by removing the unused Message component.

Let's verify that the Message component is not used in any of the module's components:


🏁 Script executed:

#!/bin/bash
# Description: Check for any remaining usage of Message component in authorization module components

# Search for Message usage in component files
rg -i "message" "sep490-frontend/src/app/modules/authorization/"

Length of output: 3072


LGTM – Change Approved with a Caveat

The simplified imports array in authorization.module.ts improves clarity by removing the unused Message component. Note that while the Message component is no longer imported in the module, there are still usages of <p-message> in the HTML templates and MessageService in the component TypeScript files (e.g., in enterprise-user-details.component.ts and users.component.ts). Please ensure that the SharedModule correctly imports and re-exports the necessary PrimeNG Message-related modules so that these usages remain fully supported.

sep490-frontend/src/app/modules/enterprise/models/building.dto.ts (1)

3-9:

❓ Verification inconclusive

Ensure property compatibility with back-end expectations
If the backend expects certain constraints or formats (e.g., date formats, string length limits, etc.), document or enforce them here for clarity. This helps keep front-end and back-end models in sync.

Would you like to verify these property constraints in the backend DTOs to confirm alignment?


🏁 Script executed:

#!/bin/bash
# Searching for BuildingDTO definitions in the backend to compare constraints
fd -t f "BuildingDTO.java" --exec cat {} | rg -A 5 'class BuildingDTO'

Length of output: 72


Manual Verification Required: Backend DTO Property Constraints

It appears that the search for a BuildingDTO.java file did not return any results. Because we couldn’t retrieve the backend constraints automatically, please manually verify that the backend's definitions for the building model enforce or document similar property constraints (e.g., date formats, string length limits, etc.) as defined in the frontend's Building interface. Confirm that properties such as validFromInclusive and validToInclusive follow the expected formats and any additional requirements expected by the backend.

  • Action items:
    • Manually confirm the backend DTO properties and constraints.
    • Ensure that the frontend model remains in sync with backend expectations.
sep490-enterprise/src/main/java/enterprise/services/BuildingService.java (1)

14-14: LGTM! Good use of Optional for nullable return.

The new findById method follows best practices by using Optional to handle potential null cases.

sep490-frontend/src/app/modules/enterprise/enterprise.module.ts (1)

16-21: LGTM! Component declarations are properly organized.

The module declarations are correctly updated with the new components while maintaining proper organization.

sep490-enterprise/src/main/java/enterprise/services/impl/BuildingServiceImpl.java (1)

27-30: LGTM!

The implementation is clean and follows best practices by using Optional for nullable results and properly delegating to the repository.

sep490-enterprise/src/main/java/enterprise/rest/BuildingController.java (1)

47-47:

❓ Verification inconclusive

Consider API versioning for the renamed endpoint.

The method has been renamed from getEnterpriseBuildings to searchEnterpriseBuildings which could break existing API consumers.

Consider:

  1. Adding API versioning (e.g., /v2/api/buildings/search)
  2. Temporarily keeping both endpoints for backward compatibility

Let's verify existing API consumers:


🏁 Script executed:

#!/bin/bash
# Search for API calls to the old endpoint name
rg -l "getEnterpriseBuildings" --type ts

Length of output: 40


API Versioning and Backward Compatibility Check for Renamed Endpoint

The method was renamed from getEnterpriseBuildings to searchEnterpriseBuildings, which might break external API consumers. Our initial search in TypeScript files did not return any references to getEnterpriseBuildings, but this result is based solely on TS files and may not cover all potential consumers.

  • Action Items:
    • Verify Usage: Perform an extensive search across the entire repository (including non-TypeScript files) or manually confirm that no external consumers rely on the old endpoint.
    • Backward Compatibility: If any usage is found or external dependencies are anticipated, consider implementing API versioning (e.g., /v2/api/buildings/search) or temporarily maintaining both endpoints.
sep490-frontend/src/app/app.module.ts (1)

113-119: Review the order of HTTP interceptors.

The order of interceptors is crucial as they are executed in the order they are provided. The current order is:

  1. Language
  2. Auth
  3. Error Handler

This is correct as the error handler should be last to catch errors from other interceptors.

sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.ts (1)

40-42: LGTM! Good use of SubscriptionAwareComponent.

The component properly extends SubscriptionAwareComponent and uses takeUntil for subscription management, which helps prevent memory leaks.

sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.css (2)

1-3: :host Styling Adjustments

The updated :host styling now applies a flexbox layout with column direction and a gap, without the previous padding utility. Ensure that this change aligns with the overall layout expectations.


5-7: Added .box-shadow Class

The new .box-shadow class applies a subtle box-shadow effect. Verify that the shadow parameters (offsets, blur, and color) meet the design specifications and are used consistently across the application.

sep490-enterprise/src/main/resources/db/migration/V0.0.1.5__CorrectBuilding.sql (3)

1-2: Dropping floors Column

Removing the floors column is in line with the new data model. Ensure that any existing queries or application logic referencing this column have been updated.


3-4: Dropping square_meters Column

The removal of the square_meters column further reinforces the updated schema. Confirm that dependent components have been refactored accordingly and that a data backup strategy is in place for production.


6-7: Adding number_of_devices Column

The addition of the new number_of_devices column—with a BIGINT type, non-null constraint, and a default value of 0—appropriately reflects the new business requirements. Verify that downstream code (DTOs, entities, and services) properly handles this field.

sep490-frontend/src/app/modules/enterprise/components/building-details/building-details.component.html (6)

1-10: Back Button Implementation

The back button is well implemented using <p-button> with the appropriate event binding (onClick)="back()" and visual properties. Consider adding accessibility attributes (e.g., aria-label) for enhanced usability.


12-19: Dynamic Title Rendering

The dynamic title, which toggles between "edit" and "create" based on the isEdit flag and is translated via the translate pipe, is clear and concise. Ensure that corresponding translation keys are correctly defined.


21-31: Building Name Input Field

The building name field is correctly set up with reactive form binding (formControlName="name") and paired with an error display component <form-field-error>. Confirm that the form control is properly initialized in the component.


34-45: Number of Devices Input Field

The implementation for the numberOfDevices input is straightforward and mirrors the setup of the name field, including label translation and error display. Validate that the form control exists and that the numeric input behaves as expected.


46-52: Informational Icon for Device Limit

Introducing an informational icon with a message (via translation) to indicate the maximum number of devices is a helpful UX enhancement. Verify that the translation key (enterprise.buildings.details.labels.maxNumberOfDevices) is properly set.


54-66: Form Action Buttons

The reset and submit buttons are correctly bound to their respective methods (reset() and submit()) and display dynamic labels based on the form mode. Ensure that the overall form validation and submission handling cover all edge cases.

sep490-frontend/src/app/modules/shared/components/table-template/table-template.component.html (1)

68-75: Empty Table Message Template

The newly added <ng-template pTemplate="emptymessage"> provides a clean user message when no table rows exist. The dynamic colspan calculation (columns.length + (checkbox ? 1 : 0)) ensures proper cell spanning. Confirm that the translation key (common.noRow) is available.

sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.html (4)

1-11: Header Section with Title and Add Building Button

This header section clearly presents the title (translated) and includes a primary action button to add a building. Double-check that the translation keys for both the title and button label are correctly defined.


13-23: View Mode Selection via p-selectbutton

The <p-selectbutton> implementation for toggling view modes uses two-way binding and a custom template for icons, which is neatly integrated. Ensure that justifyOptions includes all necessary view options.


32-38: Conditional Rendering of Building Cards

The template uses server-side style directives (@if and @for) to render building cards when in list view. Ensure that these constructs are properly processed in your Angular setup or confirm if a framework-specific templating mechanism is used.


40-110: Building Card Template

The card template efficiently displays detailed information about a building—its name, number of devices, validity dates, and address—with a clean layout and action buttons. The use of the .box-shadow class adds visual depth. Confirm that date formatting and translation keys are accurate and that all data fields (such as numberOfDevices) are correctly populated.

sep490-frontend/src/assets/i18n/zh.json (2)

12-17: Common Translations Update
New keys for "revert", "back", and the nested "error" object (with its "title" and "technicalServerError") have been added to the common section. These entries provide clearer user guidance in error scenarios and offer improved navigational context.


109-129: Enterprise Buildings Localization Enhancements
The addition of the "buildings" object under the "enterprise" section—with its "overview" (including "title" and button labels) and "details" (with "edit", "create", and detailed "labels" such as "numberOfDevices")—aligns perfectly with the updated data model. The Chinese translations are clear and consistent with UI expectations.

sep490-frontend/src/app/modules/dev/components/toolbox/toolbox.component.html (9)

1-5: Introduction of Card Template Component
A new <card-template> component is introduced to encapsulate header, body, and footer sections. The structure is clear; however, if these static texts ("header", "body", "footer") are intended for end-user display, consider linking them to localization keys for better internationalization support.


7-16: Primary Raised Buttons Group
This block creates a set of raised buttons with labels such as "Primary", "Secondary", "Success", etc. The usage of the [raised]="true" attribute is consistent and visually portrays the intended emphasis.


18-27: Text Variant Buttons Group
Buttons with variant="text" are implemented here, offering a lighter visual style. The markup is straightforward and fits well within the design language.


29-38: Text Variant with Raised Buttons Group
This block combines the text variant with the raised effect ([raised]="true"), providing an elevated appearance while keeping the minimalistic text style. The implementation is clear and maintains consistency in styling.


40-48: Outlined Buttons Group
Outlined buttons are showcased here via variant="outlined". The consistent application of the outlined style across various button labels reinforces a versatile yet unified UI design.


51-59: Icon-Only Buttons Group
A group of buttons using only icons is implemented. The selection of icons (e.g., "pi pi-check", "pi pi-bell") combined with varying severity settings serves well for compact or symbolic UI actions.


61-69: Rounded Icon Buttons Group
Buttons here add the [rounded]="true" attribute to icon-only buttons, softening their appearance. The change is executed neatly and is consistent with modern design trends.


71-79: Rounded Outlined Icon Buttons Group
The integration of both [rounded]="true" and [outlined]="true" attributes in this block delivers a distinct visual style. The consistent treatment across different buttons enhances the interface’s cohesiveness.


91-99: Rounded and Text Icon Buttons Group
The final group applies [rounded]="true" alongside [text]="true", offering a sleek, minimalist presentation for icon buttons. The consistency in design is well-maintained across the component.

sep490-frontend/src/assets/i18n/en.json (2)

12-17: Updated Common Translations
Newly added entries for "revert", "back", and the error handling object (with "title" and "technicalServerError") enhance user communication during error states. The placeholder {{correlationId}} is correctly preserved, ensuring consistency with error reporting.


109-128: Enterprise Buildings Localization Enhancements
The introduction of the "buildings" object—with its "overview" and "details" sections, including labels like "numberOfDevices"—reflects the recent data model changes. The English translations are clear and align with the backend adjustments, ensuring a smooth UI transition.

sep490-frontend/src/assets/i18n/vi.json (2)

12-17: Cập nhật Bản Dịch Chung
Các khóa mới cho "revert", "back" và đối tượng "error" đã được bổ sung, giúp truyền đạt thông điệp lỗi một cách rõ ràng cho người dùng. Placeholder {{correlationId}} được duy trì một cách chính xác.


110-127: Cải Tiến Bản Dịch cho Phần Tòa Nhà
Phần "buildings" mới, bao gồm các mục "overview""details", đã được bổ sung đầy đủ. Các nhãn như "numberOfDevices" được cập nhật để phản ánh chính xác thay đổi trong mô hình dữ liệu. Các bản dịch tiếng Việt phù hợp và rõ ràng với yêu cầu của giao diện người dùng.

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: 6

🧹 Nitpick comments (10)
sep490-commons/springfw-impl/src/main/java/commons/springfw/impl/Configs.java (1)

14-17: LGTM! Consider configuring BCrypt strength.

The implementation is secure using BCryptPasswordEncoder. For additional security, you could explicitly configure the strength parameter.

-    public PasswordEncoder passwordEncoder() {
-        return new BCryptPasswordEncoder();
+    public PasswordEncoder passwordEncoder() {
+        return new BCryptPasswordEncoder(12); // Increased strength for better security
sep490-commons/springfw-impl/src/main/java/commons/springfw/impl/securities/JwtAuthenticationConverter.java (1)

10-10: LGTM! Good use of Spring's dependency injection.

The addition of @Component annotation is correct and aligns with Spring's dependency injection pattern.

Consider extracting the JWT claims processing logic into separate private methods to improve readability and maintainability. For example:

+    private Set<SimpleGrantedAuthority> extractAuthorities(Object authoritiesClaim) {
+        if (!(authoritiesClaim instanceof List<?> authoritiesLists)) {
+            return Collections.emptySet();
+        }
+        return authoritiesLists
+                .stream()
+                .filter(String.class::isInstance)
+                .map(authority -> new SimpleGrantedAuthority((String) authority))
+                .collect(Collectors.toUnmodifiableSet());
+    }
+
+    private List<BuildingPermissionDTO> extractBuildingPermissions(Object buildingPermissionsClaim) {
+        if (!(buildingPermissionsClaim instanceof List<?> buildingPermissionsList)) {
+            return Collections.emptyList();
+        }
+        return buildingPermissionsList
+                .stream()
+                .filter(LinkedTreeMap.class::isInstance)
+                .map(this::mapToBuildingPermission)
+                .toList();
+    }
+
+    private BuildingPermissionDTO mapToBuildingPermission(Object permission) {
+        var permissionMap = (LinkedTreeMap) permission;
+        UUID uuid = Optional.ofNullable(permissionMap.get(BuildingPermissionDTO.Fields.buildingId))
+                        .map(String.class::cast)
+                        .map(UUID::fromString)
+                        .orElse(null);
+        return new BuildingPermissionDTO(
+                uuid,
+                BuildingPermissionRole.valueOf((String) permissionMap.get(BuildingPermissionDTO.Fields.role))
+        );
+    }

Also applies to: 20-20

sep490-frontend/src/app/components/sidebar/sidebar.component.ts (2)

33-46: Consider adding a fallback for this.items when the user is not an ENTERPRISE_OWNER.

Currently, the items property is only set if includeRole() returns true for the ENTERPRISE_OWNER role. If not, items remains undefined. For better clarity and user experience, you might want to handle other roles or set an empty menu array as a fallback to avoid potential runtime checks for undefined.

 this.applicationService.UserData.pipe(takeUntil(this.destroy$)).subscribe(
   (userData: UserData): void => {
     if (this.applicationService.includeRole(userData.authorities, UserRole.ENTERPRISE_OWNER)) {
       this.items = this.buildEnterpriseOwnerMenu();
     } else {
+      this.items = [];
     }
   }
 );

47-49: Align Settings label with existing localization approach.

While other labels (like 'enterprise.title') seem to use translation keys, 'Settings' is a plain string. Consider using a translation key to maintain consistency in localization.

sep490-frontend/src/app/components/sidebar/sidebar.component.html (1)

3-6: Clickable logo span may need accessibility enhancements.

Wrapping a <span> with a click listener is fine, but it might not be keyboard-accessible by default. Consider using an <a> or <button> element, adding a tabindex or ARIA attributes to improve accessibility for keyboard-only users.

-<span
-    class="inline-flex items-center pt-8 px-4 cursor-pointer"
-    (click)="homepage()"
->
+<a
+    href="#"
+    class="inline-flex items-center pt-8 px-4 cursor-pointer"
+    (click)="homepage()"
+    tabindex="0"
+    aria-label="Go to homepage"
+>
sep490-enterprise/src/main/java/enterprise/rest/DevController.java (1)

1-51: Add API documentation.

Consider adding OpenAPI/Swagger documentation to describe the purpose and usage of these development endpoints.

Add these annotations:

+@Tag(name = "Development", description = "Endpoints for development and testing purposes only")
 @RestController
 
     @PostMapping
+    @Operation(summary = "Log and return request body")
+    @ApiResponse(responseCode = "200", description = "Request body returned successfully")
     public String save(@RequestBody String body) {
 
     @PostMapping("/save-business-error")
+    @Operation(summary = "Simulate a business error")
+    @ApiResponse(responseCode = "417", description = "Demo business error thrown")
     public String saveBusinessError(@RequestBody String body) {
 
     @PostMapping("/save-technical-error")
+    @Operation(summary = "Simulate a technical error")
+    @ApiResponse(responseCode = "500", description = "Demo technical error thrown")
     public String saveTechnicalError(@RequestBody String body) {
sep490-frontend/src/app/app-routing.module.ts (1)

76-80: DEV_PATH route might need a guard for production.
Consider restricting the dev module to authorized users or removing it from production builds.

sep490-frontend/src/app/modules/core/services/application.service.ts (2)

69-70: private readonly userInfoSubject and userDataSubject introduced.
Consider explicitly typing these subjects to improve code clarity (e.g., private readonly userDataSubject: BehaviorSubject<UserData | null>). Inferred types are acceptable, but explicit types can reduce confusion.


114-127: postLogin method updates user data.
Functionality is appropriate, but lacks explicit error handling. Consider adding .catchError(...) or .subscribe({ next: ..., error: ... }) for robust error management.

sep490-idp/src/main/java/green_buildings/idp/configs/AuthorizationServerConfig.java (1)

50-50: Address TODO comment regarding deprecation.

There's a TODO comment about solving deprecated code. This should be addressed to ensure the application uses current, supported APIs.

Would you like me to help identify the deprecated APIs and suggest current alternatives?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 75415bc and a1ff3bf.

📒 Files selected for processing (15)
  • sep490-commons/springfw-impl/src/main/java/commons/springfw/impl/Configs.java (1 hunks)
  • sep490-commons/springfw-impl/src/main/java/commons/springfw/impl/audit/AuditorAwareImpl.java (1 hunks)
  • sep490-commons/springfw-impl/src/main/java/commons/springfw/impl/securities/JwtAuthenticationConverter.java (2 hunks)
  • sep490-enterprise/src/main/java/enterprise/EnterpriseApplication.java (1 hunks)
  • sep490-enterprise/src/main/java/enterprise/rest/DevController.java (1 hunks)
  • sep490-enterprise/src/main/java/enterprise/securities/ResourceServerConfig.java (1 hunks)
  • sep490-enterprise/src/test/java/enterprise/rest/DevControllerTest.java (1 hunks)
  • sep490-frontend/src/app/app-routing.module.ts (2 hunks)
  • sep490-frontend/src/app/components/sidebar/sidebar.component.html (2 hunks)
  • sep490-frontend/src/app/components/sidebar/sidebar.component.ts (1 hunks)
  • sep490-frontend/src/app/modules/core/services/application.service.ts (3 hunks)
  • sep490-idp/src/main/java/green_buildings/idp/IdentityProvider.java (1 hunks)
  • sep490-idp/src/main/java/green_buildings/idp/configs/AuthorizationServerConfig.java (3 hunks)
  • sep490-idp/src/main/java/green_buildings/idp/configs/GenericSecurityConfig.java (0 hunks)
  • sep490-idp/src/main/java/green_buildings/idp/validators/UserValidator.java (0 hunks)
💤 Files with no reviewable changes (2)
  • sep490-idp/src/main/java/green_buildings/idp/validators/UserValidator.java
  • sep490-idp/src/main/java/green_buildings/idp/configs/GenericSecurityConfig.java
🔇 Additional comments (29)
sep490-commons/springfw-impl/src/main/java/commons/springfw/impl/audit/AuditorAwareImpl.java (1)

6-6: LGTM! Good use of Spring's dependency injection.

The addition of @Component annotation is correct and aligns with Spring's dependency injection pattern.

Also applies to: 10-10

sep490-enterprise/src/main/java/enterprise/EnterpriseApplication.java (1)

5-5:

❓ Verification inconclusive

Verify if explicit component scanning is necessary.

@SpringBootApplication already includes @ComponentScan by default. The explicit @ComponentScan might be redundant unless you have a specific reason to override the default scanning behavior.

Run this script to check if there are any components that require explicit scanning:

Also applies to: 9-9


🏁 Script executed:

#!/bin/bash
# Description: Check for components in the commons.springfw package that might require explicit scanning

# Search for Spring components in the commons.springfw package
echo "Spring components in commons.springfw package:"
rg -l "@(Component|Service|Repository|Controller|Configuration)" "commons/springfw"

# Check if commons.springfw is already included in any other configuration
echo -e "\nExisting component scan configurations:"
rg -A 2 "@ComponentScan" .

Length of output: 1051


Review Verification: Confirming the Need for Explicit Component Scanning

Based on the executed script, we see that the application explicitly scans for the packages "enterprise" and "commons.springfw". While the default behavior of @SpringBootApplication would scan only the package of the main class (here, "enterprise"), the explicit inclusion of "commons.springfw" suggests that components from that package are intended to be picked up—likely because they are external to the main package hierarchy.

Key observations:

  • The search for Spring components in a folder corresponding to "commons.springfw" returned an error, implying that either the source isn’t in the repository or it's being provided via an external dependency.
  • A similar scanning configuration appears in another module, consistently including "commons.springfw".

Action Items:

  • Confirm if the "commons.springfw" package represents an external dependency or if it’s located outside the default scan path. If it isn’t actively contributing Spring components (or they are already auto-configured), you might consider removing the explicit @ComponentScan.
  • Otherwise, if components from "commons.springfw" are required and are not automatically detected by Spring Boot, retaining the explicit scan is justified.
sep490-frontend/src/app/components/sidebar/sidebar.component.ts (5)

2-11: All imports appear consistent and appropriate.

The imports for Router, takeUntil, UserRole, ApplicationService, UserData, and SubscriptionAwareComponent align well with the usage in this component, ensuring proper subscription handling and route navigation.


18-21: Extending SubscriptionAwareComponent is a good practice for managing subscriptions.

By extending SubscriptionAwareComponent, you ensure that all subscriptions are properly terminated when the component is destroyed, reducing the risk of memory leaks.


26-31: Constructor injection and super() call look correct.

Injecting ApplicationService and Router while calling super() ensures the base class (SubscriptionAwareComponent) is fully initialized. No issues here.


51-52: homepage() implementation is concise and effective.

Using void this.router.navigate(['/']) is a quick way to ignore the resulting promise. This approach is acceptable, and the method name clearly indicates its intent.


55-57: Building a specialized enterprise menu is clear and organized.

The buildEnterpriseOwnerMenu() method neatly encapsulates the items for enterprise users. If other roles gain distinct menus, consider a similar approach to keep the code modular and maintainable.

sep490-frontend/src/app/components/sidebar/sidebar.component.html (1)

35-35: Removal of extra space in the closing tag is harmless.

No functional impact. This minor HTML cleanup is fine.

sep490-frontend/src/app/app-routing.module.ts (8)

1-1: Import for inject looks good.
No issues found. This change is consistent with the newer Angular dependency injection approach and requires Angular 14+.


3-8: Imports from angular-auth-oidc-client and rxjs appear consistent.
These imports match the usage below and there are no obvious issues.


15-15: Importing ApplicationService is appropriate.
No problems or code smells detected here.


36-37: Guard activation on Home route is valid.
Adding authGuard alongside AutoLoginPartialRoutesGuard enforces stricter access control.


41-42: Dashboard route guard updated successfully.
Ensuring the user is authenticated before accessing dashboard functionality is a good practice.


50-50: Authentication guard for AUTH_PATH.
Applying the guard here is consistent with the rest of the routes.


58-58: Authentication guard for ENTERPRISE_PATH.
No issues found, this aligns with enterprise module protection.


66-66: Guard applied to EMISSIONS_PATH.
Good practice to ensure that only authenticated users can access emissions functionality.

sep490-frontend/src/app/modules/core/services/application.service.ts (7)

7-14: New imports for reactivity and data handling.
The additional RxJS imports (BehaviorSubject, filter, map, etc.) appear properly utilized below.


15-16: UUID and UserRole imports.
These imports provide type safety for enterprise IDs and roles. No issues found.


29-31: UserInfoData interface extension.
Merging UserInfoEmailScope and UserInfoPhoneScope with sub is a clean approach.


33-37: UserData interface introduced.
Extending JwtPayload with authorities, permissions, and enterpriseId is a clear way to unify user data.


74-74: userDataSubject initialization.
Initializing BehaviorSubject<UserData | null>(null) is correct. No issues.


93-97: Getter UserData returning a filtered observable.
Straightforward approach to expose non-null UserData. This is good practice for typed reactive data flows.


105-108: includeRole checks for presence of a role.
Implementation looks correct. Be mindful of any potential case sensitivity or future role naming conventions, but for now, this is fine.

sep490-idp/src/main/java/green_buildings/idp/IdentityProvider.java (2)

10-10:

❓ Verification inconclusive

Verify component scanning configuration.

The component scanning configuration now includes both commons.springfw and green_buildings.idp packages. Ensure that:

  1. All required components are being picked up
  2. No unintended components are being scanned

🏁 Script executed:

#!/bin/bash
# Description: Check for Spring components in the specified packages
# Look for @Component, @Service, @Repository, @Controller, etc.

echo "Checking for Spring components in commons.springfw:"
rg -l "@(Component|Service|Repository|Controller|Configuration)" -g "commons/springfw/**"

echo -e "\nChecking for Spring components in green_buildings.idp:"
rg -l "@(Component|Service|Repository|Controller|Configuration)" -g "green_buildings/idp/**"

Length of output: 722


Component Scanning Verification: Manual Validation Required

The component scanning configuration now targets the "commons.springfw" and "green_buildings.idp" packages. However, our initial automated search did not yield any Spring component files—likely due to the file filters applied by ripgrep. Please:

  • Manually verify or adjust the search criteria to ensure the repository contains the expected Spring components (i.e., classes annotated with @component, @service, @repository, etc.) under these package paths.
  • Double-check that the directory structure matches the expected patterns for the packages specified.

12-12:

✅ Verification successful

Verify method security configuration impact.

The addition of @EnableMethodSecurity(jsr250Enabled = true) enables JSR-250 security annotations. This is a good practice for method-level security but requires verification of:

  1. Existing @RolesAllowed, @PermitAll, and @DenyAll annotations
  2. Potential security gaps during the transition

🏁 Script executed:

#!/bin/bash
# Description: Check for JSR-250 security annotations usage

echo "Checking for JSR-250 security annotations:"
rg -A 2 "@(RolesAllowed|PermitAll|DenyAll)"

Length of output: 2165


JSR-250 security configuration verified – no gaps detected.

The verification confirms that the codebase already leverages JSR-250 annotations (primarily @RolesAllowed) in multiple locations, including:

  • sep490-idp/src/main/java/green_buildings/idp/rest/DevResource.java
  • sep490-idp/src/main/java/green_buildings/idp/rest/EnterpriseUserRestController.java
  • sep490-enterprise/src/main/java/enterprise/rest/BuildingController.java
  • sep490-enterprise/src/main/java/enterprise/rest/DevController.java
  • sep490-enterprise/src/main/java/enterprise/rest/EnterpriseController.java

Since no instances of @PermitAll or @DenyAll were encountered and the usage aligns with the expected behavior for enabling method-level security, no further changes are required at this point. Please continue to monitor the runtime behavior to ensure that no security gaps emerge during the transition.

sep490-enterprise/src/main/java/enterprise/securities/ResourceServerConfig.java (2)

18-21: Good use of constructor injection pattern.

The switch to constructor injection using @RequiredArgsConstructor for JwtAuthenticationConverter follows Spring best practices for dependency management.


29-29:

✅ Verification successful

Verify CORS configuration after bean removal.

The CORS configuration is now using defaults (Customizer.withDefaults()), but the CorsConfigurationSource bean has been removed. This might affect cross-origin requests.

Also applies to: 34-34


🏁 Script executed:

#!/bin/bash
# Description: Check for CORS-related configurations

echo "Checking for CORS configurations:"
rg -A 5 "CorsConfiguration|@CrossOrigin"

echo -e "\nChecking for existing CORS endpoints:"
rg -l "Origin.*" -g "**/*.java"

Length of output: 5330


Action: Confirm reliance on centralized CORS configuration

The removal of the local CorsConfigurationSource bean in ResourceServerConfig.java appears intentional. Our search shows that CORS is configured in shared modules (notably in sep490-commons/springfw-impl/src/main/java/commons/springfw/impl/securities/CorsConfig.java and Configs.java). Please ensure that these global settings (allowed headers, methods, origins, and credentials) fully cover your use case for cross-origin requests.

  • Verify that endpoints relying on CORS are correctly wired to the centralized configuration.
  • Confirm that the default CORS configuration meets your security and application requirements in the absence of a locally defined bean.
sep490-idp/src/main/java/green_buildings/idp/configs/AuthorizationServerConfig.java (2)

74-74: Verify JWT converter configuration.

The JWT authentication converter is now injected and configured consistently across both resource and authorization servers. This is a good practice for maintaining consistent JWT handling.


82-82:

❓ Verification inconclusive

Verify exception handling for JWK source.

The NoSuchAlgorithmException has been removed from the method signature. Ensure that:

  1. The exception is properly handled internally
  2. No cryptographic algorithm issues can occur at runtime

🏁 Script executed:

#!/bin/bash
# Description: Check for cryptographic algorithm usage and exception handling

echo "Checking for cryptographic algorithm configurations:"
rg -A 5 "KeyPair|KeyStore|RSAKey"

echo -e "\nChecking for exception handling patterns:"
rg -A 5 "try|catch|throw" -g "**/AuthorizationServerConfig.java"

Length of output: 7306


Review: Confirm Exception Handling in jwkSource()

After reviewing the code and verifying the cryptographic configurations, note that the jwkSource() method no longer declares a NoSuchAlgorithmException and does not include an explicit try–catch block. It relies on the underlying Spring Security and Nimbus JOSE libraries to handle any cryptographic or key generation issues as runtime exceptions. Please ensure that:

  • The keystore resource (keystore.jks) is reliably available and correctly configured.
  • Any cryptographic misconfiguration or algorithm issue results in a controlled startup failure or is otherwise managed through integration/unit tests.
  • You’ve verified via tests that no unexpected runtime failures occur due to missing handling for potential cryptographic errors.

@thongdanghoang thongdanghoang force-pushed the feature/77-userstory-enterprise branch 2 times, most recently from 8b1fafc to bdde695 Compare February 16, 2025 08:20
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.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments.

Actionable comments posted: 1

🔭 Outside diff range comments (3)
sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.ts (1)

67-70: 🛠️ Refactor suggestion

Improve map marker handling.

The current implementation adds markers on click without any validation or clear purpose. Consider:

  1. Adding validation before placing markers
  2. Implementing a clear use case for marker placement
  3. Adding the ability to remove markers
sep490-idp/src/main/java/green_buildings/idp/configs/AuthorizationServerConfig.java (2)

82-93: ⚠️ Potential issue

Move sensitive credentials to configuration.

The keystore password is hard-coded in the source code. This poses a security risk and violates security best practices.

Move the password to a secure configuration source (e.g., environment variables or a secure configuration service). Example:

-var keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("keystore.jks"), "P@ssW0rd".toCharArray());
+@Value("${security.keystore.password}")
+private String keystorePassword;
+
+// In the method
+var keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("keystore.jks"), keystorePassword.toCharArray());

50-51: 💡 Verification agent

🧩 Analysis chain

Address the TODO comment regarding deprecated code.

The comment indicates that OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http) is deprecated. This should be addressed to ensure future compatibility.


🌐 Web query:

What is the recommended replacement for OAuth2AuthorizationServerConfiguration.applyDefaultSecurity in Spring Authorization Server?

💡 Result:

The recommended replacement for the deprecated OAuth2AuthorizationServerConfiguration.applyDefaultSecurity() in Spring Authorization Server (version 1.4+) is to use OAuth2AuthorizationServerConfigurer directly with HttpSecurity. Here's how to implement it:

Updated Configuration Approach

@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
    http
        .securityMatcher(
            new OrRequestMatcher(
                new AntPathRequestMatcher("/oauth2/**"),
                new AntPathRequestMatcher("/connect/**")
            )
        )
        .with(
            OAuth2AuthorizationServerConfigurer.authorizationServer(),
            Customizer.withDefaults()
        );
    return http.build();
}

Key Changes:

  1. Replace Deprecated Method

    • Old (deprecated):
      OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
    • New:
      http.with(OAuth2AuthorizationServerConfigurer.authorizationServer(), Customizer.withDefaults());
  2. Required Imports

    import org.springframework.security.config.Customizer;
    import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;

Why This Works:

  • The OAuth2AuthorizationServerConfigurer now handles protocol endpoints (e.g., /oauth2/authorize, /oauth2/token) by default[1][5][9].
  • Customizer.withDefaults() applies standard security settings equivalent to the deprecated method[2][9].

Additional Considerations:

  • OpenID Connect Support: To enable OpenID Connect 1.0, explicitly initialize OidcConfigurer:
    http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
        .oidc(Customizer.withDefaults());
  • Endpoint Customization: Override default endpoints via AuthorizationServerSettings if needed[1][3].

This update resolves deprecation warnings and ensures compatibility with Spring Authorization Server versions ≥1.4[2][5][9].

Citations:


Update Deprecated Security Configuration

Please replace the deprecated call with the new recommended approach. Specifically, change:

// TODO: solve deprecated
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);

to

http.with(OAuth2AuthorizationServerConfigurer.authorizationServer(), Customizer.withDefaults());

Make sure to update your imports accordingly:

import org.springframework.security.config.Customizer;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;

This change adheres to Spring Authorization Server (≥1.4) recommendations and resolves the deprecation warning.

🧹 Nitpick comments (12)
sep490-frontend/src/app/modules/enterprise/components/subscription/subscription.component.ts (2)

11-13: Align selector name with component name.

The selector 'app-subscriptions' (plural) doesn't match the component name 'subscription' (singular). Consider updating the selector to maintain consistency:

-  selector: 'app-subscriptions',
+  selector: 'app-subscription',

43-47: Implement credit purchase logic.

The onBuyCredit method contains a TODO comment but lacks implementation. This could block users from purchasing credits.

Would you like me to help implement the credit purchase logic or create an issue to track this task?

sep490-frontend/src/app/components/sidebar/sidebar.component.ts (3)

33-49: Consider adding error handling and localization.

While the subscription management is good, consider these improvements:

  1. Add error handling to the subscription
  2. Use translation keys for the settings menu label

Apply this diff:

 ngOnInit(): void {
   this.applicationService.UserData.pipe(takeUntil(this.destroy$)).subscribe(
     (userData: UserData): void => {
       if (
         this.applicationService.includeRole(
           userData.authorities,
           UserRole.ENTERPRISE_OWNER
         )
       ) {
         this.items = this.buildEnterpriseOwnerMenu();
       }
-    }
+    },
+    (error: Error) => {
+      console.error('Failed to load user data:', error);
+    }
   );
   this.settings = [
-    {label: 'Settings', icon: 'pi pi-cog', route: '/settings'}
+    {label: 'settings.title', icon: 'pi pi-cog', route: '/settings'}
   ];
 }

51-53: Simplify the homepage navigation.

The void operator is unnecessary here as router.navigate already returns a Promise.

Apply this diff:

 homepage(): void {
-  return void this.router.navigate(['/']);
+  this.router.navigate(['/']);
 }

55-99: Improve menu structure and consistency.

  1. The method is too long, consider breaking it into smaller methods
  2. Menu labels should consistently use translation keys

Apply this diff:

-  // eslint-disable-next-line max-lines-per-function
-  private buildEnterpriseOwnerMenu(): MenuItem[] {
+  private buildEnterpriseOwnerMenu(): MenuItem[] {
+    return [
+      this.buildEnterpriseSection(),
+      this.buildManageSection()
+    ];
+  }
+
+  private buildEnterpriseSection(): MenuItem {
     return [
       {
-        label: 'enterprise.title',
+        label: 'menu.enterprise.title',
         items: [
           {
-            label: 'Dashboard',
+            label: 'menu.dashboard.title',
             icon: 'pi pi-chart-line',
             route: `/${AppRoutingConstants.DASHBOARD_PATH}`
           },
           // ... rest of the enterprise items
         ]
-      },
+      }
+    ];
+  }
+
+  private buildManageSection(): MenuItem {
+    return [
       {
-        label: 'Manage',
+        label: 'menu.manage.title',
         items: [
           {
-            label: 'Users',
+            label: 'menu.users.title',
             icon: 'pi pi-users',
             route: `/${AppRoutingConstants.AUTH_PATH}/${AppRoutingConstants.USERS_PATH}`
           },
           // ... rest of the manage items
         ]
       }
     ];
   }
sep490-frontend/src/app/app-routing.module.ts (1)

29-29: Simplify the operator chain.

The switchMap(loggedIn => of(loggedIn)) is unnecessary as it's just passing through the value without transformation.

-    switchMap(loggedIn => of(loggedIn))
+    map(loggedIn => loggedIn)
sep490-frontend/src/app/modules/core/services/application.service.ts (2)

114-127: Optimize postLogin subscriptions.

The method has two separate subscriptions that could be combined using forkJoin for better efficiency.

   postLogin(): void {
-    this.oidcSecurityService
-      .getPayloadFromAccessToken()
-      .pipe(takeUntil(this.destroy$))
-      .subscribe((data: UserData): void => {
-        this.userDataSubject.next(data);
-      });
-    this.oidcSecurityService
-      .getUserData()
-      .pipe(takeUntil(this.destroy$))
-      .subscribe(userInfo => {
-        this.userInfoSubject.next(userInfo);
-      });
+    forkJoin({
+      userData: this.oidcSecurityService.getPayloadFromAccessToken(),
+      userInfo: this.oidcSecurityService.getUserData()
+    })
+      .pipe(takeUntil(this.destroy$))
+      .subscribe(({ userData, userInfo }) => {
+        this.userDataSubject.next(userData);
+        this.userInfoSubject.next(userInfo);
+      });
   }

93-93: Follow Angular naming conventions for getters.

The getter name should be camelCase according to Angular naming conventions.

-  get UserData(): Observable<UserData> {
+  get userData(): Observable<UserData> {
sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.ts (1)

77-89: Consider implementing proper pagination.

The current implementation uses a hardcoded page size of 100, which may not scale well with large datasets. Consider:

  1. Implementing server-side pagination
  2. Adding load more functionality
  3. Using a reasonable initial page size (e.g., 20-25 items)
sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.html (2)

40-109: Enhance accessibility of the building card template.

Consider adding the following accessibility improvements:

  1. ARIA labels for buttons and interactive elements
  2. Role attributes for semantic HTML
  3. Keyboard navigation support
 <div class="rounded box-shadow border-t-2 border-t-primary *:w-full">
-    <div class="p-4 rounded-t bg-primary-50 flex justify-between">
+    <div class="p-4 rounded-t bg-primary-50 flex justify-between" role="heading" aria-level="2">
     <div class="text-xl font-bold">{{ building.name }}</div>
     <div class="">
         <p-button
             (onClick)="viewBuildingDetails(building.id)"
             icon="pi pi-info"
             text
+            [attr.aria-label]="'View details for ' + building.name"
         />
         <p-button
             icon="pi pi-map"
             text
+            [attr.aria-label]="'View map for ' + building.name"
         />
     </div>

24-30: Improve map container responsiveness.

The fixed height of 600px may not be optimal for all screen sizes. Consider:

  1. Using viewport-relative units (vh)
  2. Adding media queries for different screen sizes
  3. Implementing a responsive container system
-<div [hidden]="listView" class="border-black border-2 border-solid" style="height: 600px">
+<div [hidden]="listView" class="border-black border-2 border-solid" style="height: 80vh; min-height: 400px; max-height: 800px">
sep490-frontend/src/app/modules/dev/components/toolbox/toolbox.component.html (1)

1-99: Add documentation for the toolbox component.

Consider adding:

  1. Comments explaining different button variations
  2. Usage examples in code comments
  3. Documentation for the card-template component
+<!-- Card template example -->
 <card-template>
   <div header>header</div>
   <div body>body</div>
   <div footer>footer</div>
 </card-template>

+<!-- Primary button variations -->
 <div class="flex justify-center flex-wrap gap-4 mb-6">
   <p-button label="Primary" [raised]="true"/>
   <!-- ... -->
 </div>
🛑 Comments failed to post (1)
sep490-frontend/src/app/modules/enterprise/components/building-details/building-details.component.ts (1)

31-34: ⚠️ Potential issue

Fix inconsistent validation for numberOfDevices.

The field is initialized to 0 but has a minimum validation of 1, which creates an invalid initial state.

-    numberOfDevices: new FormControl(0, {
+    numberOfDevices: new FormControl(1, {
       nonNullable: true,
       validators: [Validators.min(1), Validators.required]
     })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    numberOfDevices: new FormControl(1, {
      nonNullable: true,
      validators: [Validators.min(1), Validators.required]
    })

@thongdanghoang thongdanghoang force-pushed the feature/77-userstory-enterprise branch from bdde695 to 2469597 Compare February 16, 2025 09:06
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: 2

♻️ Duplicate comments (1)
sep490-frontend/src/app/app-routing.module.ts (1)

17-31: 🛠️ Refactor suggestion

Optimize the auth guard implementation.

The current implementation has a few areas for improvement:

  1. The switchMap(loggedIn => of(loggedIn)) is unnecessary and can be removed as it doesn't transform the data.
  2. The return type Observable<LoginResponse> might not match the actual type from checkAuth().
  3. Consider implementing canActivate interface for better type safety.

Here's the suggested implementation:

-const authGuard: () => Observable<LoginResponse> = () => {
+const authGuard = () => {
   const authService = inject(OidcSecurityService);
   const applicationService = inject(ApplicationService);
 
   return authService.checkAuth().pipe(
     tap(authData => {
       if (!authData.isAuthenticated) {
         applicationService.login();
       } else {
         applicationService.postLogin();
       }
     })
-    switchMap(loggedIn => of(loggedIn))
   );
 };
🧹 Nitpick comments (6)
sep490-enterprise/src/test/java/enterprise/TestcontainersConfigs.java (1)

43-56: Consider removing commented-out code.

The old static lifecycle methods are now commented out and can be safely removed since they've been replaced with the static initialization block.

-//    @BeforeAll
-//    static void beforeAll() {
-//        postgres.start();
-//        idP.withExposedPorts(8180)
-//                .withCommand("start-dev --http-port 8180")
-//                .waitingFor(Wait.forHttp("/realms/greenbuildings/.well-known/openid-configuration"))
-//                .start();
-//    }
-
-//    @AfterAll
-//    static void afterAll() {
-//        postgres.stop();
-//        idP.stop();
-//    }
sep490-frontend/src/app/components/sidebar/sidebar.component.ts (3)

33-49: Consider improving i18n and configuration management.

While the implementation is functionally correct, consider these improvements:

  1. Move the settings menu items to a configuration file for better maintainability.
  2. Use a translation key for the 'Settings' label to maintain i18n consistency, similar to how 'enterprise.title' is used in the main menu.
-    this.settings = [
-      {label: 'Settings', icon: 'pi pi-cog', route: '/settings'}
-    ];
+    this.settings = [
+      {label: 'settings.title', icon: 'pi pi-cog', route: '/settings'}
+    ];

51-53: Consider using routing constants.

For consistency with other routes in the component, consider using AppRoutingConstants for the root route navigation.

-    return void this.router.navigate(['/']);
+    return void this.router.navigate([AppRoutingConstants.ROOT_PATH]);

55-99: Consider refactoring menu configuration.

The menu structure is well-organized, but consider these improvements:

  1. Move menu items to a configuration file to improve maintainability and avoid the eslint warning.
  2. Split the method into smaller functions, each handling a specific menu section (enterprise/manage).

Example refactor:

private buildEnterpriseOwnerMenu(): MenuItem[] {
  return [
    this.buildEnterpriseSection(),
    this.buildManageSection()
  ];
}

private buildEnterpriseSection(): MenuItem {
  return {
    label: 'enterprise.title',
    items: [
      /* enterprise menu items */
    ]
  };
}

private buildManageSection(): MenuItem {
  return {
    label: 'Manage',
    items: [
      /* manage menu items */
    ]
  };
}
sep490-frontend/src/app/modules/core/services/application.service.ts (2)

76-85: Consider adding error handling to the token payload subscription.

While the subscription logic is correct, it would be beneficial to handle potential errors when retrieving the token payload.

Consider adding error handling:

 this.registerSubscription(
   this.oidcSecurityService.isAuthenticated$
     .pipe(
       filter((auth: AuthenticatedResult): boolean => auth.isAuthenticated),
       switchMap(() => this.oidcSecurityService.getPayloadFromAccessToken())
     )
-    .subscribe((userData: UserData): void =>
-      this.userDataSubject.next(userData)
-    )
+    .subscribe({
+      next: (userData: UserData): void => this.userDataSubject.next(userData),
+      error: (error): void => {
+        console.error('Failed to retrieve token payload:', error);
+        this.userDataSubject.next(null);
+      }
+    })
 );

105-108: Consider extracting the JWT role prefix as a constant.

The role prefix should be defined as a class constant for better maintainability.

+private static readonly JWT_ROLE_PREFIX = 'ROLE_';

 includeRole(authorities: string[], role: UserRole): boolean {
-  const jwtRolePrefix = 'ROLE_';
-  return authorities.includes(`${jwtRolePrefix}${UserRole[role]}`);
+  return authorities.includes(`${ApplicationService.JWT_ROLE_PREFIX}${UserRole[role]}`);
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8b1fafc and 2469597.

📒 Files selected for processing (19)
  • sep490-commons/springfw-impl/src/main/java/commons/springfw/impl/Configs.java (1 hunks)
  • sep490-commons/springfw-impl/src/main/java/commons/springfw/impl/audit/AuditorAwareImpl.java (1 hunks)
  • sep490-commons/springfw-impl/src/main/java/commons/springfw/impl/securities/JwtAuthenticationConverter.java (2 hunks)
  • sep490-enterprise/src/main/java/enterprise/EnterpriseApplication.java (1 hunks)
  • sep490-enterprise/src/main/java/enterprise/rest/DevController.java (1 hunks)
  • sep490-enterprise/src/main/java/enterprise/securities/ResourceServerConfig.java (1 hunks)
  • sep490-enterprise/src/test/java/enterprise/TestcontainersConfigs.java (1 hunks)
  • sep490-enterprise/src/test/java/enterprise/adapters/exchangerate_api/ExchangeRateApiCurrencyConverterTest.java (0 hunks)
  • sep490-enterprise/src/test/java/enterprise/rest/BuildingControllerTest.java (1 hunks)
  • sep490-enterprise/src/test/java/enterprise/rest/DevControllerTest.java (1 hunks)
  • sep490-frontend/src/app/app-routing.module.ts (2 hunks)
  • sep490-frontend/src/app/components/sidebar/sidebar.component.html (2 hunks)
  • sep490-frontend/src/app/components/sidebar/sidebar.component.ts (1 hunks)
  • sep490-frontend/src/app/modules/core/services/application.service.ts (3 hunks)
  • sep490-frontend/src/app/modules/enterprise/components/subscription/subscription.component.ts (1 hunks)
  • sep490-idp/src/main/java/green_buildings/idp/IdentityProvider.java (1 hunks)
  • sep490-idp/src/main/java/green_buildings/idp/configs/AuthorizationServerConfig.java (3 hunks)
  • sep490-idp/src/main/java/green_buildings/idp/configs/GenericSecurityConfig.java (0 hunks)
  • sep490-idp/src/main/java/green_buildings/idp/validators/UserValidator.java (0 hunks)
💤 Files with no reviewable changes (3)
  • sep490-enterprise/src/test/java/enterprise/adapters/exchangerate_api/ExchangeRateApiCurrencyConverterTest.java
  • sep490-idp/src/main/java/green_buildings/idp/validators/UserValidator.java
  • sep490-idp/src/main/java/green_buildings/idp/configs/GenericSecurityConfig.java
🚧 Files skipped from review as they are similar to previous changes (11)
  • sep490-frontend/src/app/components/sidebar/sidebar.component.html
  • sep490-commons/springfw-impl/src/main/java/commons/springfw/impl/securities/JwtAuthenticationConverter.java
  • sep490-commons/springfw-impl/src/main/java/commons/springfw/impl/audit/AuditorAwareImpl.java
  • sep490-commons/springfw-impl/src/main/java/commons/springfw/impl/Configs.java
  • sep490-enterprise/src/test/java/enterprise/rest/DevControllerTest.java
  • sep490-enterprise/src/main/java/enterprise/rest/DevController.java
  • sep490-enterprise/src/main/java/enterprise/securities/ResourceServerConfig.java
  • sep490-enterprise/src/main/java/enterprise/EnterpriseApplication.java
  • sep490-frontend/src/app/modules/enterprise/components/subscription/subscription.component.ts
  • sep490-idp/src/main/java/green_buildings/idp/IdentityProvider.java
  • sep490-idp/src/main/java/green_buildings/idp/configs/AuthorizationServerConfig.java
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build Java Modules (sep490-enterprise)
🔇 Additional comments (10)
sep490-enterprise/src/test/java/enterprise/rest/BuildingControllerTest.java (2)

40-40: LGTM!

The test has been updated to use the new numberOfDevices field instead of the removed floors field.


37-41: Add test cases for invalid numberOfDevices values.

The test coverage for the new numberOfDevices field should be expanded to include edge cases.

Consider adding these test cases:

@Test
void createBuilding_withNegativeNumberOfDevices_returns400() {
    var building = BuildingDTO.builder()
                            .name("Building 1")
                            .numberOfDevices(-1)
                            .build();
    RestAssured.given()
               .auth().oauth2(getToken("enterprise.owner@greenbuildings.com", "enterprise.owner"))
               .contentType(ContentType.JSON)
               .body(building)
               .when()
               .post("/api/buildings")
               .then()
               .statusCode(400);
}
sep490-enterprise/src/test/java/enterprise/TestcontainersConfigs.java (3)

7-9: LGTM!

The test configuration has been properly updated to use Spring Boot's test framework with Testcontainers support.

Also applies to: 15-15, 20-21


27-33: LGTM!

The container initialization has been moved to a static block, which is a good practice for ensuring containers are started only once before any tests run.


35-41: LGTM!

The instance-level setup with @BeforeEach ensures that each test starts with a fresh baseURI configuration.

sep490-frontend/src/app/components/sidebar/sidebar.component.ts (2)

1-21: LGTM! Good use of subscription management.

The component now properly extends SubscriptionAwareComponent which is a good practice for managing RxJS subscriptions and preventing memory leaks.


26-31: LGTM! Clean dependency injection.

The constructor follows Angular best practices with proper dependency injection and base class initialization.

sep490-frontend/src/app/modules/core/services/application.service.ts (3)

7-17: LGTM! Well-structured interfaces and imports.

The new interfaces UserInfoData and UserData are well-designed, properly extending their base interfaces and including all necessary fields for role-based access control.

Also applies to: 29-37


69-70: LGTM! Good encapsulation and immutability.

The changes improve encapsulation by making subjects private and readonly, preventing unintended modifications from outside the service.

Also applies to: 74-75


93-97: LGTM! Well-implemented UserData getter.

The getter properly filters out null values and provides type-safe access to user data.

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: 0

🧹 Nitpick comments (1)
sep490-frontend/src/app/modules/enterprise/components/payment/payment.component.ts (1)

53-56: Consider using type-safe field names for sorting.

The sort field name should be type-safe to prevent runtime errors if the field name changes.

Consider using an enum or const for sort field names:

enum PaymentSortField {
  CreatedDate = 'createdDate',
  Amount = 'amount'
}

this.sort = {
  field: PaymentSortField.CreatedDate,
  direction: 'DESC'
};
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c479643 and 66bbafc.

📒 Files selected for processing (2)
  • sep490-frontend/src/app/modules/enterprise/components/payment/payment.component.html (1 hunks)
  • sep490-frontend/src/app/modules/enterprise/components/payment/payment.component.ts (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build Java Modules (sep490-enterprise)
🔇 Additional comments (2)
sep490-frontend/src/app/modules/enterprise/components/payment/payment.component.ts (1)

62-84: LGTM! Sort configuration aligns with table columns.

The sort configuration correctly aligns with the sortable columns defined in the table. Both 'createdDate' and 'amount' fields are marked as sortable, which matches the sort implementation.

sep490-frontend/src/app/modules/enterprise/components/payment/payment.component.html (1)

35-42: LGTM! Sort binding is correctly implemented.

The sort binding is properly implemented on the table-template component, maintaining consistency with other input bindings.

@nganntqe170236 nganntqe170236 merged commit 9a72163 into main Feb 16, 2025
8 checks passed
@nganntqe170236 nganntqe170236 deleted the feature/77-userstory-enterprise branch February 16, 2025 10:32
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