Skip to content

Create e-commerce Web API#96

Open
basemkasem wants to merge 50 commits intothe-csharp-academy:mainfrom
basemkasem:main
Open

Create e-commerce Web API#96
basemkasem wants to merge 50 commits intothe-csharp-academy:mainfrom
basemkasem:main

Conversation

@basemkasem
Copy link
Copy Markdown

No description provided.

basemkasem and others added 30 commits February 19, 2026 17:26
Fix UnitOfWork performance issue or creating a new object each time needed in a request.
Update "delete" logic in GenericRepository
# This is the 1st commit message:

Add pagination support to GetAllAsync and include properties to GetAllAsync and GetByIdAsync

# The commit message the-csharp-academy#2 will be skipped:

# fixup! Add pagination support to GetAllAsync and include properties to GetAllAsync and GetByIdAsync
Fix category including property to product.
Fix a repository method to be async
Added detailed documentation for the E-commerce API, including features, architecture, technologies, installation instructions, API endpoints, usage examples, and future enhancements.
basemkasem and others added 20 commits March 27, 2026 06:30
Removed contributing guidelines and license section.
…oller to use FluentValidation for validation.
… names and error messages in ProductController
…troller to use FluentValidation for validation.
Created input validation and exception handling from the future enhancements section and added to the features section.
Updated exception handling and input validation sections for clarity and consistency.
Updated README to reflect API versioning and added FluentValidation details.
Updated the status of the authentication & authorization task to indicate it is currently in progress.
Copy link
Copy Markdown

@chrisjamiecarter chrisjamiecarter left a comment

Choose a reason for hiding this comment

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

Hey @basemkasem 👋,

Excellent work on your E-commerce API project submission 🎉!

I have performed a peer review. Review/ignore any comments as you wish.

Your code demonstrates a solid understanding of Clean Architecture with excellent separation of concerns across Core, Data, Services, and Web layers. The implementation includes sophisticated features like the Result pattern for error handling, FluentValidation for input validation, API versioning, soft delete pattern, and pagination support. The build succeeds and the code structure is well-organized.


🟠 Project Submission

💡 Please place all your code inside a single top-level folder named: [ProjectName].[UserName].

👨‍🏫 Example: EcommerceApi.basemkasem

📁 CodeReviews.Console.EcommerceApi ⬅️ Forked repo
 ┣ 📄 .codacy.yml
 ┣ 📄 .gitignore
 ┣ 📁 EcommerceApi.basemkasem ❗ Should be this
 ┃  ┗ 📄 Project.sln ✅
 ┃  ┗ 📄 README.md ❗Should be here not root
 ┃  ┗ 📁 EcommerceApi.Core ✅
 ┃  ┗ 📁 EcommerceApi.Data ✅
 ┃  ┗ 📁 EcommerceApi.Service ✅
 ┃  ┗ 📁 EcommerceApi.Web ✅

💭 This helps me clearly identify your work and confirms you can work within community repository guidelines.


I will go ahead and mark as approved, keep up the excellent work on the next projects! 😊

Best regards,
@chrisjamiecarter 👍

@@ -0,0 +1,8 @@
namespace Ecommerce.Core.DTOs.Category;

public class CategoryDto
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Class vs Record

💭 Nothing wrong here, just think of the benefits of using a record here instead of a class.


namespace Ecommerce.Core.Interfaces.Repositories;

public interface IGenericRepository<T> where T : class
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Generic Repositories

❓ Interesting, did you implement generic repositories for learning, or do you actually prefer using them?


namespace Ecommerce.Core.Interfaces.Repositories;

public interface IUnitOfWork
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Unit of Work

❓ I know you have implemented CA and app should not know about infra, but should unit of work be defined here as a contract? Also as you are using EFCore in Infra, that already implements the UoW pattern, so is kind of pointless.

RuleFor(x => x.Name)
.NotEmpty()
.WithMessage("Category name is required.")
.MaximumLength(50)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Magic Numbers

💡 Move magic numbers like this into the entity, so the single source of truth lives there instead of every single validator.

public DbSet<SaleItem> SaleItems { get; set; }


protected override void OnModelCreating(ModelBuilder modelBuilder)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Configuration Classes

💡 Consider creating configuration classes for your entities and holding this information there instead of here in AppDbContext, then applying by calling modelBuilder.ApplyConfigurationsFromAssembly; instead.


app.MapControllers();

app.Run(); No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 Missing Database Initialization

💡 The application doesn't initialize the database on startup. I would recommend for C# academy project submissions you add EnsureCreated or Migrate to ensure the database is created/migrated. I know your README covers this, but one of your jobs is to make it as frictionless for the reviewer as possible.

}
},
"AllowedHosts": "*"
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 Missing Connection String

💡 Again, I know this is covered in the README, but the appsettings.json is missing the required "ConnectionStrings" section. You should at least have a dummy/placeholder value in here. I assume you are using user secrets for the actual connection string on your machine which is best practice.

Price = product.Price,
CategoryId = product.CategoryId
};
if(newProduct.Quantity <= 0)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 Domain Concern

💡 This logic is probably a Domain rule and should be on the entity. Also would be true for Quantity == 0 which is not negative like the fail message suggests.

int rowsAffected = await _unitOfWork.CompleteAsync();
if (rowsAffected == 0)
{
return Result<ProductDto>.Fail("Failed to create category");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Error Message References Wrong Entity

💡 When creation fails, the error message says "Failed to create category" but it's actually creating a Product. This should say "Failed to create product".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants