Skip to content

Implement media storage enhancements with Metadata Saving#120

Open
gabito1451 wants to merge 5 commits into
PayStell:mainfrom
gabito1451:#119
Open

Implement media storage enhancements with Metadata Saving#120
gabito1451 wants to merge 5 commits into
PayStell:mainfrom
gabito1451:#119

Conversation

@gabito1451

@gabito1451 gabito1451 commented Jul 25, 2025

Copy link
Copy Markdown

Pull Request Overview

📝 Summary

This PR introduces improvements to the file upload feature in the Express backend. It includes middleware for handling file uploads and a method for saving file metadata.

🔗 Related Issues

🔄 Changes Made

controllers/fileUpload.controller.ts

  • Added handleFileUpload middleware:

    • Verifies file presence in request.
    • Uses FileUploadService to generate file URL.
    • Attaches fileUrl to req.body.
  • Added saveFileMetadata controller method:

    • Extracts file metadata (filename, size, mimetype, etc.)
    • Merges with request body.
    • Returns metadata as JSON.

services/fileUpload.service.ts

  • Implemented:
    public async saveFileMetadata(file: Express.Multer.File, body: any): Promise<any> {
      return {
        filename: file.filename,
        originalname: file.originalname,
        mimetype: file.mimetype,
        size: file.size,
        ...body,
      };
    }

🖼️ Current Output

Give evidence like screenshots of what your job looks like.

🧪 Testing

If applicable, describe the tests performed. Provide screenshots, test outputs, or any resources that can help reviewers understand how the changes were tested.

💬 Comments

Any additional context, questions, or considerations for the reviewers.

Summary by CodeRabbit

  • New Features

    • File upload endpoint with virus scanning, image processing, metadata capture, and metadata retrieval.
    • Configurable storage backends: local disk or AWS S3.
    • Daily cleanup job to remove unreferenced files older than 30 days.
    • API documentation exposure (Swagger) and additional health/session/payment/subscription endpoints.
  • Bug Fixes

    • Improved file deletion to correctly handle both local and S3 storage.
  • Chores

    • Updated runtime and dev dependencies and reorganized type packages.

@coderabbitai

coderabbitai Bot commented Jul 25, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Introduces a full media storage subsystem: new storage providers (local, S3), storage interface, enhanced upload service (virus scanning, image processing, multi-backend uploads/deletes), file metadata entity and persistence, upload route/controller wiring, scheduled cleanup job, and package dependency updates for clamav and sharp.

Changes

Cohort / File(s) Change Summary
Package manifest
package.json
Added runtime deps clamav.js, sharp; reorganized type packages and updated devDependencies (@types/clamav.js, @types/aws-sdk, bumped @types/express, moved @types/multer).
App wiring & routes
src/app.ts
Registered file upload routes under /api/files, added middleware wiring (auth, audit, config, rate limiting), Swagger setup, and expanded route registration order and error handling.
Upload controller & route
src/controllers/fileUpload.controller.ts, src/routes/fileUpload.route.ts
Controller attaches fileMetadata (filename, size) to req.body; new /upload POST route using Multer invokes controller and persists metadata via FileUploadService.
File metadata model
src/models/fileMetaData.model.ts
New FileMetadata TypeORM entity and exported StorageProviderType alias with fields for filename, originalName, mimeType, size, url, userId, tags, category, description, uploadedAt, storageProvider, isWatermarked; indexes on userId and category.
File upload service
src/services/fileUpload.service.ts
Major refactor: added storageType (local
Storage abstraction & providers
src/storage/storageProvider.ts, src/storage/localStorageProvider.ts, src/storage/s3StorageProvider.ts
Added StorageProvider interface and two implementations: LocalStorageProvider (file move, delete, URL) and S3StorageProvider (S3 client uploads, delete, URL generation).
Cleanup task
src/tasks/cleanUpTask.ts
New daily cron job to batch-scan metadata, check references, delete aged/unreferenced files via FileUploadService, and remove DB records.
Database export
src/config/db.ts
Changed AppDataSource declaration to an exported constant (export const AppDataSource).

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ExpressApp
    participant FileUploadRoute
    participant Multer
    participant FileUploadController
    participant FileUploadService
    participant ClamAV
    participant Sharp
    participant StorageProvider
    participant MetadataDB

    Client->>ExpressApp: POST /api/files/upload (multipart)
    ExpressApp->>FileUploadRoute: dispatch
    FileUploadRoute->>Multer: parse file
    Multer->>FileUploadController: attach file to req
    FileUploadController->>FileUploadService: processAndUploadFile(file)
    FileUploadService->>ClamAV: scan file
    ClamAV-->>FileUploadService: scan result
    alt clean
        FileUploadService->>Sharp: process image (resize/compress)
        Sharp-->>FileUploadService: processed buffer
        FileUploadService->>StorageProvider: uploadFile(processed)
        StorageProvider-->>FileUploadService: fileKey / URL
        FileUploadService->>MetadataDB: save metadata (FileMetadata)
        MetadataDB-->>FileUploadService: saved record
        FileUploadService-->>FileUploadController: url & metadata
        FileUploadController-->>Client: 200 {url, metadata}
    else infected
        FileUploadService-->>FileUploadController: error (rejected)
        FileUploadController-->>Client: 400/422
    end
Loading
sequenceDiagram
    participant Cron
    participant MetadataDB
    participant ReferenceQuery
    participant FileUploadService
    participant StorageProvider

    Cron->>MetadataDB: fetch metadata (batches)
    loop per file
        MetadataDB->>ReferenceQuery: check references (user_documents)
        alt referenced or tagged important
            Note right of Cron: skip deletion
        else eligible
            Cron->>FileUploadService: deleteFile(fileUrl)
            FileUploadService->>StorageProvider: deleteFile(key)
            StorageProvider-->>FileUploadService: confirmation
            FileUploadService->>MetadataDB: remove record
        end
    end
    Cron-->>Cron: log completion
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Suggested reviewers

  • MPSxDev

Poem

🐇✨
I nibble bytes and hop through code,
I scan and shrink each payload.
I stash the files both near and far,
Then tidy up by moon and star.
A merry rabbit—files in order!

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning While the pull request delivers local and AWS S3 storage support, virus scanning, metadata schema, and a cleanup job, it does not provide Google Cloud storage integration, lacks a complete CRUD REST API for file management, omits image thumbnail generation and watermarking, and fails to offer configurable limits by user type, thereby falling short of several of the specified acceptance criteria in issue #119. To satisfy issue #119, please add Google Cloud storage support, implement full CRUD endpoints under /api/files, incorporate thumbnail generation and watermarking in the image pipeline, and expose configuration options for per-user-type limits.
Out of Scope Changes Check ⚠️ Warning The pull request introduces extensive modifications to the global application setup in src/app.ts—including audit and configuration middleware, Auth0 integration, and unrelated domain routes such as payment, subscriptions, and email verification—that are not part of the file management system objectives defined in the linked issue. Please isolate unrelated middleware and route registrations into separate pull requests, ensuring this PR focuses solely on implementing the file management enhancements outlined in issue #119.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “Implement media storage enhancements with Metadata Saving” succinctly captures the primary intent of the pull request by highlighting both the enhancement of storage capabilities and the addition of metadata persistence, which directly aligns with the main changes introduced in the code.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 21

🧹 Nitpick comments (8)
src/controllers/fileUpload.controller.ts (1)

17-20: Use safer property access for req.file.

The code uses non-null assertion (req.file.filename, req.file.mimetype, etc.) without additional null checks beyond the initial if (!req.file) check. While this should be safe given the guard clause, using optional chaining or additional validation would be more defensive.

Consider using safer property access:

       const metadata = await fileUploadService.saveFileMetadata({
-        filename: req.file.filename,
-        mimetype: req.file.mimetype,
-        size: req.file.size,
+        filename: req.file?.filename || '',
+        mimetype: req.file?.mimetype || '',
+        size: req.file?.size || 0,
       });
src/tasks/cleanUpTask.ts (1)

7-7: Consider making the cron schedule configurable.

The cleanup schedule is hardcoded to run at 2:00 AM daily. Consider making this configurable through environment variables for different deployment environments.

-  cron.schedule("0 2 * * *", async () => {
+  const schedule = process.env.CLEANUP_CRON_SCHEDULE || "0 2 * * *";
+  cron.schedule(schedule, async () => {
src/routes/fileUpload.route.ts (1)

10-10: Avoid creating multiple service instances.

Creating a new FileUploadService instance in the route when the controller also creates one could lead to inconsistent state or unnecessary resource usage.

Consider using dependency injection or a singleton pattern:

-const fileUploadService = new FileUploadService();
+// Import from a shared instance or use dependency injection
+import { fileUploadService } from '../services/fileUpload.service';
src/storage/localStorageProvider.ts (1)

19-21: Add return type and validate fileKey

-  getFileUrl(fileKey: string) {
+  getFileUrl(fileKey: string): string {
+    // Ensure fileKey doesn't contain path separators
+    const safeKey = path.basename(fileKey);
-    return `/uploads/${fileKey}`;
+    return `/uploads/${safeKey}`;
   }
src/storage/storageProvider.ts (1)

3-3: Consider renaming to avoid confusion with the StorageProvider type

There's a StorageProvider type defined in src/models/fileMetaData.model.ts as a string union type. Consider renaming this interface to IStorageProvider or StorageProviderInterface to avoid confusion.

-export interface StorageProvider {
+export interface IStorageProvider {
src/models/fileMetaData.model.ts (1)

36-37: Consider database portability for array columns

PostgreSQL array columns aren't supported by all databases (e.g., MySQL, SQLite). Consider using a many-to-many relationship with a separate tags table for better portability.

src/services/fileUpload.service.ts (2)

89-102: Handle buffer input and make image processing configurable

The method assumes file.path exists, which won't work with memory storage.

   private async processImage(
     file: Express.Multer.File,
   ): Promise<Express.Multer.File> {
-    const buffer = await sharp(file.path)
-      .resize(800, 800, { fit: "inside" })
-      .jpeg({ quality: 80 })
+    const maxDimension = parseInt(process.env.IMAGE_MAX_DIMENSION || '800', 10);
+    const quality = parseInt(process.env.IMAGE_QUALITY || '80', 10);
+    
+    const input = file.path || file.buffer;
+    if (!input) throw new Error('No file data available');
+    
+    const buffer = await sharp(input)
+      .resize(maxDimension, maxDimension, { fit: "inside" })
+      .jpeg({ quality })
       .toBuffer();

     return {
       ...file,
       buffer,
       size: buffer.length,
     };
   }

15-153: Consider using the StorageProvider pattern consistently

This service duplicates logic that's already in LocalStorageProvider and S3StorageProvider. Consider refactoring to use those implementations:

// Example refactor
export class FileUploadService {
  private storageProvider: StorageProvider;
  
  constructor() {
    const storageType = process.env.STORAGE || 'local';
    this.storageProvider = storageType === 's3' 
      ? new S3StorageProvider()
      : new LocalStorageProvider();
  }
  
  async processAndUploadFile(file: Express.Multer.File): Promise<string> {
    // Scan and process...
    return this.storageProvider.uploadFile(processedFile);
  }
}

This would:

  1. Reduce code duplication
  2. Make the service more focused (SRP)
  3. Make it easier to add new storage providers
  4. Improve testability
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ae6799f and 9f8d848.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (10)
  • package.json (3 hunks)
  • src/app.ts (2 hunks)
  • src/controllers/fileUpload.controller.ts (1 hunks)
  • src/models/fileMetaData.model.ts (1 hunks)
  • src/routes/fileUpload.route.ts (1 hunks)
  • src/services/fileUpload.service.ts (1 hunks)
  • src/storage/localStorageProvider.ts (1 hunks)
  • src/storage/s3StorageProvider.ts (1 hunks)
  • src/storage/storageProvider.ts (1 hunks)
  • src/tasks/cleanUpTask.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
src/storage/localStorageProvider.ts (2)
src/models/fileMetaData.model.ts (1)
  • StorageProvider (10-10)
src/storage/storageProvider.ts (1)
  • StorageProvider (3-10)
src/routes/fileUpload.route.ts (2)
src/services/fileUpload.service.ts (1)
  • FileUploadService (15-153)
src/middlewares/merchantAuth.ts (1)
  • asyncHandler (20-24)
src/storage/s3StorageProvider.ts (2)
src/models/fileMetaData.model.ts (1)
  • StorageProvider (10-10)
src/storage/storageProvider.ts (1)
  • StorageProvider (3-10)
src/storage/storageProvider.ts (1)
src/models/fileMetaData.model.ts (1)
  • StorageProvider (10-10)
src/models/fileMetaData.model.ts (1)
src/storage/storageProvider.ts (1)
  • StorageProvider (3-10)
🔇 Additional comments (3)
src/app.ts (1)

28-28: LGTM! Route integration follows established patterns.

The import and route mounting for the new file upload functionality are correctly implemented and follow the same pattern as existing routes in the application.

Also applies to: 154-154

src/storage/storageProvider.ts (1)

3-10: Good interface design with proper typing

The interface is well-designed with async methods and optional parameters for extensibility.

src/models/fileMetaData.model.ts (1)

12-57: Well-structured entity with good practices

Good implementation details:

  • Proper use of indexes on frequently queried fields
  • Snake_case column naming for database consistency
  • Automatic timestamp with @CreateDateColumn
  • UUID primary key for better distribution

Comment thread package.json
"axios": "^1.8.1",
"bcryptjs": "^2.4.3",
"bull": "^4.16.5",
"clamav.js": "^0.12.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify security of new dependencies and document ClamAV requirement.

The addition of clamav.js and sharp introduces new security considerations:

  1. clamav.js requires a ClamAV daemon running on port 3310 (as seen in the service code)
  2. sharp is a native module that processes image data

Please verify these packages for known vulnerabilities and document the ClamAV setup requirement:

Also applies to: 50-50


🏁 Script executed:

#!/bin/bash
# Check for known vulnerabilities in the new packages
npm audit --only=prod

# Check specific packages for security advisories
curl -s "https://registry.npmjs.org/clamav.js" | jq '.versions | keys | .[-5:]'
curl -s "https://registry.npmjs.org/sharp" | jq '.versions | keys | .[-5:]'

# Verify latest versions
npm view clamav.js version
npm view sharp version

Length of output: 793


Security verification & documentation needed for clamav.js@^0.12.0 and sharp@^0.34.3

• Both clamav.js and sharp are pinned to their latest published versions.
npm audit --only=prod failed due to a missing lockfile. Please:
– Generate and commit a lockfile (npm i --package-lock-only).
– Re-run vulnerability checks (npm audit --omit=dev or review the npm/GitHub advisories directly).
• Document the ClamAV daemon requirement in your README or deployment docs:
– Default host/port (e.g. localhost:3310).
– Example Docker-Compose service for ClamAV.
• Document Sharp’s native prerequisites (libvips, build tools) or link to Sharp’s official install guide.

🤖 Prompt for AI Agents
In package.json at line 26, the dependencies clamav.js@^0.12.0 and sharp@^0.34.3
are used without a lockfile, causing npm audit to fail. Generate and commit a
package-lock.json by running 'npm i --package-lock-only', then re-run 'npm audit
--omit=dev' to check for vulnerabilities. Additionally, update the README or
deployment documentation to include ClamAV daemon requirements such as default
host and port (localhost:3310), provide an example Docker-Compose service for
ClamAV, and document Sharp's native prerequisites like libvips and build tools
or link to Sharp's official installation guide.

Comment thread package.json Outdated
Comment thread src/controllers/fileUpload.controller.ts Outdated
Comment thread src/models/fileMetaData.model.ts Outdated
Comment thread src/models/fileMetaData.model.ts Outdated
Comment thread src/storage/s3StorageProvider.ts Outdated
Comment thread src/storage/s3StorageProvider.ts Outdated
Comment on lines +25 to +31
async deleteFile(fileKey: string) {
const params = {
Bucket: this.bucketName,
Key: fileKey,
};
await s3.deleteObject(params).promise();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Update to AWS SDK v3 syntax and add return type

-  async deleteFile(fileKey: string) {
+  async deleteFile(fileKey: string): Promise<void> {
     const params = {
       Bucket: this.bucketName,
       Key: fileKey,
     };
-    await s3.deleteObject(params).promise();
+    await this.s3Client.send(new DeleteObjectCommand(params));
   }
📝 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
async deleteFile(fileKey: string) {
const params = {
Bucket: this.bucketName,
Key: fileKey,
};
await s3.deleteObject(params).promise();
}
async deleteFile(fileKey: string): Promise<void> {
const params = {
Bucket: this.bucketName,
Key: fileKey,
};
await this.s3Client.send(new DeleteObjectCommand(params));
}
🤖 Prompt for AI Agents
In src/storage/s3StorageProvider.ts around lines 25 to 31, the deleteFile method
uses AWS SDK v2 syntax and lacks an explicit return type. Update the method to
use AWS SDK v3 syntax by importing and using the DeleteObjectCommand with the S3
client’s send method. Also, add an explicit return type Promise<void> to the
deleteFile method signature.

Comment thread src/storage/s3StorageProvider.ts Outdated
Comment thread src/tasks/cleanUpTask.ts Outdated
Comment thread src/tasks/cleanUpTask.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (1)
src/config/db.ts (1)

33-48: Critical: Missing FileMetadata entity registration.

The FileMetadata entity from src/models/fileMetaData.model.ts is not included in the entities array, which will cause runtime errors when the cleanup task and file upload services try to access this entity.

Add the FileMetadata entity to the entities array:

 entities: [
   User,
   TwoFactorAuth,
   Session,
   EmailVerification,
   WalletVerification,
   MerchantEntity,
   MerchantWebhookEntity,
   MerchantWebhookEventEntity,
   PaymentLink,
   Referral,
   ReferralReward,
   ReferralProgram,
   AuditLog,
   Wallet,
+  FileMetadata,
 ],

You'll also need to add the import:

+import { FileMetadata } from "../models/fileMetaData.model";
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9f8d848 and 363c457.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • package.json (3 hunks)
  • src/config/db.ts (1 hunks)
  • src/controllers/fileUpload.controller.ts (1 hunks)
  • src/models/fileMetaData.model.ts (1 hunks)
  • src/storage/s3StorageProvider.ts (1 hunks)
  • src/storage/storageProvider.ts (1 hunks)
  • src/tasks/cleanUpTask.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/controllers/fileUpload.controller.ts
  • src/storage/s3StorageProvider.ts
  • src/storage/storageProvider.ts
  • package.json
🔇 Additional comments (4)
src/config/db.ts (1)

22-22: LGTM! Export enables cross-module database access.

The change from local to exported constant correctly enables the cleanup task and other modules to access the database connection.

src/tasks/cleanUpTask.ts (1)

51-78: LGTM! Proper reference checking implemented.

The function now correctly checks actual file references in the database and has been appropriately renamed. The query runner usage and error handling are well implemented.

src/models/fileMetaData.model.ts (2)

9-9: LGTM! Good type naming to avoid conflicts.

The StorageProviderType name appropriately avoids conflicts with the StorageProvider interface mentioned in past reviews.


11-57: Well-designed entity with proper indexing and constraints.

The entity design is solid with:

  • Appropriate indexes on userId and category for query optimization
  • Proper column mappings with snake_case database names
  • Sensible defaults for tags array and isWatermarked boolean
  • Good use of TypeORM decorators and nullable fields

The structure supports the file upload and cleanup functionality well.

Comment thread src/tasks/cleanUpTask.ts
@gabito1451

Copy link
Copy Markdown
Author

GM Ser @respp , please kindly review

@respp respp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi @gabito1451, thanks for your PR. You’ve implemented a solid foundation: the FileMetadata model, the storage providers (local and S3), and a well-designed cleanup system. To complete the implementation according the issue, it’s important to register the FileMetadata entity in db.ts and finish the CRUD API (list, retrieve, update, and delete files). Some basic validations like file type and size are also missing. Additionally, I noticed you used atomic commits, which is a great practice, but the commit messages are not descriptive at all. You should follow the Git contribution guidelines for that. By addressing this and the suggestions from the CodeRabbit AI, you’ll be much closer to completing your implementation. The foundation is strong, but it’s not ready to be merged just yet.
image

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d4b75fb and 7381e94.

📒 Files selected for processing (3)
  • package.json (3 hunks)
  • src/app.ts (6 hunks)
  • src/config/db.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • package.json
  • src/config/db.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/app.ts (7)
src/middlewares/ipValidation.middleware.ts (1)
  • validateIpAddress (15-66)
src/middlewares/globalRateLimiter.middleware.ts (1)
  • globalRateLimiter (3-12)
src/middlewares/requestLogger.middleware.ts (1)
  • requestLogger (9-31)
src/middleware/rateLimiter.ts (1)
  • intelligentRateLimiter (24-253)
src/utils/schedular.ts (1)
  • startExpiredSessionCleanupCronJobs (4-12)
src/utils/subscriptionScheduler.ts (1)
  • subscriptionScheduler (59-59)
src/config/auth0Config.ts (1)
  • oauthConfig (1-19)
🪛 GitHub Actions: CI Pipeline
src/app.ts

[error] 1-1: Prettier formatting check failed during 'npm run format:check'. src/app.ts has formatting issues. Run 'prettier --write' to fix.

🔇 Additional comments (1)
src/app.ts (1)

1-174: Fix Prettier formatting to unblock CI.

npm run format:check is failing on this file. Please run Prettier locally (e.g., prettier --write src/app.ts) so the pipeline passes.

Comment thread src/app.ts
Comment on lines +74 to 79
app.use(RateLimitMonitoringService.createRateLimitMonitoringMiddleware() as RequestHandler);
app.use(globalRateLimiter as RequestHandler);
app.use(requestLogger as RequestHandler);
app.use(intelligentRateLimiter);
app.use(rateLimitMonitoringService.createRateLimitMonitoringMiddleware());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove duplicate rate-limit monitoring middleware.

Both RateLimitMonitoringService.createRateLimitMonitoringMiddleware() and rateLimitMonitoringService.createRateLimitMonitoringMiddleware() resolve to the same middleware, so registering them twice will double-log every request (and double any downstream persistence work). Keep just one invocation to avoid duplicate side effects.

🤖 Prompt for AI Agents
In src/app.ts around lines 74 to 79, the rate-limit monitoring middleware is
registered twice
(RateLimitMonitoringService.createRateLimitMonitoringMiddleware() and
rateLimitMonitoringService.createRateLimitMonitoringMiddleware()); remove the
duplicate registration to avoid double-logging and double persistence—delete the
first invocation
(RateLimitMonitoringService.createRateLimitMonitoringMiddleware()) and keep the
existing rateLimitMonitoringService.createRateLimitMonitoringMiddleware() call.

@respp

respp commented Oct 6, 2025

Copy link
Copy Markdown
Contributor

any updates?? @gabito1451

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.

Media Storage Management System

2 participants