feat: Implement file management and authorization features
Build and Deploy to Kubernetes / build-and-deploy (push) Failing after 3m9s

- Add RequiresPermissionAttribute for gRPC method access control.
- Create IFileManagementService interface for file upload and management.
- Implement AddProductImageCommand and handler for adding product images.
- Implement CreateNewProductsCommand and handler for creating new products with image uploads.
- Implement DeleteProductsCommand and handler for deleting products and their associations.
- Implement RemoveProductImageCommand and handler for removing product images from galleries.
- Implement UpdateProductsCommand and handler for updating product details and images.
- Create GetProductGalleryQuery and handler for retrieving product galleries.
- Implement PermissionService for role-based access control using JWT claims.
- Implement FileManagementService for handling file uploads and image optimization.
- Define gRPC service and messages for file management in fms.proto.
- Add FluentValidation for request validation in various commands.
- Create PermissionInterceptor for enforcing permissions on gRPC methods.
This commit is contained in:
masoodafar-web
2026-02-10 22:04:54 +03:30
parent f64b6be7da
commit b42d9e141d
65 changed files with 3082 additions and 2384 deletions
@@ -79,6 +79,50 @@ service ProductsContract
get: "/Customer/GetProducts"
};
};
// ============= Category-Product DragDrop Methods =============
rpc GetProductsForCategory(GetProductsForCategoryRequest) returns (GetProductsForCategoryResponse){
option (google.api.http) = {
get: "/GetProductsForCategory"
};
};
rpc GetCategories(GetCategoriesRequest) returns (GetCategoriesResponse){
option (google.api.http) = {
get: "/GetCategories"
};
};
rpc UpdateProductCategories(UpdateProductCategoriesRequest) returns (google.protobuf.Empty){
option (google.api.http) = {
post: "/UpdateProductCategories"
body: "*"
};
};
rpc UpdateCategoryProducts(UpdateCategoryProductsRequest) returns (google.protobuf.Empty){
option (google.api.http) = {
post: "/UpdateCategoryProducts"
body: "*"
};
};
// ============= Product Image Management =============
rpc AddProductImage(AddProductImageRequest) returns (AddProductImageResponse){
option (google.api.http) = {
post: "/AddProductImage"
body: "*"
};
};
rpc RemoveProductImage(RemoveProductImageRequest) returns (google.protobuf.Empty){
option (google.api.http) = {
delete: "/RemoveProductImage"
};
};
rpc GetProductGallery(GetProductGalleryRequest) returns (GetProductGalleryResponse){
option (google.api.http) = {
get: "/GetProductGallery"
};
};
}
message CreateNewProductsRequest
{
@@ -96,6 +140,10 @@ message CreateNewProductsRequest
int32 remaining_count = 12;
// لیست شناسه دسته‌بندی‌های محصول
repeated int64 category_ids = 13;
// فایل تصویر اصلی محصول (آپلود باینری)
ImageFileModel image_file = 14;
// فایل تصویر بندانگشتی محصول (آپلود باینری)
ImageFileModel thumbnail_file = 15;
}
message CreateNewProductsResponse
{
@@ -118,6 +166,10 @@ message UpdateProductsRequest
int32 remaining_count = 13;
// لیست شناسه دسته‌بندی‌های محصول
repeated int64 category_ids = 14;
// فایل تصویر اصلی محصول (آپلود باینری)
ImageFileModel image_file = 15;
// فایل تصویر بندانگشتی محصول (آپلود باینری)
ImageFileModel thumbnail_file = 16;
}
message DeleteProductsRequest
{
@@ -334,3 +386,97 @@ message ToggleProductStatusResponse
int32 failed = 3;
repeated BulkOperationError errors = 4;
}
// Category Product Item (for drag-drop UI)
message CategoryProductItem
{
int64 id = 1;
string title = 2;
bool selected = 3;
}
// Get Products for Category
message GetProductsForCategoryRequest
{
int64 category_id = 1;
}
message GetProductsForCategoryResponse
{
repeated CategoryProductItem items = 1;
}
// Category Item (for product categories drag-drop)
message CategoryItem
{
int64 id = 1;
string title = 2;
bool selected = 3;
}
// Get Categories for Product
message GetCategoriesRequest
{
int64 product_id = 1;
}
message GetCategoriesResponse
{
repeated CategoryItem items = 1;
}
// Update Product Categories
message UpdateProductCategoriesRequest
{
int64 product_id = 1;
repeated int64 category_ids = 2;
}
// Update Category Products
message UpdateCategoryProductsRequest
{
int64 category_id = 1;
repeated int64 product_ids = 2;
}
// Image File Model
message ImageFileModel
{
bytes file = 1;
string mime = 2;
string file_name = 3;
}
// Get Product Gallery
message GetProductGalleryRequest
{
int64 product_id = 1;
}
message GetProductGalleryResponse
{
repeated ProductGalleryItem items = 1;
}
// Add Product Image
message AddProductImageRequest
{
int64 product_id = 1;
string title = 2;
ImageFileModel image_file = 3;
}
message AddProductImageResponse
{
int64 product_gallery_id = 1;
int64 product_image_id = 2;
string title = 3;
string image_path = 4;
string image_thumbnail_path = 5;
}
// Remove Product Image
message RemoveProductImageRequest
{
int64 product_gallery_id = 1;
}