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

fix(bulk-mileage): update bulk mileage #16539

Merged
merged 22 commits into from
Oct 30, 2024
Merged

fix(bulk-mileage): update bulk mileage #16539

merged 22 commits into from
Oct 30, 2024

Conversation

thorkellmani
Copy link
Member

@thorkellmani thorkellmani commented Oct 23, 2024

What

  • Add xlsx support to bulk mileage upload
  • Parse error messages from service and display

Why

  • NEED xlsx support
  • Error message should be more detailed

Checklist:

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • Formatting passes locally with my changes
  • I have rebased against main before asking for a review

Summary by CodeRabbit

  • New Features

    • Introduced new interfaces and union types for improved error handling in vehicle mileage updates.
    • Added new mutation methods for posting and updating vehicle mileage with enhanced error management.
    • Enhanced file upload functionality to support both .csv and .xlsx formats.
    • Added new messages for better user feedback regarding mileage input and file uploads.
  • Bug Fixes

    • Improved error handling for bulk mileage reading requests.
  • Documentation

    • Updated GraphQL schema to include new fields for error codes in responses.
  • Refactor

    • Streamlined error handling and response structures across various components and services.

@thorkellmani thorkellmani added the deploy-feature Deploys features to dev label Oct 23, 2024
Copy link
Contributor

github-actions bot commented Oct 23, 2024

Affected services are: api,service-portal,system-e2e,
Feature deployment of your services will begin shortly. Your feature will be accessible here:
https://fixbulk-milegae-update-api-catalogue.dev01.devland.is/api
https://fixbulk-milegae-update-beta.dev01.devland.is/
https://fixbulk-milegae-update-beta.dev01.devland.is/api
https://fixbulk-milegae-update-beta.dev01.devland.is/minarsidur
https://fixbulk-milegae-update-beta.dev01.devland.is/samradsgatt

Deployed services: service-portal,api,consultation-portal,web.
Excluded services: ``

Copy link
Contributor

coderabbitai bot commented Oct 24, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

This pull request introduces several significant changes related to vehicle mileage management, primarily focusing on enhancing error handling and response structures. New interfaces and union types for error responses are created, alongside updates to existing GraphQL mutations and resolvers. Additionally, improvements in file handling for mileage uploads are implemented, including support for multiple file formats. The modifications aim to provide more detailed error information and streamline the user experience when interacting with vehicle mileage data.

Changes

File Path Change Summary
libs/api/domains/vehicles/src/lib/dto/updateResponseError.dto.ts Added interface UpdateResponseError for structured error responses.
libs/api/domains/vehicles/src/lib/models/v3/postVehicleMileageResponse.model.ts Added union type VehicleMileagePostResponse for handling mileage post responses.
libs/api/domains/vehicles/src/lib/models/v3/putVehicleMileageResponse.model.ts Added union type VehicleMileagePutResponse for handling mileage put responses.
libs/api/domains/vehicles/src/lib/models/v3/vehicleMileageResponseError.model.ts Added class VehiclesMileageUpdateError for GraphQL error responses.
libs/api/domains/vehicles/src/lib/resolvers/mileage.resolver.ts Added methods postVehicleMileageReadingV2 and putVehicleMileageReadingV2 with enhanced error handling.
libs/api/domains/vehicles/src/lib/services/vehicles.service.ts Added methods postMileageReadingV2 and putMileageReadingV2 with improved error handling and structured responses.
libs/service-portal/assets/src/lib/messages.ts Updated messages for mileage input and file uploads to enhance user feedback.
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileage.graphql Updated mutations to utilize new versions with enhanced error handling.
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageFileDownloader.tsx Updated to allow dynamic file type selection for downloads.
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx Introduced MutationStatus type and centralized error handling for mutation responses.
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx Updated to handle multiple file formats and improved error handling for uploads.
libs/service-portal/assets/src/utils/parseFileToMileage.ts Added functionality for parsing mileage records from CSV and XLSX formats.
libs/service-portal/assets/src/screens/VehicleBulkMileageJobDetail/VehicleBulkMileageJobDetail.tsx Refined rendering logic for vehicle registration requests.
libs/api/domains/vehicles/src/lib/services/bulkMileage.service.ts Enhanced error handling in postBulkMileageReading method.
libs/api/domains/vehicles/src/lib/models/v3/bulkMileage/bulkMileageReadingResponse.model.ts Updated requestId field to be optional and added errorCode field.
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.graphql Added errorCode to mutation response for vehicleBulkMileagePost.
libs/api/domains/vehicles/src/lib/dto/vehiclesListInputV3.ts Added new optional field query to VehiclesListInputV3 class.

Possibly related PRs

Suggested reviewers

  • thordurhhh
  • rafnarnason

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

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.

@thorkellmani thorkellmani marked this pull request as ready for review October 24, 2024 11:36
@thorkellmani thorkellmani requested a review from a team as a code owner October 24, 2024 11:36
@thorkellmani thorkellmani changed the title fix(bulk-mileage): add xlsx support to upload fix(bulk-mileage): update bulk mileage Oct 24, 2024
Copy link
Contributor

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

🧹 Outside diff range and nitpick comments (9)
libs/api/domains/vehicles/src/lib/dto/updateResponseError.dto.ts (2)

1-12: Add JSDoc documentation and improve type definitions.

The interface would benefit from proper documentation and some structural improvements:

  1. Add JSDoc to describe the purpose and usage of this interface
  2. Consider extracting the error item type for reusability

Here's the suggested improvement:

+/**
+ * Represents an error response for vehicle mileage update operations.
+ * @interface UpdateResponseError
+ */
 export interface UpdateResponseError {
   type: string
   title: string
   status: number
-  Errors: Array<{
-    lookupNo: number
-    warnSever: string
-    errorMess: string
-    permno: string
-    warningSerialNumber: string
-  }>
+  errors: Array<VehicleMileageError>
 }
+
+/**
+ * Represents an individual error entry in the mileage update response.
+ * @interface VehicleMileageError
+ */
+interface VehicleMileageError {
+  lookupNo: number
+  warnSeverity: string
+  errorMessage: string
+  permitNumber: string
+  warningSerialNumber: string
+}

1-12: Consider generalizing the error response structure.

The current interface seems specific to vehicle mileage updates but follows a common error response pattern. Consider creating a more generic base error response type that can be extended for specific use cases.

Example approach:

/**
 * Base error response structure for API responses
 */
export interface BaseErrorResponse {
  type: string
  title: string
  status: number
  errors: Array<BaseError>
}

/**
 * Base error entry structure
 */
export interface BaseError {
  message: string
  code?: string
  details?: Record<string, unknown>
}

/**
 * Vehicle mileage specific error response
 */
export interface UpdateResponseError extends BaseErrorResponse {
  errors: Array<VehicleMileageError>
}
libs/api/domains/vehicles/src/lib/models/v3/vehicleMileageResponseError.model.ts (1)

4-14: Add JSDoc documentation for the error model.

Since this is a public API in a library, please add JSDoc documentation to describe the purpose and usage of this error model.

