Add product short id to Boilerplate's sales module (#9929)#9930
Add product short id to Boilerplate's sales module (#9929)#9930msynk merged 6 commits intobitfoundation:developfrom yasmoradi:9929
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThe pull request replaces the old GUID-based product identification with an integer-based system across the stack. In the UI, a new sortable column displaying the product “Number” has been added. Routing and controller methods have been updated to use this integer, along with changes in data mapping and URL generation. Database models and migrations now enforce uniqueness and include the new property. Additionally, localization files have been updated with new entries for “Number” and minor modifications have been made to tooling and query string handling. Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant R as Router
participant PC as ProductController
participant DB as Database
U->>R: Navigate to ProductPage with Number & Name
R->>PC: Route request with parameter Number
PC->>DB: Query product details using Number
DB-->>PC: Return product details
PC-->>R: Render Product Page with updated info
R-->>U: Display Product Information
Poem
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (11)
src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/ProductPage.razor.cs (3)
32-32: Parallelize loading carefully.Using
Task.WhenAllfor parallel calls is an efficient approach, but if any of these tasks throw exceptions, none of them complete successfully. Consider adding robust error handling or partial-failure recovery to improve resilience.
41-41: Handle null product scenarios.After invoking
productViewController.Get(Number, ...), gracefully handle the possibility of a null or not-found product. For example, show an error message or redirect ifproductremains null.
56-56: Gracefully handle empty similar products.Consider how the UI behaves if
GetSimilarreturns an empty list. Ensure there's a fallback or an appropriate message to maintain a good user experience.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/AppDbContext.cs (1)
41-54: Streamline preprocessor directives and consider consolidated conditions.Defining a sequence named “ProductNumber” for SQL Server or PostgreSQL is a solid approach for generating unique product numbers. However, the nested
#ifdirectives and provider name checks can complicate readability. Consider consolidating them or using environment-specific code paths to reduce complexity.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Migrations/20250217182038_InitialMigration.cs (2)
7-9: Document migration purpose briefly.Including a short comment summarizing this migration’s shift to integer-based product identification helps future maintainers understand context and rationale.
10-545: Evaluate seed data volume and indexing strategies.The large seed block showcases numerous products with integer-based IDs. This is helpful for testing but can slow migrations in production. Ensure relevant indexes (e.g., the unique index on
Number) are fully optimized, and consider optional or partial seeding in non-development environments.src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Products/ProductsPage.razor (1)
39-43: Consider adding search functionality for product numbers.While the new column is well-implemented with sorting capability, consider adding a search box similar to the Name and Category columns for enhanced filtering capabilities.
<BitDataGridPropertyColumn Title="@Localizer[nameof(AppStrings.Number)]" Property="p => p!.Number" Class="name-col" Sortable="true"> + <ColumnOptions> + <BitStack Horizontal> + <BitSearchBox @bind-Value="ProductNumberFilter" + AutoFocus DisableAnimation + Immediate DebounceTime="500" + Placeholder="@Localizer[(nameof(AppStrings.SearchOnNumber))]" /> + @if (isLoading) + { + <BitEllipsisLoading CustomSize="32" /> + } + </BitStack> + </ColumnOptions> </BitDataGridPropertyColumn>src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Configurations/Product/ProductConfiguration.cs (1)
25-56: Consider simplifying the product number generation logic.The current approach using
productsCountInEachForLoopand base number 9001 works but could be simplified for better maintainability.Consider using a simpler sequential numbering approach:
-const int productsCountInEachForLoop = 23; +const int baseNumber = 1001; for (int i = 1; i <= 6; i++) { builder.HasData( - new() { ..., Number = 9001 + (productsCountInEachForLoop * i) }, - new() { ..., Number = 9002 + (productsCountInEachForLoop * i) }, + new() { ..., Number = baseNumber + ((i - 1) * 100) + 1 }, + new() { ..., Number = baseNumber + ((i - 1) * 100) + 2 }, // ... rest of the products ); }This would generate more predictable numbers like 1001, 1002, 1101, 1102, etc.
src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/ProductPage.razor (1)
49-97: Consider enhancing error state handling.While the product display logic is solid, consider adding explicit error state handling for cases where the product fails to load but isn't null (e.g., partial data).
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Program.Middlewares.cs (1)
239-239: LGTM! Consider optimizing sitemap generation.The query change from
ProductDto.IdtoProductDto.Numberis correct. However, since sitemap generation is a resource-intensive operation, consider implementing additional caching strategies.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Migrations/AppDbContextModelSnapshot.cs (1)
315-1833: Seed data updated with sequential product numbers.The seed data changes look good:
- Each product has a unique Number value starting from 9024
- Product names follow a consistent pattern with numeric suffixes
- Referential integrity is maintained with valid CategoryId values
Consider optimizing the seed data volume.
The current seed data includes multiple copies of each product with only minor variations. Consider:
- Reducing the number of seed records to improve initial database creation time
- Using a more diverse set of products instead of duplicates
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (23)
src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Products/ProductsPage.razor(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/ProductPage.razor(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/ProductPage.razor.cs(4 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/.config/dotnet-tools.json(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Controllers/Products/ProductController.cs(2 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Controllers/Products/ProductViewController.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/AppDbContext.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Configurations/Product/ProductConfiguration.cs(2 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Migrations/20250109120517_InitialMigration.Designer.cs(0 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Migrations/20250109120517_InitialMigration.cs(0 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Migrations/20250217182038_InitialMigration.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Migrations/AppDbContextModelSnapshot.cs(5 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Mappers/ProductsMapper.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Models/Products/Product.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/.config/dotnet-tools.json(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Program.Middlewares.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Controllers/IAppController.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Controllers/Products/IProductViewController.cs(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Dtos/Products/ProductDto.cs(2 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.fa.resx(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.nl.resx(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.resx(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Services/AppQueryStringCollection.cs(1 hunks)
💤 Files with no reviewable changes (2)
- src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Migrations/20250109120517_InitialMigration.Designer.cs
- src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Migrations/20250109120517_InitialMigration.cs
🧰 Additional context used
🪛 Biome (1.9.4)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/.config/dotnet-tools.json
[error] 7-7: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 7-7: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 7-7: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 7-8: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/.config/dotnet-tools.json
[error] 7-7: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 7-7: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 7-7: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 7-8: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build and test
🔇 Additional comments (23)
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Services/AppQueryStringCollection.cs (1)
18-18: LGTM! Improved null safety with explicit parameter nullability.The change to make the
queryparameter nullable (string?) better reflects the method's ability to handle null input, making the contract more explicit. This aligns with C# best practices for null safety.src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Controllers/IAppController.cs (1)
16-16: LGTM! Good improvement in type safety.Making
existingQueryStringnullable is a positive change that:
- Better represents the reality that query strings can be null
- Provides clearer API contracts through nullable reference types
- Maintains backward compatibility
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/.config/dotnet-tools.json (1)
6-8: Updateddotnet-efTool Version in API ConfigurationThe version for the
dotnet-eftool under thenet9.0framework condition has been updated to"9.0.2", which aligns with the intended update. Note that some static analysis tools are reporting errors (e.g., "End of file expected" and suggestions about using an array) which appear to be false positives in this context—likely due to the use of conditional comments. If these warnings persist and affect your build or validation pipelines, consider configuring your JSON linter or preprocessor to ignore these conditional comment sections.🧰 Tools
🪛 Biome (1.9.4)
[error] 6-6: Expected a property but instead found '//#if (framework == 'net9.0')'.
Expected a property here.
(parse)
[error] 7-7: End of file expected
Use an array for a sequence of values:
[1, 2](parse)
[error] 7-7: End of file expected
Use an array for a sequence of values:
[1, 2](parse)
[error] 7-7: End of file expected
Use an array for a sequence of values:
[1, 2](parse)
[error] 7-8: End of file expected
Use an array for a sequence of values:
[1, 2](parse)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/.config/dotnet-tools.json (1)
6-8: Consistent Update ofdotnet-efVersion in Web ConfigurationSimilar to the API configuration file, the
dotnet-eftool's version under thenet9.0condition has been updated to"9.0.2". This ensures consistency across the project. The static analysis warnings (e.g., "End of file expected") are most likely false positives due to the conditional comment syntax. You may need to adjust your configuration for the JSON linter if these warnings are problematic.🧰 Tools
🪛 Biome (1.9.4)
[error] 6-6: Expected a property but instead found '//#if (framework == 'net9.0')'.
Expected a property here.
(parse)
[error] 7-7: End of file expected
Use an array for a sequence of values:
[1, 2](parse)
[error] 7-7: End of file expected
Use an array for a sequence of values:
[1, 2](parse)
[error] 7-7: End of file expected
Use an array for a sequence of values:
[1, 2](parse)
[error] 7-8: End of file expected
Use an array for a sequence of values:
[1, 2](parse)
src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/ProductPage.razor.cs (3)
12-12: Validate negative or zero values for product number.While switching from Guid to int, ensure there's handling or checks for invalid
Numbervalues (e.g., negative or zero) to avoid potential runtime issues or confusion in the UI.
34-34: Check if base.OnInitAsync should be called first.Some Blazor patterns dictate calling the base method early for framework initialization tasks. Verify whether any base logic depends on the product load sequence or concurrency behavior.
70-71: Confirm filter logic for sibling products.Filtering out the current product by
ne {Number}is correct to exclude the active product, but also ensure there's no overlap if partial matches occur. Verify that the OData filter remains safe from injection or misuse (the underlying library typically handles this, but it's worth confirming).src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Migrations/20250217182038_InitialMigration.cs (1)
547-589: Down method consistency.Dropping the newly created entities is correct. If you add or rename additional tables in the future, ensure these
DropTablecalls remain consistent to cleanly revert the schema.src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Controllers/Products/IProductViewController.cs (1)
11-18: LGTM! Consistent transition from GUID to integer-based product identification.The changes consistently update all method signatures and route attributes to use
numberinstead ofid, aligning with the PR objective.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Models/Products/Product.cs (1)
10-11: LGTM! Good use of Range validation.The
Rangevalidation ensures that product numbers are non-negative.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Mappers/ProductsMapper.cs (1)
25-29: LGTM! Good use of MapperIgnoreSource.Correctly ignoring the
Numberproperty during mapping to prevent overwriting the database-managed value.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Controllers/Products/ProductViewController.cs (1)
16-24: LGTM! Well-structured implementation with appropriate caching.The changes consistently use
numberfor product identification while maintaining proper caching and async/await patterns.Also applies to: 27-36, 38-49
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Dtos/Products/ProductDto.cs (2)
9-10: LGTM! Range validation ensures data integrity.The
[Range(0, int.MaxValue)]attribute ensures that product numbers are always non-negative.
60-60:Details
✅ Verification successful
Verify URL compatibility with existing routes.
The URL pattern has been updated to use
Numberinstead ofId. Ensure all route handlers and links throughout the application have been updated accordingly.
🏁 Script executed:
#!/bin/bash # Search for any remaining URL patterns using product Id rg -g '!*.{json,md,txt}' '/product/[^/]+/[^/]+' --multilineLength of output: 724
URL Pattern Update Verified
- Confirmed that
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Dtos/Products/ProductDto.csnow generates URLs usingNumberinstead of the previousId.- Verified in
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Controllers/Products/ProductController.csthat route calls and cache purging utilize the updated URL pattern (e.g.,/product/{dto.Number}/{Uri.EscapeDataString(dto.Name!)}).- No instances of URL patterns using
Idwere detected in our search.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Controllers/Products/ProductController.cs (2)
81-81: LGTM! Cache purging paths updated correctly.Cache purging paths now use the new number-based URL structure, maintaining consistency with the DTO changes.
102-102: LGTM! Cache purging in Delete method aligned with Update method.The cache purging paths in the Delete method mirror those in the Update method, ensuring consistent cache invalidation.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Configurations/Product/ProductConfiguration.cs (1)
11-11: LGTM! Unique index ensures data integrity.The unique index on the Number property prevents duplicate product numbers.
src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/ProductPage.razor (1)
1-2: LGTM! Route parameter changes align with the new integer-based product identification.The route parameter changes from
{Id:guid}to{Number:int}are consistent across both default and culture-specific routes.src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.fa.resx (1)
381-383: LGTM! Persian localization for "Number" added correctly.The new localization entry for "Number" (شماره) follows the established pattern and provides proper Persian translation.
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.resx (1)
381-383: LGTM! English localization for "Number" added correctly.The new localization entry for "Number" follows the established pattern and maintains consistency with other language resources.
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.nl.resx (1)
381-383: LGTM! Dutch localization for "Number" added.The new localization entry "Nummer" for "Number" is correctly added and follows the existing format.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Migrations/AppDbContextModelSnapshot.cs (2)
289-291:Details
❓ Verification inconclusive
Product entity enhanced with image support and unique number.
Good additions to the Product entity:
- ImageFileName property for storing image references
- Number property with a unique index for product identification
- Logical property ordering maintained
Verify image file handling implementation.
Since a new ImageFileName property has been added, ensure proper image file handling is implemented:
- File upload validation
- Storage location configuration
- File cleanup on product deletion
Also applies to: 297-301, 310-312
🏁 Script executed:
#!/bin/bash # Search for image handling implementation rg -g "!*.resx" -g "!*.cs.d.ts" "ImageFileName" -A 5Length of output: 7714
Product entity enhancements verified with integrated image file handling – further validation needed
The migration snapshot and model updates correctly introduce the new
ImageFileNameandNumberproperties in the Product entity. The related image file handling is partially implemented (see usage in the AttachmentController and ProductDto), ensuring that image paths are processed as expected.Please ensure that the complete image handling flow is robust by verifying:
- File upload validations are in place.
- Storage location configuration is correctly set.
- File cleanup on product deletion is properly handled.
14-14:Details
✅ Verification successful
Verify EF Core version compatibility.
The EF Core version has been updated to 9.0.2. Let's verify this is the latest stable version and check for any breaking changes.
🌐 Web query:
What is the latest stable version of Entity Framework Core?💡 Result:
The latest stable version of Entity Framework Core as of February 17, 2025 is Entity Framework Core 9.0, which was released on November 14, 2024[6][10]. This version targets .NET 8 and will be supported until May 12, 2026[4].
Key details about EF Core versions:
- EF Core 8.0 (released November 2023) introduced features like JSON columns and bulk updates[1]
- EF Core 9.0 added new capabilities including enhanced LINQ query optimizations and improved performance metrics[6]
- The next planned release is EF Core 10.0, scheduled for November 2025[4]
The latest NuGet package available is Microsoft.EntityFrameworkCore v9.0.2, which includes recent bug fixes and performance improvements[8][10]. This version continues to support multiple database providers including SQL Server, PostgreSQL, MySQL, and SQLite[2].
Citations:
- 1: https://en.wikipedia.org/wiki/Entity_Framework
- 2: https://www.entityframeworktutorial.net/efcore/entity-framework-core.aspx
- 3: https://www.infoq.com/news/2023/03/ef-core-8/
- 4: https://learn.microsoft.com/en-us/ef/core/what-is-new/
- 5: https://www.bricelam.net/2020/02/24/a-history-of-ef.html
- 6: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-9.0/whatsnew
- 7: https://www.nuget.org/packages/EntityFramework/
- 8: https://www.nuget.org/packages/microsoft.entityframeworkcore
- 9: https://learn.microsoft.com/en-us/ef/ef6/what-is-new/past-releases
- 10: https://github.com/dotnet/efcore/releases
EF Core Version Compatibility Verified
- The code in
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Migrations/AppDbContextModelSnapshot.csat line 14 now uses:modelBuilder.HasAnnotation("ProductVersion", "9.0.2");- A web query confirms that EF Core 9.0 is the latest stable version and the NuGet package Microsoft.EntityFrameworkCore v9.0.2 is in line with this release.
- No breaking changes or additional modifications are necessary.
closes #9929
Summary by CodeRabbit