-
Notifications
You must be signed in to change notification settings - Fork 0
Chore/image moderation #42
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
Conversation
c9d636b to
09ebca5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds image content moderation functionality using Azure AI Content Safety to validate uploaded images before storing them. It integrates Azure AI Foundry's content safety services to automatically check gathering cover images for inappropriate content.
- Added Azure AI Content Safety integration with configuration and service client setup
- Implemented content moderation logic that analyzes images and blocks unsafe content
- Consolidated configuration files by moving development settings to main appsettings.json
Reviewed Changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Evently.Server/Features/Files/Services/ObjectStorageService.cs | Added content safety client and moderation logic to analyze images |
| src/Evently.Server/Features/Gatherings/Controllers/GatheringsController.cs | Added content moderation check before uploading cover images |
| src/Evently.Server/Common/Domains/Models/Settings.cs | Added AzureAIFoundry configuration model |
| src/Evently.Server/Common/Domains/Interfaces/IObjectStorageService.cs | Added PassesContentModeration method to interface |
| src/Evently.Server/Evently.Server.csproj | Added Azure.AI.ContentSafety package reference |
| src/Evently.Server/appsettings.json | Added configuration sections for Azure AI Foundry and other services |
| src/Evently.Server/appsettings.Development.json | Removed all content (consolidated into main appsettings) |
| src/evently.client/src/lib/services/gathering-service.ts | Fixed handling of empty gathering category details array |
| src/evently.client/src/lib/components/card.tsx | Added null check for image source before using placeholder images |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
src/Evently.Server/Features/Files/Services/ObjectStorageService.cs
Outdated
Show resolved
Hide resolved
| int? score = result.CategoriesAnalysis | ||
| .Select(v => v.Severity) | ||
| .Aggregate((a, b) => a + b) | ||
| ?? 0; | ||
| return result.CategoriesAnalysis.Count != 0 && score == 0; |
Copilot
AI
Oct 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic for determining content safety is incorrect. When CategoriesAnalysis.Count is 0, the method returns false (content is unsafe), but when there are no categories to analyze, the content should be considered safe. Also, the aggregate will throw an exception if the collection is empty.
| int? score = result.CategoriesAnalysis | |
| .Select(v => v.Severity) | |
| .Aggregate((a, b) => a + b) | |
| ?? 0; | |
| return result.CategoriesAnalysis.Count != 0 && score == 0; | |
| if (result.CategoriesAnalysis.Count == 0) | |
| { | |
| // No categories to analyze, consider content safe | |
| return true; | |
| } | |
| int score = result.CategoriesAnalysis.Sum(v => v.Severity); | |
| return score == 0; |
| BinaryData binaryData = await coverImg.ToBinaryData(); | ||
| bool isContentSafe = await objectStorageService.PassesContentModeration(binaryData); | ||
| if (!isContentSafe) { | ||
| return new Uri(string.Empty, UriKind.RelativeOrAbsolute); |
Copilot
AI
Oct 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning an empty URI when content moderation fails is misleading. Consider throwing an exception or returning a specific error response to clearly indicate the image was rejected due to content policy violations.
src/Evently.Server/appsettings.json
Outdated
| "ContentSafetyKey": "<ai-foundary-content-safety-key>", | ||
| "ContentSafetyEndpoint": "<ai-foundary-content-safety-api>" |
Copilot
AI
Oct 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'foundary' to 'foundry'.
| "ContentSafetyKey": "<ai-foundary-content-safety-key>", | |
| "ContentSafetyEndpoint": "<ai-foundary-content-safety-api>" | |
| "ContentSafetyKey": "<ai-foundry-content-safety-key>", | |
| "ContentSafetyEndpoint": "<ai-foundry-content-safety-api>" |
b8b8cd3 to
df69999
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 2 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| .Aggregate((a, b) => a + b) | ||
| ?? 0; |
Copilot
AI
Oct 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The null-conditional operator ?? is applied to the wrong expression. If result.CategoriesAnalysis is empty, Aggregate will throw an exception before the null check. Consider using DefaultIfEmpty() or checking if the collection is empty first.
| .Aggregate((a, b) => a + b) | |
| ?? 0; | |
| .DefaultIfEmpty(0) | |
| .Aggregate((a, b) => a + b); |
| AnalyzeImageResult result = response.Value; | ||
| int? score = result.CategoriesAnalysis | ||
| .Select(v => v.Severity) | ||
| .Aggregate((a, b) => a + b) |
Copilot
AI
Oct 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The aggregation logic assumes all severity values are integers that can be summed. Consider using Sum() instead of Aggregate((a, b) => a + b) for clarity and better null handling.
| .Aggregate((a, b) => a + b) | |
| .Sum() |
No description provided.