Skip to content

Conversation

@BengeeL
Copy link
Member

@BengeeL BengeeL commented Jun 25, 2025

Summary by CodeRabbit

  • New Features

    • Added an image upload service for thumbnail processing, including resizing, compression, and validation before upload.
    • Improved content creation and editing routing to clearly distinguish between create and edit modes.
  • Bug Fixes

    • Fixed potential issues with comment refreshing by ensuring state updates only occur with valid data.
  • Refactor

    • Enhanced the content editor with better structure, modular functions, and improved error handling.
    • Updated authentication and authorization handling for content editing.
    • Improved image preview styles for thumbnails.
  • Style

    • Updated comment styles in several service files for consistency.
    • Adjusted ESLint configuration and string formatting.
  • Chores

    • Updated route authentication for editing content to require user authentication.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 25, 2025

Walkthrough

This update refactors both frontend and backend components related to content editing and image handling. Key changes include new image upload and validation logic, improved modularity and error handling in the content editor, route and authentication adjustments, and updates to comment styles. No core functionality is altered, but maintainability and clarity are enhanced.

Changes

File(s) Change Summary
backend/src/modules/content/controllers/content.controller.ts Refactored user ID extraction and authorization in editContent; cleaned up comments and formatting.
backend/src/modules/content/routes/content.routes.ts Simplified edit route by removing userId param; added authentication middleware.
backend/src/modules/storage/services/storage.service.ts Changed uploadFileDevelopment to return a URL instead of a filesystem path.
frontend/eslint.config.js Switched to double quotes and added a rule to disable exhaustive deps for react-hooks.
frontend/src/App.tsx Split content create/edit routes and passed explicit isEditMode prop to ContentEditor.
frontend/src/components/content/CommentList.tsx Added a check to ensure comments state updates only with valid data.
frontend/src/pages/content/ContentEditor.tsx Major refactor: modularized logic, improved error handling, added image upload abstraction, clarified comments.
frontend/src/services/ImageService.ts Introduced new service for image resizing, validation, and upload.
frontend/src/services/AuthenticationService.ts
frontend/src/services/CommentService.ts
frontend/src/services/FollowService.ts
frontend/src/services/NotificationService.ts
frontend/src/services/SubscriptionService.ts
frontend/src/services/UserService.ts
Replaced all JSDoc-style comments with standard block comments.
frontend/src/styles/content/createContent.scss Updated .thumbnail-preview to use max dimensions and object-fit for better image display.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ContentEditor
    participant ImageService
    participant Backend

    User->>ContentEditor: Selects or edits content, uploads thumbnail
    ContentEditor->>ImageService: uploadThumbnail(thumbnailFile)
    ImageService->>ImageService: Resize, validate, compress image
    ImageService->>Backend: POST /api/content/upload-thumbnail (multipart/form-data)
    Backend-->>ImageService: Returns thumbnail URL or error
    ImageService-->>ContentEditor: Returns thumbnail URL or error
    ContentEditor->>Backend: POST/PUT content with thumbnail URL and data
    Backend-->>ContentEditor: Returns success or error
    ContentEditor-->>User: Navigates or displays error
Loading

Suggested reviewers

  • Mindful-Developer
  • Hi-kue

Poem

In a burrow of code, the carrots align,
Images now shrink, and thumbnails look fine.
Routes are more tidy, the comments less wild,
The editor’s smarter, the bunny is smiled.
With each hop of logic, the garden grows bright—
Refactored and ready for users’ delight!
🥕✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Post Copyable Unit Tests in Comment
  • Commit Unit Tests in branch SUMMA-35

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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.

@BengeeL BengeeL changed the title SUMMA-35 SUMMA-35: ImageService processing frontend Jun 25, 2025
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: 2

🧹 Nitpick comments (7)
frontend/src/services/NotificationService.ts (1)

31-35: Remove noisy console.log or guard it behind a logger flag

Shipping raw console.log calls can leak PII in production and pollute client consoles. Consider a proper logger or strip in production bundles.

frontend/src/services/SubscriptionService.ts (1)

6-12: Redundant @returns tags – pick one per outcome

Three consecutive @returns lines makes generated docs confusing:

* @returns A promise …
* @returns {Promise<{url: string}>}
* @returns {Error}

Collapse to a single @returns line (or use @throws for errors) to keep tooling output clean.

frontend/src/services/CommentService.ts (1)

5-11: /* … */ loses JSDoc/intellisense support – deliberate?

Changing /** … */ to /* … */ strips JSDoc, so IDEs no longer show typed hints for parameters/returns.
If you only wanted visual style consistency, prefer keeping the opening /** while removing @ tags you dislike.
Otherwise you trade off DX for style.

frontend/src/services/UserService.ts (1)

5-12: Mixed comment styles in same file

Lines 13-21 still use /** … */ while the rest switched to /* … */. Decide on one style to avoid churn in future diffs.

frontend/src/services/FollowService.ts (1)

5-10: Consider retaining JSDoc comments for better tooling support.

Converting from JSDoc-style comments (/** ... */) to regular multiline comments (/* ... */) removes valuable benefits such as:

  • Automatic documentation generation
  • Enhanced IDE intellisense and hover information
  • Better TypeScript integration
  • Standard documentation format for service classes

JSDoc comments are particularly valuable for service classes like this one that expose public APIs.

Also applies to: 12-21, 47-56, 81-89, 110-118, 139-147, 169-178, 204-213

frontend/src/services/ImageService.ts (1)

9-152: Consider refactoring to standalone functions instead of a static-only class.

The static analysis correctly identifies that this class contains only static members. This pattern is generally discouraged in favor of standalone functions, which are more tree-shakable and follow functional programming principles.

Consider refactoring to standalone functions:

-export class ImageService {
-  public static async uploadThumbnail(
+export async function uploadThumbnail(
     thumbnail: File
   ): Promise<{ url: string } | Error> {
     try {
-      const preparedFile = await ImageService.prepareImageForUpload(thumbnail);
+      const preparedFile = await prepareImageForUpload(thumbnail);
       // ... rest of implementation
     }
   }

-  private static async prepareImageForUpload(file: File): Promise<File> {
+async function prepareImageForUpload(file: File): Promise<File> {
     // ... implementation
   }
   // ... other functions

This would make the code more modular and easier to test individual functions.

frontend/src/pages/content/ContentEditor.tsx (1)

282-282: Address the TODO comment.

The TODO indicates plans to move thumbnail logic to a content service, which would further improve separation of concerns.

Would you like me to help design the content service structure or create an issue to track this refactoring task?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e634609 and 1d2b396.

📒 Files selected for processing (15)
  • backend/src/modules/content/controllers/content.controller.ts (5 hunks)
  • backend/src/modules/content/routes/content.routes.ts (2 hunks)
  • backend/src/modules/storage/services/storage.service.ts (1 hunks)
  • frontend/eslint.config.js (1 hunks)
  • frontend/src/App.tsx (1 hunks)
  • frontend/src/components/content/CommentList.tsx (1 hunks)
  • frontend/src/pages/content/ContentEditor.tsx (6 hunks)
  • frontend/src/services/AuthenticationService.ts (9 hunks)
  • frontend/src/services/CommentService.ts (5 hunks)
  • frontend/src/services/FollowService.ts (7 hunks)
  • frontend/src/services/ImageService.ts (1 hunks)
  • frontend/src/services/NotificationService.ts (3 hunks)
  • frontend/src/services/SubscriptionService.ts (3 hunks)
  • frontend/src/services/UserService.ts (9 hunks)
  • frontend/src/styles/content/createContent.scss (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
backend/src/modules/content/routes/content.routes.ts (1)
backend/src/shared/middleware/auth.ts (1)
  • authenticateToken (20-67)
backend/src/modules/storage/services/storage.service.ts (1)
backend/src/shared/utils/logger.ts (1)
  • logger (28-49)
backend/src/modules/content/controllers/content.controller.ts (1)
backend/src/modules/content/services/content.service.ts (1)
  • ContentService (27-854)
frontend/src/services/ImageService.ts (1)
frontend/src/scripts/api.ts (1)
  • apiURL (8-8)
🪛 Biome (1.9.4)
frontend/src/services/ImageService.ts

[error] 9-152: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)

🔇 Additional comments (16)
frontend/src/services/NotificationService.ts (1)

75-88: Let’s confirm the current markAsRead implementation and its HTTP call to determine whether notificationId is used or truly “mark all.”

#!/bin/bash
# Locate and display the markAsRead method in NotificationService.ts
rg -n "static async markAsRead" -n frontend/src/services/NotificationService.ts --context 5
frontend/src/services/AuthenticationService.ts (1)

4-11: Same JSDoc-to-plain-comment swap – verify tooling impact

As with other services, swapping to /* disables automatic doc generation & TS intellisense. Confirm this is an intentional repo-wide decision before merging.

frontend/src/styles/content/createContent.scss (1)

98-104: Excellent styling improvements for responsive image display.

The changes enhance the thumbnail preview functionality:

  • Using max-width/max-height instead of fixed dimensions provides better responsive behavior
  • Adding object-fit: cover prevents image distortion while maintaining aspect ratio
  • The explanatory comment clearly documents the intent

These changes align well with modern CSS practices for responsive image handling.

frontend/eslint.config.js (2)

1-25: LGTM on the quote style consistency.

The conversion from single quotes to double quotes provides consistent formatting throughout the configuration file.

Also applies to: 27-29


26-26: Reconsider disabling the exhaustive-deps rule.

Disabling "react-hooks/exhaustive-deps" removes an important safety check that helps prevent common React hooks issues such as:

  • Stale closures in useEffect
  • Missing dependencies causing bugs
  • Infinite re-render loops

This rule should only be disabled if there's a specific, well-documented reason.

Can you provide justification for why this rule needs to be disabled? If it's causing false positives in specific cases, consider using eslint-disable comments on those specific lines instead of globally disabling the rule.

frontend/src/components/content/CommentList.tsx (1)

58-61: Good defensive programming practice.

Adding the conditional check for commentsResult before updating state prevents potential issues with undefined or null values. This complements the existing error handling and ensures the component state remains consistent.

backend/src/modules/content/routes/content.routes.ts (2)

4-4: LGTM on adding authentication middleware import.

The import supports the security enhancement for the content editing route.


27-31: Excellent security improvement for content editing.

The changes significantly enhance security by:

  • Removing the userId parameter from the URL path, preventing URL manipulation attacks
  • Adding authenticateToken middleware to verify user identity via JWT token
  • Ensuring the controller receives the authenticated user ID from req.user.uid instead of trusting URL parameters

This prevents unauthorized users from editing others' content by manipulating the URL parameters.

frontend/src/App.tsx (1)

103-110: Excellent routing improvement!

The separation of create and edit routes with explicit isEditMode props improves code clarity and makes the component behavior more predictable. This aligns well with the ContentEditor refactoring.

backend/src/modules/content/controllers/content.controller.ts (2)

89-91: Good security improvement in authentication handling.

Retrieving the user ID from req.user?.uid instead of request parameters is more secure and aligns with the authentication middleware changes. This prevents potential authorization bypass through URL manipulation.

Also applies to: 98-98


108-108: Consider the error status code change.

The error status code was changed from 401 to 500. Ensure this aligns with your error handling strategy - 401 (Unauthorized) might be more appropriate for authorization failures than 500 (Internal Server Error).

frontend/src/services/ImageService.ts (2)

61-61: Good file size validation.

The 5MB limit is reasonable for thumbnail images, especially given the resizing to 1280x1280 pixels that occurs beforehand.


86-99: Solid aspect ratio preservation logic.

The image resizing logic correctly maintains aspect ratio and properly handles both width and height constraints. Good implementation!

frontend/src/pages/content/ContentEditor.tsx (3)

150-158: Well-implemented URL to File conversion.

The urlToFile function correctly handles the conversion from URL to File object, which is essential for editing existing content with thumbnails.


166-176: Good separation of concerns with clearContent helper.

Extracting the clear functionality into a dedicated function improves code organization and reusability.


284-296: Excellent ImageService integration with proper error handling.

The integration with ImageService.uploadThumbnail is clean and includes proper error handling by checking if the response is an Error instance.

Comment on lines +116 to +121
// Returning URL for the file
const urlPath = `${filePath}/${fileName}`;
const url = `http://localhost:3000/local_uploads/${urlPath}`;

// Return the absolute file system path
return { url: fullPath };
return { url };
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Update the misleading comment.

The comment on line 120 states "Return the absolute file system path" but the method now returns a URL string. This inconsistency could confuse future developers.

-      // Return the absolute file system path
+      // Return the URL for accessing the uploaded file
       return { url };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Returning URL for the file
const urlPath = `${filePath}/${fileName}`;
const url = `http://localhost:3000/local_uploads/${urlPath}`;
// Return the absolute file system path
return { url: fullPath };
return { url };
// Returning URL for the file
const urlPath = `${filePath}/${fileName}`;
const url = `http://localhost:3000/local_uploads/${urlPath}`;
// Return the URL for accessing the uploaded file
return { url };
🤖 Prompt for AI Agents
In backend/src/modules/storage/services/storage.service.ts around lines 116 to
121, the comment on line 120 incorrectly states "Return the absolute file system
path" while the code actually returns a URL string. Update this comment to
accurately reflect that the method returns a URL string pointing to the file
location, removing any mention of an absolute file system path to avoid
confusion.

Comment on lines +312 to +314
if (!auth.isAuthenticated) {
navigate("/authentication/login");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve authentication check pattern.

The current authentication check executes on every render, which could cause unnecessary redirects. Consider using a useEffect hook to handle this more efficiently.

-  // User must be authenticated to create content
-  if (!auth.isAuthenticated) {
-    navigate("/authentication/login");
-  }
+  // User must be authenticated to create content
+  useEffect(() => {
+    if (!auth.isAuthenticated) {
+      navigate("/authentication/login");
+    }
+  }, [auth.isAuthenticated, navigate]);

This prevents the redirect from being triggered on every render and follows React best practices.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!auth.isAuthenticated) {
navigate("/authentication/login");
}
// User must be authenticated to create content
useEffect(() => {
if (!auth.isAuthenticated) {
navigate("/authentication/login");
}
}, [auth.isAuthenticated, navigate]);
🤖 Prompt for AI Agents
In frontend/src/pages/content/ContentEditor.tsx around lines 312 to 314, the
authentication check runs on every render causing unnecessary redirects.
Refactor the code to move the authentication check and navigate call inside a
useEffect hook with an empty dependency array or appropriate dependencies, so
the redirect only happens once when the component mounts or when authentication
state changes, following React best practices.

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