+/**
+ * Represents an error response for vehicle mileage updates.
+ * Used in GraphQL mutations to provide structured error information.
+ */
 @ObjectType()
 export class VehiclesMileageUpdateError {
+  /** Human-readable error message */
   @Field()
   message!: string
 
+  /** Optional error code for client-side handling */
   @Field(() => Int, { nullable: true })
   code?: number
 
+  /** Additional error details in JSON format */
   @Field(() => JSON, { nullable: true })
   error?: Record<string, unknown>
 }
libs/api/domains/vehicles/src/lib/models/v3/putVehicleMileageResponse.model.ts (1)

5-15: Add type safety and documentation to the union type.

While the implementation is correct, consider these improvements for better maintainability and type safety:

Apply this diff to add JSDoc documentation and type safety:

+/**
+ * Union type for vehicle mileage update responses.
+ * Represents either a successful update with vehicle data or an error response.
+ */
 export const VehicleMileagePutResponse = createUnionType({
   name: 'VehicleMileagePutResponse',
   types: () => [VehicleMileagePutModel, VehiclesMileageUpdateError] as const,
-  resolveType(value) {
+  resolveType(value: { permno?: string } | Record<string, unknown>) {
     if (value.permno) {
       return VehicleMileagePutModel
     }

     return VehiclesMileageUpdateError
   },
 })
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileage.graphql (1)

22-47: Consider documenting the error codes for API consumers.

The enhanced error handling with union types and structured error responses improves the API's robustness. To maximize the benefit of these improvements, consider:

  1. Documenting the possible error codes and their meanings
  2. Adding examples of error handling in the component documentation
  3. Creating shared error handling utilities for components using these mutations
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageFileDownloader.tsx (1)

Line range hint 15-32: Consider improving loading state management and error handling

The current implementation has several areas for improvement:

  1. The shared loading state affects both buttons simultaneously
  2. The error handling could be more specific to different failure scenarios
  3. The example data is hardcoded

Consider implementing these improvements:

-  const [isLoading, setIsLoading] = useState(false)
+  const [loadingStates, setLoadingStates] = useState<Record<'csv' | 'xlsx', boolean>>({
+    csv: false,
+    xlsx: false
+  })

-  const downloadExampleFile = async (type: 'csv' | 'xlsx') => {
-    setIsLoading(true)
+  const downloadMileageTemplate = async (type: 'csv' | 'xlsx') => {
+    setLoadingStates(prev => ({ ...prev, [type]: true }))
     try {
       downloadFile(
         `magnskraning_kilometrastodu_example`,
         ['bilnumer', 'kilometrastada'],
-        [
-          ['ABC001', 10000],
-          ['DEF002', 99999],
-        ],
+        MILEAGE_EXAMPLES,
         type,
       )
     } catch (error) {
-      onError(error)
+      onError(
+        error instanceof Error 
+          ? `Failed to download ${type.toUpperCase()} template: ${error.message}`
+          : 'Unknown error occurred while downloading template'
+      )
     } finally {
-      setIsLoading(false)
+      setLoadingStates(prev => ({ ...prev, [type]: false }))
     }
   }

Add at the top of the file:

const MILEAGE_EXAMPLES = [
  ['ABC001', 10000],
  ['DEF002', 99999],
] as const;
libs/api/domains/vehicles/src/lib/resolvers/mileage.resolver.ts (1)

38-40: Consider aligning version naming across models and methods.

There's a version mismatch between V2 method names and V3 model imports. This inconsistency could lead to confusion in the future. Consider either:

  1. Moving models to v2/ directory to match method versions, or
  2. Updating method names to V3 to match model versions
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (1)

51-53: Consider improving error message formatting.

While the function signature and type handling look good, the error message concatenation could be improved for better maintainability.

Consider this improvement:

- `${formatMessage(vehicleMessage.errorWhileProcessing) + error.message}
-         `,
+ formatMessage(vehicleMessage.errorWhileProcessing, { error: error.message })

This assumes adding an interpolation parameter to the message definition.

libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx (1)

Line range hint 1-168: Enhance TypeScript type definitions.

To better align with the coding guidelines for library components:

  1. Consider extracting and exporting the PostStatus type
  2. Add explicit return type for the component
+type PostStatus = 'initial' | 'posting' | 'post-success' | 'put-success' | 'error';

 interface Props {
   vehicle: VehicleType
 }
-export const VehicleBulkMileageRow = ({ vehicle }: Props) => {
+export const VehicleBulkMileageRow = ({ vehicle }: Props): JSX.Element => {
   const [postStatus, setPostStatus] = useState<PostStatus>('initial')
   // ... rest of the component
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 8ec5136 and 6a2145f.

📒 Files selected for processing (12)
  • libs/api/domains/vehicles/src/lib/dto/updateResponseError.dto.ts (1 hunks)
  • libs/api/domains/vehicles/src/lib/models/v3/postVehicleMileageResponse.model.ts (1 hunks)
  • libs/api/domains/vehicles/src/lib/models/v3/putVehicleMileageResponse.model.ts (1 hunks)
  • libs/api/domains/vehicles/src/lib/models/v3/vehicleMileageResponseError.model.ts (1 hunks)
  • libs/api/domains/vehicles/src/lib/resolvers/mileage.resolver.ts (2 hunks)
  • libs/api/domains/vehicles/src/lib/services/vehicles.service.ts (3 hunks)
  • libs/service-portal/assets/src/lib/messages.ts (2 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileage.graphql (1 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageFileDownloader.tsx (3 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx (2 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (5 hunks)
  • libs/service-portal/assets/src/utils/parseFileToMileage.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
libs/api/domains/vehicles/src/lib/dto/updateResponseError.dto.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/api/domains/vehicles/src/lib/models/v3/postVehicleMileageResponse.model.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/api/domains/vehicles/src/lib/models/v3/putVehicleMileageResponse.model.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/api/domains/vehicles/src/lib/models/v3/vehicleMileageResponseError.model.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/api/domains/vehicles/src/lib/resolvers/mileage.resolver.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/api/domains/vehicles/src/lib/services/vehicles.service.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/lib/messages.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileage.graphql (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageFileDownloader.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/utils/parseFileToMileage.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
🪛 Biome
libs/api/domains/vehicles/src/lib/models/v3/vehicleMileageResponseError.model.ts

[error] 2-2: Do not shadow the global "JSON" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🔇 Additional comments (16)
libs/api/domains/vehicles/src/lib/dto/updateResponseError.dto.ts (1)

5-11: ⚠️ Potential issue

Improve property naming for clarity and consistency.

Several property names could be more descriptive and consistent:

  • 'Errors' should be camelCase as per TypeScript conventions
  • 'warnSever' appears to be a typo of 'warnSeverity'
  • 'errorMess' should be 'errorMessage'
  • 'permno' should be 'permitNumber'

Let's verify if these property names are used elsewhere in the codebase:

libs/api/domains/vehicles/src/lib/models/v3/vehicleMileageResponseError.model.ts (1)

1-14: Verify error model integration with vehicle mileage mutations.

The implementation looks good and follows NestJS/GraphQL conventions. However, let's verify its integration with the mileage update mutations.

✅ Verification successful

Let me gather more information about how this error model is integrated with the mutations by examining the resolver and response models.


Error model is properly integrated with vehicle mileage mutations

The verification shows that the VehiclesMileageUpdateError model is correctly integrated:

  • It's properly used in both POST and PUT response union types alongside success models
  • The resolver correctly handles error instances in mutation responses
  • The union types have proper type resolution logic based on the permno field
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of VehiclesMileageUpdateError in mutations
# Expected: Should find references in mutation return types and error handling

# Search for references to this error type in mutation definitions
echo "Searching for mutation definitions using this error type..."
ast-grep --pattern 'createUnionType({
  $$$
  types: () => [$$$VehiclesMileageUpdateError$$$]
  $$$
})'

# Search for error handling implementations
echo "Searching for error handling implementations..."
rg -l "VehiclesMileageUpdateError" --type ts

Length of output: 835


Script:

#!/bin/bash
# Check the mileage resolver implementation
echo "Checking mileage resolver implementation..."
rg -A 10 "VehiclesMileageUpdateError" libs/api/domains/vehicles/src/lib/resolvers/mileage.resolver.ts

# Check response models
echo -e "\nChecking POST response model..."
cat libs/api/domains/vehicles/src/lib/models/v3/postVehicleMileageResponse.model.ts

echo -e "\nChecking PUT response model..."
cat libs/api/domains/vehicles/src/lib/models/v3/putVehicleMileageResponse.model.ts

Length of output: 2532

🧰 Tools
🪛 Biome

[error] 2-2: Do not shadow the global "JSON" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

libs/api/domains/vehicles/src/lib/models/v3/postVehicleMileageResponse.model.ts (2)

1-3: LGTM! Clean and necessary imports.

The imports are well-organized and properly scoped for the functionality needed.


5-15: Verify the discriminator field usage across related types.

The resolveType function uses 'permno' as a discriminator. Let's verify this is consistently used across related types.

✅ Verification successful

Let me try different commands to verify the discriminator field usage.


Let me search for the VehicleMileageDetail type definition to verify the discriminator field.


The discriminator field usage is correctly implemented

The verification confirms that:

  1. VehicleMileageDetail has permno as an optional string field
  2. VehiclesMileageUpdateError does not have permno field, but has message, code, and error fields
  3. The union type's resolveType function correctly uses permno presence to discriminate between these types

This implementation ensures type-safe discrimination between successful mileage updates and error responses.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent usage of 'permno' field in related types
# Expected: Find all related type definitions to ensure 'permno' is properly defined

# Search for type definitions containing 'permno'
rg -t typescript "interface.*VehicleMileageDetail|type.*VehicleMileageDetail" -A 5

# Search for other potential discriminator fields in error types
rg -t typescript "interface.*Error|type.*Error.*vehicles.*mileage" -A 5

Length of output: 228


Script:

#!/bin/bash
# Search for VehicleMileageDetail type definition and its properties
rg "VehicleMileageDetail" -A 5

# Search for VehiclesMileageUpdateError type definition
rg "VehiclesMileageUpdateError" -A 5

# Search for any other files using permno as discriminator
rg "permno.*\?" -A 2

Length of output: 51973


Script:

#!/bin/bash
# Search for VehicleMileageDetail class/type definition
ast-grep --pattern 'class VehicleMileageDetail {
  $$$
}'

# Search for VehiclesMileageUpdateError class/type definition
ast-grep --pattern 'class VehiclesMileageUpdateError {
  $$$
}'

Length of output: 3202

libs/api/domains/vehicles/src/lib/models/v3/putVehicleMileageResponse.model.ts (2)

1-3: LGTM! Clean and focused imports.

The imports are well-organized and properly scoped for the union type implementation.


8-14: Verify the discriminator logic for type resolution.

The current implementation assumes that the presence of permno is sufficient to determine a successful response. Ensure this is a reliable discriminator across all possible response scenarios.

Let's check how these types are used in the codebase:

✅ Verification successful

Let me analyze the code further to verify the discriminator logic.


Let me check one more thing to understand the complete type resolution flow.


The discriminator logic using permno is reliable and consistent

The verification shows that:

  1. Both success models (VehicleMileagePutModel and VehicleMileageDetail) have permno as an optional field
  2. The error model (VehiclesMileageUpdateError) has no permno field
  3. This pattern is consistently used across both PUT and POST responses
  4. The discriminator logic aligns with the GraphQL union type resolution pattern where presence of a field determines the concrete type
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the structure of VehicleMileagePutModel and usage of permno

# Check the structure of VehicleMileagePutModel
ast-grep --pattern 'class VehicleMileagePutModel {
  $$$
}'

# Check for other uses of permno in vehicle-related responses
rg -g '*.ts' -g '*.graphql' 'permno' 

Length of output: 57047


Script:

#!/bin/bash
# Check the structure of VehiclesMileageUpdateError and its usage
ast-grep --pattern 'class VehiclesMileageUpdateError {
  $$$
}'

# Check for other response models in the same directory
fd ".*Response.model.ts" libs/api/domains/vehicles/src/lib/models/v3/

Length of output: 1493


Script:

#!/bin/bash
# Check the implementation of postVehicleMileageResponse for comparison
cat libs/api/domains/vehicles/src/lib/models/v3/postVehicleMileageResponse.model.ts

# Check the VehicleMileagePutModel implementation
cat libs/api/domains/vehicles/src/lib/models/getVehicleMileage.model.ts

Length of output: 2753

libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileage.graphql (2)

22-33: Well-structured mutation with improved error handling!

The updated mutation properly handles both success and error cases through union types, making it more robust and maintainable.


38-47: Consistent error handling pattern across mutations!

The put mutation maintains symmetry with the post mutation's error handling approach, which is a good practice for API consistency.

libs/api/domains/vehicles/src/lib/resolvers/mileage.resolver.ts (2)

105-151: Well-structured implementation with proper error handling.

The V2 mutations are well-implemented with:

  • Type-safe error handling
  • Consistent patterns between post and put operations
  • Proper separation of concerns
  • Reusable structure following the coding guidelines

The implementation provides a solid foundation for the XLSX upload support.


105-126: 🛠️ Refactor suggestion

Add input validation for XLSX file type.

Since this PR adds XLSX support, consider adding validation for the file type in the input. This could prevent invalid file uploads early in the request lifecycle.

Consider adding file type validation in the input DTO:

@IsIn(['xlsx', 'xls', 'csv'])
fileType: string;

Add JSDoc comments for the new V2 mutation.

Consider adding documentation to explain:

  • The difference between V1 and V2 endpoints
  • The new XLSX support feature
  • The error handling capabilities
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (2)

9-9: LGTM: Import changes align with XLSX support addition.

The imports are properly structured and follow the libs architecture guidelines for reusability.

Also applies to: 24-24


182-182: Verify file extension whitelist consistency.

The accept prop includes .xlsx, but we should verify it matches the fileExtensionWhitelist definitions.

✅ Verification successful

Let me try a different search pattern to find the file extension whitelist configuration.


Let me try searching without specifying the file type since TypeScript isn't recognized.


Based on the search results, I can now provide a final response since I found both the fileExtensionWhitelist definition and its usage in the codebase.

File extension whitelist is consistent with the accept prop

The accept prop ['.csv', '.xlsx'] in VehicleBulkMileageUpload.tsx is consistent with the fileExtensionWhitelist defined in libs/island-ui/core/types.ts:

export const fileExtensionWhitelist = {
  '.csv': 'text/csv',
  '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  // ...
}

The code also properly validates the uploaded file's type against these whitelisted extensions:

file.type === fileExtensionWhitelist['.csv']
  ? 'csv'
  : file.type === fileExtensionWhitelist['.xlsx']
  ? 'xlsx'
  : undefined
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for fileExtensionWhitelist definition to ensure consistency
rg -A 5 "fileExtensionWhitelist.*=.*{" --type typescript

Length of output: 178


Script:

#!/bin/bash
# Search for fileExtensionWhitelist with a simpler pattern
rg "fileExtensionWhitelist" --type typescript

# Also search for any file extension validation or constants
rg "allowedFileExtensions|ALLOWED_EXTENSIONS|FILE_EXTENSIONS" --type typescript

# Search for any validation related to xlsx or csv files
rg "\.(xlsx|csv)" --type typescript -A 2

Length of output: 275


Script:

#!/bin/bash
# Search for fileExtensionWhitelist
rg "fileExtensionWhitelist"

# Search for any file extension validation or constants
rg "allowedFileExtensions|ALLOWED_EXTENSIONS|FILE_EXTENSIONS"

# Search for any validation related to xlsx or csv files
rg "\.(xlsx|csv)" -A 2

# Also search specifically in the VehicleBulkMileageUpload directory
fd . libs/service-portal/assets/src/screens/VehicleBulkMileageUpload --exec cat {}

Length of output: 29098

libs/service-portal/assets/src/lib/messages.ts (2)

975-978: LGTM: Clear and informative error message.

The new error message clearly communicates the accepted file types (.csv and .xlsx) to users.


1033-1033: LGTM: Consistent update to accepted file types.

The message has been correctly updated to include .xlsx as an accepted file type, maintaining consistency with the error message and PR objectives.

libs/service-portal/assets/src/utils/parseFileToMileage.ts (2)

2-2: Consider optimizing 'xlsx' import for bundle size

Importing the entire xlsx library can increase the bundle size and impact application performance.

[performance]

Consider importing only the necessary functions from xlsx or implementing dynamic imports if applicable. This aligns with effective tree-shaking and bundling practices.


14-21: Titles configuration enhances header recognition

The vehicleIndexTitle and mileageIndexTitle arrays include Icelandic titles, enhancing flexibility in recognizing headers.

Copy link

codecov bot commented Oct 24, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 36.71%. Comparing base (3c56c86) to head (eeb23cb).
Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main   #16539   +/-   ##
=======================================
  Coverage   36.71%   36.71%           
=======================================
  Files        6858     6858           
  Lines      142638   142638           
  Branches    40639    40656   +17     
=======================================
+ Hits        52365    52366    +1     
+ Misses      90273    90272    -1     
Flag Coverage Δ
air-discount-scheme-backend 54.08% <ø> (ø)
air-discount-scheme-web 0.00% <ø> (ø)
api 3.37% <ø> (ø)
api-catalogue-services 77.85% <ø> (ø)
api-domains-air-discount-scheme 36.93% <ø> (ø)
api-domains-assets 26.71% <ø> (ø)
api-domains-auth-admin 48.48% <ø> (ø)
api-domains-communications 39.91% <ø> (ø)
api-domains-criminal-record 48.00% <ø> (ø)
api-domains-driving-license 44.48% <ø> (ø)
api-domains-education 31.58% <ø> (ø)
api-domains-health-insurance 34.77% <ø> (ø)
api-domains-mortgage-certificate 34.98% <ø> (ø)
api-domains-payment-schedule 41.16% <ø> (ø)
application-api-files 56.78% <ø> (ø)
application-core 71.41% <ø> (-0.09%) ⬇️
application-system-api 41.31% <ø> (ø)
application-template-api-modules 27.77% <ø> (-0.02%) ⬇️
application-templates-accident-notification 29.24% <ø> (ø)
application-templates-car-recycling 3.12% <ø> (ø)
application-templates-criminal-record 26.30% <ø> (ø)
application-templates-driving-license 18.40% <ø> (ø)
application-templates-estate 12.25% <ø> (ø)
application-templates-example-payment 25.20% <ø> (ø)
application-templates-financial-aid 15.47% <ø> (ø)
application-templates-general-petition 23.42% <ø> (ø)
application-templates-inheritance-report 6.51% <ø> (ø)
application-templates-marriage-conditions 15.18% <ø> (ø)
application-templates-mortgage-certificate 43.55% <ø> (ø)
application-templates-parental-leave 29.94% <ø> (ø)
application-types 6.62% <ø> (ø)
application-ui-components 1.27% <ø> (ø)
application-ui-shell 21.22% <ø> (ø)
auth-admin-web 2.43% <ø> (ø)
auth-nest-tools 30.02% <ø> (ø)
auth-react 22.26% <ø> (ø)
auth-shared 75.00% <ø> (ø)
clients-charge-fjs-v2 24.11% <ø> (ø)
clients-driving-license 40.67% <ø> (ø)
clients-driving-license-book 43.80% <ø> (ø)
clients-financial-statements-inao 49.32% <ø> (ø)
clients-license-client 1.83% <ø> (ø)
clients-middlewares 73.11% <ø> (ø)
clients-regulations 42.80% <ø> (ø)
clients-rsk-company-registry 29.76% <ø> (ø)
clients-rsk-personal-tax-return 38.00% <ø> (ø)
clients-smartsolutions 12.77% <ø> (ø)
clients-syslumenn 49.49% <ø> (ø)
clients-zendesk 54.61% <ø> (ø)
cms 0.42% <ø> (ø)
cms-translations 39.04% <ø> (ø)
content-search-index-manager 95.65% <ø> (ø)
content-search-toolkit 8.16% <ø> (ø)
contentful-apps 5.44% <ø> (ø)
dokobit-signing 63.38% <ø> (ø)
download-service 44.22% <ø> (ø)
email-service 61.13% <ø> (ø)
feature-flags 91.11% <ø> (ø)
file-storage 53.71% <ø> (ø)
financial-aid-backend 51.24% <ø> (ø)
financial-aid-shared 17.81% <ø> (ø)
icelandic-names-registry-backend 53.97% <ø> (ø)
infra-nest-server 48.17% <ø> (ø)
infra-tracing 43.24% <ø> (ø)
island-ui-core 28.86% <ø> (ø)
judicial-system-api 19.52% <ø> (ø)
judicial-system-audit-trail 69.43% <ø> (ø)
judicial-system-backend 55.32% <ø> (ø)
judicial-system-formatters 79.91% <ø> (ø)
judicial-system-message 67.37% <ø> (ø)
judicial-system-message-handler 48.53% <ø> (ø)
judicial-system-scheduler 70.62% <ø> (ø)
judicial-system-types 44.13% <ø> (ø)
judicial-system-web 27.65% <ø> (ø)
license-api 42.53% <ø> (+0.07%) ⬆️
localization 10.15% <ø> (ø)
logging 48.43% <ø> (ø)
message-queue 68.58% <ø> (ø)
nest-audit 68.20% <ø> (ø)
nest-aws 61.15% <ø> (ø)
nest-config 78.44% <ø> (ø)
nest-core 43.54% <ø> (ø)
nest-feature-flags 51.52% <ø> (ø)
nest-problem 45.85% <ø> (ø)
nest-sequelize 94.44% <ø> (ø)
nest-swagger 51.71% <ø> (ø)
nova-sms 62.74% <ø> (ø)
portals-admin-regulations-admin 1.84% <ø> (ø)
portals-core 16.01% <ø> (ø)
reference-backend 49.79% <ø> (ø)
regulations 16.78% <ø> (ø)
residence-history 85.00% <ø> (ø)
services-auth-admin-api 51.89% <ø> (ø)
services-auth-delegation-api 57.52% <ø> (+0.06%) ⬆️
services-auth-ids-api 51.45% <ø> (+<0.01%) ⬆️
services-auth-personal-representative 45.07% <ø> (+0.02%) ⬆️
services-auth-personal-representative-public 41.21% <ø> (-0.05%) ⬇️
services-auth-public-api 48.95% <ø> (ø)
services-documents 60.58% <ø> (ø)
services-endorsements-api 53.59% <ø> (ø)
services-sessions 65.39% <ø> (+0.04%) ⬆️
services-university-gateway 49.47% <ø> (ø)
services-user-notification 46.90% <ø> (-0.01%) ⬇️
services-user-profile 61.84% <ø> (+0.07%) ⬆️
shared-components 27.51% <ø> (ø)
shared-form-fields 31.22% <ø> (ø)
shared-mocking 64.62% <ø> (ø)
shared-pii 92.85% <ø> (ø)
shared-problem 87.50% <ø> (ø)
shared-utils 27.69% <ø> (ø)
skilavottord-ws 24.18% <ø> (ø)
testing-e2e 66.66% <ø> (ø)
web 1.80% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

see 1 file with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3c56c86...eeb23cb. Read the comment docs.

@datadog-island-is
Copy link

datadog-island-is bot commented Oct 24, 2024

Datadog Report

Branch report: fix/bulk-milegae-update
Commit report: c1c28e5
Test service: api

✅ 0 Failed, 4 Passed, 0 Skipped, 2.68s Total Time
➡️ Test Sessions change in coverage: 1 no change

Copy link
Contributor

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

🧹 Outside diff range and nitpick comments (6)
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageFileDownloader.tsx (2)

Line range hint 15-32: Enhance example data to be more representative

While the function correctly implements file type support, consider making the example data more realistic and helpful:

 downloadFile(
   `magnskraning_kilometrastodu_example`,
   ['bilnumer', 'kilometrastada'],
   [
-    ['ABC001', 10000],
-    ['DEF002', 99999],
+    ['AB A12', 10000],  // Common format for Icelandic plates
+    ['CD B34', 25000],
+    ['EF C56', 99999],  // Include more examples
   ],
   type,
 )

Line range hint 27-29: Enhance error handling with specific error messages

Consider providing more specific error messages based on the error type to align with the PR's objective of improving error messaging.

     } catch (error) {
-      onError(error)
+      const errorMessage = error instanceof Error 
+        ? error.message 
+        : formatMessage(vehicleMessage.genericDownloadError)
+      onError(errorMessage)
     } finally {
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (2)

51-53: Consider enhancing error message specificity.

While the error handling is good, consider providing more specific error messages for different scenarios (empty file, parsing error, invalid format) to help users better understand and fix issues.

Example enhancement:

 if (!records.length) {
-  setUploadErrorMessage(formatMessage(vehicleMessage.uploadFailed))
+  setUploadErrorMessage(formatMessage(vehicleMessage.emptyFileError))
   return
 }

Line range hint 143-154: Remove duplicate AlertMessage for upload failure.

There are two identical AlertMessage components for the upload failure case. Consider removing the duplicate.

-        {data?.vehicleBulkMileagePost?.errorMessage && !loading && !error && (
-          <AlertMessage
-            type="warning"
-            title={formatMessage(vehicleMessage.uploadFailed)}
-            message={data.vehicleBulkMileagePost.errorMessage}
-          />
-        )}
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx (1)

41-41: Consider enhancing component reusability.

While the component follows TypeScript practices, consider:

  1. Moving state management logic into a custom hook (e.g., useVehicleMileage)
  2. Extracting mutation-related logic into a separate service
    This would improve reusability across different NextJS apps and make the component more maintainable.

Also applies to: 168-171

libs/service-portal/assets/src/utils/parseFileToMileage.ts (1)

73-74: Remove unnecessary initialization of parsedLines

The variable parsedLines is initialized but immediately reassigned with the parsed result. The initial assignment is unnecessary and can be removed to clean up the code.

Apply this diff to remove the unnecessary initialization:

- let parsedLines: Array<Array<string>> = [[]]
  let accumulatedChunk = ''
  let done = false

  while (!done) {
    const res = await reader.read()
    done = res.done
    if (!done) {
      accumulatedChunk += decoder.decode(res.value)
    }
  }

- parsedLines = parseCsvString(accumulatedChunk)
+ const parsedLines = parseCsvString(accumulatedChunk)
  return parsedLines

Also applies to: 86-86

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6a2145f and 6d890ca.

📒 Files selected for processing (10)
  • libs/api/domains/vehicles/src/lib/models/v3/postVehicleMileageResponse.model.ts (1 hunks)
  • libs/api/domains/vehicles/src/lib/models/v3/putVehicleMileageResponse.model.ts (1 hunks)
  • libs/api/domains/vehicles/src/lib/models/v3/vehicleMileageResponseError.model.ts (1 hunks)
  • libs/api/domains/vehicles/src/lib/resolvers/mileage.resolver.ts (2 hunks)
  • libs/api/domains/vehicles/src/lib/services/vehicles.service.ts (3 hunks)
  • libs/service-portal/assets/src/lib/messages.ts (3 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageFileDownloader.tsx (3 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx (3 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (5 hunks)
  • libs/service-portal/assets/src/utils/parseFileToMileage.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • libs/api/domains/vehicles/src/lib/models/v3/postVehicleMileageResponse.model.ts
  • libs/api/domains/vehicles/src/lib/models/v3/putVehicleMileageResponse.model.ts
  • libs/api/domains/vehicles/src/lib/models/v3/vehicleMileageResponseError.model.ts
  • libs/api/domains/vehicles/src/lib/resolvers/mileage.resolver.ts
🧰 Additional context used
📓 Path-based instructions (6)
libs/api/domains/vehicles/src/lib/services/vehicles.service.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/lib/messages.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageFileDownloader.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/utils/parseFileToMileage.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
🪛 Biome
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageFileDownloader.tsx

[error] 37-45: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

🔇 Additional comments (12)
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageFileDownloader.tsx (1)

1-1: Tree-shaking optimization comment already exists

libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (2)

9-9: LGTM: Import changes align with XLSX support.

The new imports support the enhanced file type handling capabilities.

Also applies to: 24-24


184-184: LGTM: File type support properly updated.

The accept prop correctly reflects the supported file types.

libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx (2)

28-34: LGTM: Well-defined type for mutation status.

The MutationStatus type definition improves type safety and maintainability by clearly defining all possible mutation states.


168-171: Previous review comment about useEffect dependencies is still applicable.

libs/api/domains/vehicles/src/lib/services/vehicles.service.ts (3)

14-14: LGTM: New imports are well-organized and properly typed

The imports appropriately support the new error handling functionality and follow TypeScript best practices.

Also applies to: 22-22, 38-41, 44-44, 52-53


473-514: Verify the correctness of status code handling

The condition res.raw.status === 200 is used to determine if a mileage reading already exists, suggesting that a PUT request should be used instead. Typically, a 200 OK status indicates a successful operation. Please confirm whether a 200 status correctly signifies that the mileage reading already exists, or if a different status code (such as 409 Conflict) should be checked.

#!/bin/bash
# Search for similar status code handling patterns in the codebase
rg -A 2 "raw\.status === 200" --type ts

516-547: Refactor duplicated code in mileage reading methods

The postMileageReadingV2 and putMileageReadingV2 methods contain similar logic for authorization checks and error handling. To improve maintainability and reduce duplication, consider refactoring shared logic into a helper method.

Example refactoring:

private async handleMileageReadingRequest<T>(
  auth: User,
  input: RootPostRequest['postMileageReadingModel'] | RootPutRequest['putMileageReadingModel'],
  operation: (auth: User, input: any) => Promise<T>,
): Promise<T | VehiclesMileageUpdateError | null> {
  if (!input) return null;

  const isAllowed = await this.isAllowedMileageRegistration(auth, input.permno);
  if (!isAllowed) {
    this.logger.error(UNAUTHORIZED_OWNERSHIP_LOG, {
      category: LOG_CATEGORY,
      error: 'Mileage reading operation failed',
    });
    throw new ForbiddenException(UNAUTHORIZED_OWNERSHIP_LOG);
  }

  try {
    const result = await operation(auth, input);
    return result;
  } catch (e) {
    if (e instanceof FetchError && (e.status === 400 || e.status === 429)) {
      const errorBody = e.body as UpdateResponseError;
      return {
        code: e.status,
        message: errorBody.Errors?.[0]?.errorMess || 'Unknown error',
      };
    } else throw e;
  }
}

Then update the methods:

async postMileageReadingV2(
  auth: User,
  input: RootPostRequest['postMileageReadingModel'],
): Promise<PostMileageReadingModel | VehiclesMileageUpdateError | null> {
  return this.handleMileageReadingRequest(auth, input, async (auth, input) => {
    const res = await this.getMileageWithAuth(auth).rootPostRaw({ postMileageReadingModel: input });
    if (res.raw.status === 200) {
      this.logger.info('Tried to post already existing mileage reading. Should use PUT');
      return null;
    }
    return res.value();
  });
}

async putMileageReadingV2(
  auth: User,
  input: RootPutRequest['putMileageReadingModel'],
): Promise<MileageReadingDto | VehiclesMileageUpdateError | null> {
  return this.handleMileageReadingRequest(auth, input, (auth, input) =>
    this.getMileageWithAuth(auth).rootPut({ putMileageReadingModel: input }),
  );
}
libs/service-portal/assets/src/lib/messages.ts (3)

975-978: LGTM: Error message for wrong file type.

The message definition follows the established pattern and clearly communicates the supported file types.


1033-1033: LGTM: Updated accepted file types message.

The message is correctly updated to include both .csv and .xlsx formats, aligning with the new feature support.


1071-1071: LGTM: Template download message with dynamic argument.

The message correctly uses the {arg} placeholder for dynamic template type insertion, following the established pattern for parameterized messages.

libs/service-portal/assets/src/utils/parseFileToMileage.ts (1)

1-120: Overall code quality is good

The implementation effectively handles parsing of both CSV and XLSX files, utilizing TypeScript features and maintaining consistency with coding guidelines. The code is well-structured and aligns with best practices for reusability and type safety.

Copy link
Contributor

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

🧹 Outside diff range and nitpick comments (2)
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageFileDownloader.tsx (1)

30-38: Remove duplicate title prop

The title is specified twice through menuLabel and title props. Consider removing one of them as they serve the same purpose.

 <DropdownMenu
   icon="ellipsisHorizontal"
   menuLabel={formatMessage(vehicleMessage.downloadTemplate)}
   items={(['csv', 'xlsx'] as const).map((type) => ({
     title: `.${type}`,
     onClick: () => downloadExampleFile(type),
   }))}
-  title={formatMessage(vehicleMessage.downloadTemplate)}
 />
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (1)

Line range hint 56-82: Consider enhancing error handling structure.

While the error handling is comprehensive, it could be more maintainable with a clearer structure.

Consider this refactoring:

 const postMileage = async (file: File, type: 'xlsx' | 'csv') => {
   try {
     const records = await parseFileToMileageRecord(file, type)
-    if (!records.length) {
-      setUploadErrorMessage(formatMessage(vehicleMessage.uploadFailed))
-      return
-    }
-    if (typeof records === 'string') {
-      setUploadErrorMessage(records)
-      return
-    }
+    if (!Array.isArray(records) || !records.length) {
+      throw new Error(
+        typeof records === 'string' 
+          ? records 
+          : formatMessage(vehicleMessage.uploadFailed)
+      )
+    }
     vehicleBulkMileagePostMutation({
       variables: {
         input: {
           mileageData: records.map((r) => ({
             mileageNumber: r.mileage,
             vehicleId: r.vehicleId,
           })),
           originCode: 'ISLAND.IS',
         },
       },
     })
   } catch (error) {
     setUploadErrorMessage(
-      `${formatMessage(vehicleMessage.errorWhileProcessing) + error.message}
-        `,
+      formatMessage(vehicleMessage.errorWhileProcessing) + error.message.trim()
     )
   }
 }

This refactoring:

  • Simplifies the validation logic
  • Unifies error handling in the catch block
  • Removes string template literal whitespace
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6d890ca and d529ecd.

📒 Files selected for processing (4)
  • libs/service-portal/assets/src/lib/messages.ts (2 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageFileDownloader.tsx (1 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (5 hunks)
  • libs/service-portal/assets/src/utils/parseFileToMileage.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • libs/service-portal/assets/src/lib/messages.ts
🧰 Additional context used
📓 Path-based instructions (3)
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageFileDownloader.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/utils/parseFileToMileage.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
📓 Learnings (1)
libs/service-portal/assets/src/utils/parseFileToMileage.ts (1)
Learnt from: thorkellmani
PR: island-is/island.is#16539
File: libs/service-portal/assets/src/utils/parseFileToMileage.ts:103-117
Timestamp: 2024-10-25T16:01:02.482Z
Learning: In the `parseFileToMileage.ts` file, prefer using `csv-parse` over `papaparse` for CSV parsing in the Service Portal Assets.
🪛 Biome
libs/service-portal/assets/src/utils/parseFileToMileage.ts

[error] 109-109: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

🔇 Additional comments (5)
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageFileDownloader.tsx (1)

30-38: Well-implemented dropdown for file type selection!

The DropdownMenu implementation is clean, type-safe, and provides a good user experience for selecting file types. The use of const assertion with as const ensures type safety for the file type options.

libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (3)

9-9: LGTM! Well-structured type definitions and imports.

The implementation follows best practices by:

  • Using TypeScript's const assertions for type safety
  • Defining the extension mapping outside the component for better performance
  • Following the modular import structure

Also applies to: 24-29


Line range hint 133-182: Verify error message handling from the service.

The PR objective mentions parsing error messages from the service. Let's verify the implementation of error message display.

Let's check the error message structure:

#!/bin/bash
# Description: Verify error message structure in GraphQL schema
# Expected: Find the error message field definition in the response type

ast-grep --pattern 'type VehicleBulkMileagePost {
  $$$
  errorMessage: String
  $$$
}'

185-185: Verify file extension whitelist alignment.

The accept prop includes .xlsx, which should align with the fileExtensionWhitelist imported from core.

Let's verify the whitelist configuration:

✅ Verification successful

File extension whitelist is properly configured

The code shows that the .xlsx extension is correctly defined in both the accept prop and the fileExtensionWhitelist mapping:

[fileExtensionWhitelist['.xlsx']]: 'xlsx'

The accept prop and whitelist are properly aligned, ensuring consistent file type validation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify file extension whitelist configuration
# Expected: Find the whitelist definition that includes .xlsx

rg -A 5 "fileExtensionWhitelist.*=.*{" --type typescript

Length of output: 89


Script:

#!/bin/bash
# Let's try different search patterns to find the whitelist configuration
rg -i "whitelist.*xlsx" --type typescript

# Also search for file extension related constants or configurations
rg -i "allowedExtensions|fileExtensions|acceptedExtensions|extensions.*xlsx" --type typescript

# Search specifically in core or config related files
fd -e ts -e tsx config
fd -e ts -e tsx core | xargs rg -l -i "extension"

Length of output: 40348


Script:

#!/bin/bash
# Let's search for file extension related code in the service-portal core and assets
rg -A 5 "fileExtension|accept.*xlsx" libs/service-portal/core libs/service-portal/assets

# Also search for any file upload related components or utilities
ast-grep --pattern 'interface $_ {
  $$$
  accept?: $_
  $$$
}'

Length of output: 8770

libs/service-portal/assets/src/utils/parseFileToMileage.ts (1)

1-108: Code adheres to coding guidelines

The code is well-structured, utilizes TypeScript effectively for defining types, and follows best practices for reusability and bundling in a library context.

Also applies to: 110-125

Copy link
Contributor

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

🧹 Outside diff range and nitpick comments (3)
libs/service-portal/assets/src/utils/parseFileToMileage.ts (2)

19-63: LGTM! Consider adding input validation.

The function handles both formats well and includes thorough header validation. Consider adding validation for the input file size and empty files.

Add size validation before processing:

if (file.size === 0) {
  throw new Error('File is empty');
}
if (file.size > MAX_FILE_SIZE) {
  throw new Error('File size exceeds limit');
}

83-101: LGTM! Consider adding sheet selection option.

The XLSX parsing implementation is robust with proper error handling. Consider adding an optional parameter for sheet selection instead of always using the first sheet.

interface XlsxOptions {
  sheetIndex?: number;
}

const parseXlsx = async (file: File, options: XlsxOptions = {}) => {
  const sheetIndex = options.sheetIndex ?? 0;
  // ... use sheetIndex instead of 0
}
libs/service-portal/assets/src/screens/VehicleBulkMileageJobDetail/VehicleBulkMileageJobDetail.tsx (1)

232-256: LGTM! The conditional rendering change improves code clarity.

The ternary operator implementation for conditional rendering is more explicit and aligns with React best practices. The code effectively displays error messages which aligns with the PR objective of showing more detailed error information.

Consider extracting the table row rendering logic into a separate component for better reusability:

type VehicleRowProps = {
  vehicleId: string
  returnCode: string
  mileage: number
  errors?: Array<{ message: string }>
}

const VehicleRow: React.FC<VehicleRowProps> = ({ vehicleId, returnCode, mileage, errors = [] }) => (
  <T.Row>
    <T.Data>
      <Box display="flex" justifyContent="spaceBetween">
        <Icon
          icon={returnCode !== 'E' ? 'checkmark' : 'warning'}
          color={returnCode !== 'E' ? 'mint400' : 'red400'}
        />
        {vehicleId}
      </Box>
    </T.Data>
    <T.Data>{displayWithUnit(mileage, 'km', true)}</T.Data>
    <T.Data>{errors.map((e) => e.message).join(', ')}</T.Data>
  </T.Row>
)
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d529ecd and acbcc8e.

📒 Files selected for processing (2)
  • libs/service-portal/assets/src/screens/VehicleBulkMileageJobDetail/VehicleBulkMileageJobDetail.tsx (1 hunks)
  • libs/service-portal/assets/src/utils/parseFileToMileage.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
libs/service-portal/assets/src/screens/VehicleBulkMileageJobDetail/VehicleBulkMileageJobDetail.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/utils/parseFileToMileage.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
📓 Learnings (1)
libs/service-portal/assets/src/utils/parseFileToMileage.ts (1)
Learnt from: thorkellmani
PR: island-is/island.is#16539
File: libs/service-portal/assets/src/utils/parseFileToMileage.ts:103-117
Timestamp: 2024-10-25T16:01:02.482Z
Learning: In the `parseFileToMileage.ts` file, prefer using `csv-parse` over `papaparse` for CSV parsing in the Service Portal Assets.
🪛 Biome
libs/service-portal/assets/src/utils/parseFileToMileage.ts

[error] 115-115: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

🔇 Additional comments (3)
libs/service-portal/assets/src/utils/parseFileToMileage.ts (3)

5-8: LGTM! Well-defined TypeScript interface.

The MileageRecord interface is well-structured and follows TypeScript best practices, making it reusable across different NextJS apps.


65-81: LGTM! Browser-compatible implementation.

The CSV parsing implementation correctly uses TextDecoder and handles streaming appropriately.


115-117: ⚠️ Potential issue

Improve readability by separating assignment.

The assignment within the while condition can be made more readable.

- while ((record = parser.read()) !== null) {
-   records.push(record)
- }
+ record = parser.read()
+ while (record !== null) {
+   records.push(record)
+   record = parser.read()
+ }

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome

[error] 115-115: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

Copy link
Contributor

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

🧹 Outside diff range and nitpick comments (1)
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (1)

Line range hint 56-77: Consider improving error handling and separation of concerns.

The postMileage function currently handles both file parsing and data submission. Consider:

  1. Using TypeScript discriminated unions for better error handling
  2. Separating the parsing and submission logic into distinct functions
type ParseResult = 
  | { success: true; records: MileageRecord[] }
  | { success: false; error: string };

const parseFile = async (file: File, type: 'xlsx' | 'csv'): Promise<ParseResult> => {
  try {
    const records = await parseFileToMileageRecord(file, type);
    if (!records.length) {
      return { success: false, error: formatMessage(vehicleMessage.uploadFailed) };
    }
    if (typeof records === 'string') {
      return { success: false, error: records };
    }
    return { success: true, records };
  } catch (error) {
    return { 
      success: false, 
      error: `${formatMessage(vehicleMessage.errorWhileProcessing)}${error.message}`
    };
  }
};

const postMileage = async (file: File, type: 'xlsx' | 'csv') => {
  const result = await parseFile(file, type);
  if (!result.success) {
    setUploadErrorMessage(result.error);
    return;
  }
  
  vehicleBulkMileagePostMutation({
    variables: {
      input: {
        mileageData: result.records.map((r) => ({
          mileageNumber: r.mileage,
          vehicleId: r.vehicleId,
        })),
        originCode: 'ISLAND.IS',
      },
    },
  });
};
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between acbcc8e and 98f7c59.

📒 Files selected for processing (2)
  • libs/api/domains/vehicles/src/lib/services/bulkMileage.service.ts (3 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (5 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
libs/api/domains/vehicles/src/lib/services/bulkMileage.service.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
🔇 Additional comments (4)
libs/api/domains/vehicles/src/lib/services/bulkMileage.service.ts (2)

16-16: LGTM: Clean import addition for error handling.

The named import of FetchError follows TypeScript best practices and maintains tree-shaking capabilities.


Line range hint 37-72: LGTM: Robust error handling implementation.

The try-catch block with specific handling for rate limiting (429) and guid validation provides comprehensive error management while maintaining type safety.

libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (2)

24-24: LGTM! Good separation of concerns.

The file parsing logic is properly extracted into a separate utility function, making it reusable across different components and improving maintainability.


178-178: LGTM! File type support properly updated.

The InputFileUpload component's accept prop now correctly includes both CSV and XLSX formats, aligning with the PR's objective to support XLSX file uploads.

Copy link
Contributor

@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

🧹 Outside diff range and nitpick comments (1)
libs/api/domains/vehicles/src/lib/models/v3/bulkMileage/bulkMileageReadingResponse.model.ts (1)

11-13: Consider documenting error scenarios.

Since both requestId and errorMessage are optional, it would be helpful to document the scenarios when each field would be null/undefined. This helps consumers of the API understand the expected behavior.

 @Field({ nullable: true })
+ // Present when the request fails with a specific error message
 errorMessage?: string
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 98f7c59 and 340e6f8.

📒 Files selected for processing (2)
  • libs/api/domains/vehicles/src/lib/models/v3/bulkMileage/bulkMileageReadingResponse.model.ts (1 hunks)
  • libs/api/domains/vehicles/src/lib/services/bulkMileage.service.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • libs/api/domains/vehicles/src/lib/services/bulkMileage.service.ts
🧰 Additional context used
📓 Path-based instructions (1)
libs/api/domains/vehicles/src/lib/models/v3/bulkMileage/bulkMileageReadingResponse.model.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
🔇 Additional comments (1)
libs/api/domains/vehicles/src/lib/models/v3/bulkMileage/bulkMileageReadingResponse.model.ts (1)

6-10: LGTM! Type safety improvements look good.

The changes to make requestId optional both in TypeScript and GraphQL schema are consistent and align well with the error handling improvements.

Copy link
Contributor

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

🧹 Outside diff range and nitpick comments (2)
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.graphql (1)

5-5: Consider documenting error codes.

The addition of errorCode improves error handling capabilities. Consider documenting the possible error codes and their meanings in the schema or documentation to help consumers handle errors appropriately.

libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageTable.tsx (1)

Line range hint 1-57: Enhance component documentation

While the component follows TypeScript practices, it would benefit from additional documentation explaining its purpose and usage, especially given its location in the libs directory where reusability is important.

Add JSDoc comments to describe the component's purpose and props:

+/**
+ * A table component for displaying and managing vehicle mileage data in bulk.
+ * Used in the service portal for updating mileage information for multiple vehicles.
+ */
interface Props {
+  /** Array of vehicles to display in the table */
  vehicles: Array<VehicleType>
+  /** Loading state to show/hide the empty table message */
  loading: boolean
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3394333 and c041637.

📒 Files selected for processing (7)
  • libs/api/domains/vehicles/src/lib/models/v3/bulkMileage/bulkMileageReadingResponse.model.ts (1 hunks)
  • libs/api/domains/vehicles/src/lib/services/bulkMileage.service.ts (3 hunks)
  • libs/service-portal/assets/src/lib/messages.ts (3 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx (8 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageTable.tsx (1 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.graphql (1 hunks)
  • libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • libs/api/domains/vehicles/src/lib/models/v3/bulkMileage/bulkMileageReadingResponse.model.ts
  • libs/api/domains/vehicles/src/lib/services/bulkMileage.service.ts
  • libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.tsx
🧰 Additional context used
📓 Path-based instructions (4)
libs/service-portal/assets/src/lib/messages.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageTable.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.graphql (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
🔇 Additional comments (5)
libs/service-portal/assets/src/screens/VehicleBulkMileageUpload/VehicleBulkMileageUpload.graphql (1)

Line range hint 1-7: Verify error handling implementation.

Let's verify that the error code handling is consistently implemented across the codebase.

libs/service-portal/assets/src/lib/messages.ts (4)

877-880: LGTM: New validation message follows TypeScript and i18n best practices.

The message is properly typed, follows the namespace convention, and maintains consistency with other validation messages.


883-883: LGTM: Message text improvement.

The updated message is more concise while maintaining clarity.


889-893: LGTM: Rate limiting message follows best practices.

The message provides clear feedback and actionable guidance to users when they exceed the upload rate limit.


1042-1042: LGTM: File type message is consistent.

The message correctly lists both accepted file types (.csv and .xlsx).

@thorkellmani thorkellmani added the deprecated:automerge (Disabled) Merge this PR as soon as all checks pass label Oct 30, 2024
Copy link
Member

@disaerna disaerna left a comment

Choose a reason for hiding this comment

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

Approved with comments

@kodiakhq kodiakhq bot merged commit 0947e07 into main Oct 30, 2024
304 checks passed
@kodiakhq kodiakhq bot deleted the fix/bulk-milegae-update branch October 30, 2024 13:27
thorkellmani added a commit that referenced this pull request Oct 31, 2024
* fix: add xlsx

* fix: support xlsx

* feat: parse and display errors

* fix: coderabbit grilling session

* chore: prettier button

* chore: remove imports

* chore: more rabbit grilling

* chore: switch in csv-pasre

* fix: parse

* fix: handle 429

* chore: update message

* fix: use service error

* feat: fix reveiw errors

* fix: standard error handling

* fix: bunny comments

* feat: add search

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deploy-feature Deploys features to dev deprecated:automerge (Disabled) Merge this PR as soon as all checks pass
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants