Thanks to visit codestin.com
Credit goes to github.com

Skip to content

debug inbox #6550

Merged
enkhtuvshinD merged 1 commit intomainfrom
getFileUploadConfigs-debug
Oct 28, 2025
Merged

debug inbox #6550
enkhtuvshinD merged 1 commit intomainfrom
getFileUploadConfigs-debug

Conversation

@uuganaa1007
Copy link
Collaborator

@uuganaa1007 uuganaa1007 commented Oct 28, 2025

Summary by Sourcery

Improve uploadMedia performance and security by adding AWS config caching with TTL and concurrency control, fetch timeouts, and redirect protection, and add debug logging across Facebook integration components.

New Features:

  • Add in-memory cache for AWS upload configurations in uploadMedia with time-based TTL and concurrency control
  • Introduce a manual cache invalidation function for upload configurations

Enhancements:

  • Implement fetch timeout and redirect blocking for secure media uploads to S3
  • Refactor uploadMedia to use cached configs and improve error handling

Chores:

  • Add console.log debug statements in Facebook integration controllers, receiveMessage handler, and GraphQL resolver for tracing

Summary by CodeRabbit

  • Bug Fixes

    • Improved media upload reliability with enhanced error handling and timeout management for network requests to ensure more stable file transfers.
    • Refined upload configuration flow to streamline operations and reduce potential upload failures.
  • Performance

    • Implemented intelligent caching for upload configurations to minimize redundant operations and improve overall system efficiency.

@sourcery-ai
Copy link

sourcery-ai bot commented Oct 28, 2025

Reviewer's Guide

This PR adds a caching layer and concurrency controls to the Facebook media upload utility, enhances the uploadMedia function with abortable fetch requests and null checks, and injects console.log statements across the Facebook integration controllers and resolvers to facilitate inbox debugging.

Sequence diagram for updated media upload with caching and abortable fetch

sequenceDiagram
participant Caller
participant FacebookUtils
participant S3
Caller->>FacebookUtils: uploadMedia(subdomain, url, video)
alt Cache miss or expired
    FacebookUtils->>FacebookUtils: Fetch upload config (concurrency control)
end
FacebookUtils->>S3: createAWS(subdomain)
FacebookUtils->>FacebookUtils: fetch(url) with AbortController (timeout)
alt fetch ok
    FacebookUtils->>S3: s3.upload({Bucket, Key, Body, ...})
    S3-->>FacebookUtils: Location
    FacebookUtils-->>Caller: Location
else fetch fails or config unavailable
    FacebookUtils-->>Caller: null
end
Loading

Class diagram for updated Facebook media upload utility

classDiagram
class UploadConfig {
  +AWS_BUCKET: string
}
class FacebookUtils {
  +cachedUploadConfig: UploadConfig | null
  +isFetchingConfig: boolean
  +lastFetchTime: number
  +CACHE_TTL_MS: number
  +uploadMedia(subdomain: string, url: string, video: boolean)
  +invalidateUploadConfigCache()
}
UploadConfig <.. FacebookUtils: uses
Loading

Class diagram for added debug logging in Facebook integration controllers

classDiagram
class FacebookController {
  +processMessagingEvent()
}
class ReceiveMessage {
  +receiveMessage(models, subdomain, integration, activity)
}
class IntegrationResolver {
  +resolveIntegrationChannel(integration, models)
}
FacebookController --> ReceiveMessage: calls
IntegrationResolver --> FacebookController: logs integration
FacebookController : +console.log(integration)
FacebookController : +console.log(facebookAccounts)
FacebookController : +console.log(activityData)
ReceiveMessage : +console.log(activity)
ReceiveMessage : +console.log(integration)
IntegrationResolver : +console.log(integration)
Loading

File-Level Changes

Change Details Files
Introduce in-memory caching for file upload configurations
  • Define UploadConfig type and cache variables (cachedUploadConfig, isFetchingConfig, lastFetchTime, CACHE_TTL_MS)
  • Fetch configs once per TTL window with concurrency guard
  • Add invalidateUploadConfigCache helper
backend/plugins/frontline_api/src/modules/integrations/facebook/utils.ts
Enhance uploadMedia with abortable fetch, redirect prevention, and null checks
  • Change mediaFile path prefix to 'uploads/' and use 16-char alphanumeric
  • Wrap fetch in AbortController with 10s timeout and block redirects
  • Add null check after cache fetch and return early
  • Convert response to buffer and upload via s3.upload unchanged
backend/plugins/frontline_api/src/modules/integrations/facebook/utils.ts
Add debug console.log statements in Facebook controllers and resolvers
  • Log integration, facebookAccounts, and activityData in processMessagingEvent
  • Log activity and integration in receiveMessage
  • Log integration in custom GraphQL resolver
backend/plugins/frontline_api/src/modules/integrations/facebook/controller/controller.ts
backend/plugins/frontline_api/src/modules/integrations/facebook/controller/receiveMessage.ts
backend/plugins/frontline_api/src/modules/inbox/graphql/resolvers/customResolvers/integration.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link

coderabbitai bot commented Oct 28, 2025

Walkthrough

The PR adds debugging logging to multiple Facebook integration modules, removes an unused import, and introduces an in-memory TTL-based cache for file upload configuration with improved S3 upload error handling and fetch timeout controls via AbortController.

Changes

Cohort / File(s) Summary
Debug logging additions
backend/plugins/frontline_api/src/modules/inbox/graphql/resolvers/customResolvers/integration.ts, backend/plugins/frontline_api/src/modules/integrations/facebook/controller/controller.ts, backend/plugins/frontline_api/src/modules/integrations/facebook/controller/receiveMessage.ts
Added console.log statements for debugging integration objects and function flows (channel resolver, processMessagingEvent, receiveMessage). No control-flow changes.
Import cleanup
backend/plugins/frontline_api/src/modules/integrations/facebook/meta/automation/messages/utils.ts
Removed unused moment import; no behavioral impact as usage was only in commented sections.
Upload config caching & S3 flow refactor
backend/plugins/frontline_api/src/modules/integrations/facebook/utils.ts
Introduced in-memory TTL-based cache for file upload configuration with concurrency control; reworked uploadMedia to use cached config; added 10-second fetch timeout via AbortController; streamlined S3 upload payload; improved error logging; exported invalidateUploadConfigCache() helper.

Sequence Diagram

sequenceDiagram
    participant Client as Client
    participant uploadMedia as uploadMedia()
    participant cache as Upload Config Cache
    participant s3 as AWS S3
    participant mediaUrl as Media URL

    rect rgb(200, 220, 240)
    Note over uploadMedia,cache: Old Flow (per-call fetch)
    Client->>uploadMedia: uploadMedia(url, config)
    uploadMedia->>uploadMedia: getFileUploadConfigs() each call
    uploadMedia->>s3: Upload with config
    end

    rect rgb(220, 240, 200)
    Note over uploadMedia,cache: New Flow (cached config)
    Client->>uploadMedia: uploadMedia(url, config)
    uploadMedia->>cache: Check cache (TTL)
    alt Cache Hit
        cache-->>uploadMedia: Return cached config
    else Cache Miss
        uploadMedia->>uploadMedia: Fetch & cache config
    end
    
    uploadMedia->>mediaUrl: Fetch with AbortController<br/>(10s timeout, no redirect)
    mediaUrl-->>uploadMedia: File stream
    uploadMedia->>s3: Upload (simplified payload)
    s3-->>uploadMedia: Location URL
    uploadMedia-->>Client: Return Location
    
    alt Error
        uploadMedia-->>Client: Log & return null
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

  • backend/plugins/frontline_api/src/modules/integrations/facebook/utils.ts — Verify cache TTL/concurrency implementation, AbortController timeout correctness, S3 payload structure, and null-check placement after config fetch.
  • Cache invalidation entrypoint — Confirm invalidateUploadConfigCache() is exported correctly and callable from intended contexts.
  • Error handling in S3 upload flow — Validate error logging and null-return behavior for fetch/upload failures.

Possibly related PRs

Suggested reviewers

  • Enkhtuvshin0513

Poem

🐰 A cache hops in, TTL wise,
Configs stored, no need to reprise—
S3 uploads now timeout-true,
Abort threads dance their 10-sec debut!
Logs debug where shadows creep,
While rabbits cache their secrets deep. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title Check ⚠️ Warning The PR title "debug inbox" is misleading about the primary change in this changeset. While the PR does include multiple console.log debug statements across several files, the most substantial change is the introduction of a TTL-based caching system for upload configuration in the utils.ts file, which is a significant architectural change that includes concurrency control, timeout handling, and a new public export. The title suggests debugging is the main focus when the core objective is actually refactoring the upload media flow to use cached configuration. This misrepresents what reviewers should expect from the changeset. Consider revising the title to better reflect the primary change, such as "Add caching layer for upload configuration with debug logging" or "Refactor file upload to use cached configuration." This would accurately communicate that the PR introduces a significant caching system while acknowledging the debug statements, helping reviewers understand the true scope of the changes before diving into the code.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch getFileUploadConfigs-debug

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.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • There are a lot of raw console.log calls sprinkled through controllers and resolvers—replace them with a structured logger at the appropriate log level or remove them once debugging is done.
  • The cache TTL logic isn’t actually enforced since lastFetchTime is never updated and isFetchingConfig isn’t used to gate fetches—either update the timestamp and check TTL or remove the unused flags.
  • You added an isFetchingConfig flag for concurrency control but never leverage it to prevent duplicate fetches; implement a wait mechanism or drop the unused flag.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- There are a lot of raw console.log calls sprinkled through controllers and resolvers—replace them with a structured logger at the appropriate log level or remove them once debugging is done.
- The cache TTL logic isn’t actually enforced since lastFetchTime is never updated and isFetchingConfig isn’t used to gate fetches—either update the timestamp and check TTL or remove the unused flags.
- You added an isFetchingConfig flag for concurrency control but never leverage it to prevent duplicate fetches; implement a wait mechanism or drop the unused flag.

## Individual Comments

### Comment 1
<location> `backend/plugins/frontline_api/src/modules/integrations/facebook/utils.ts:114-115` </location>
<code_context>

+type UploadConfig = { AWS_BUCKET: string };
+let cachedUploadConfig: UploadConfig | null = null;
+let isFetchingConfig = false; // Concurrency control
+let lastFetchTime = 0; // Time-based cache invalidation
+const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
+
</code_context>

<issue_to_address>
**issue (bug_risk):** Concurrency control with isFetchingConfig may not prevent race conditions.

A boolean flag may not reliably prevent concurrent fetches. Use a locking mechanism or promise-based solution to ensure only one fetch occurs at a time, with others waiting for completion.
</issue_to_address>

### Comment 2
<location> `backend/plugins/frontline_api/src/modules/integrations/facebook/controller/controller.ts:181` </location>
<code_context>
         ],
       });

+      console.log(integration, ' controller integration');
       if (!integration) {
         debugFacebook(`No integration found for pageId: ${pageId}`);
</code_context>

<issue_to_address>
**suggestion:** Console.log statements added for debugging.

Please remove or conditionally enable these statements to prevent exposing information or cluttering production logs.

Suggested implementation:

```typescript
      if (process.env.NODE_ENV === 'development') {
        // eslint-disable-next-line no-console
        console.log(integration, ' controller integration');
      }

```

```typescript
      if (process.env.NODE_ENV === 'development') {
        // eslint-disable-next-line no-console
        console.log(facebookAccounts, ' controller facebookAccounts');
      }

```
</issue_to_address>

### Comment 3
<location> `backend/plugins/frontline_api/src/modules/integrations/facebook/controller/receiveMessage.ts:22-23` </location>
<code_context>
   activity: Activity,
 ) => {
   try {
+    console.log(activity, 'activity');
+    console.log(integration, 'integration');
+
     debugFacebook(
</code_context>

<issue_to_address>
**🚨 issue (security):** Debugging logs may expose sensitive information.

Sanitize or restrict logged data to avoid exposing sensitive details, particularly in production.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@sonarqubecloud
Copy link

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Caution

Changes requested ❌

Reviewed everything up to 35b4644 in 2 minutes and 1 seconds. Click for details.
  • Reviewed 194 lines of code in 5 files
  • Skipped 0 files when reviewing.
  • Skipped posting 5 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. backend/plugins/frontline_api/src/modules/integrations/facebook/meta/automation/messages/utils.ts:1
  • Draft comment:
    Ensure the removal of the 'moment' import is intentional; verify that no dependent code requires the moment library.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% The comment is asking the PR author to verify that the removal of the moment import is intentional and that no dependent code requires it. This falls under asking the author to double-check things, which is against the rules. The comment does not provide a specific suggestion or point out a specific issue.
2. backend/plugins/frontline_api/src/modules/integrations/facebook/utils.ts:162
  • Draft comment:
    The enhancements in uploadMedia (use of AbortController with timeout and redirect: 'error') are good for security; ensure aborted fetch errors are properly handled and consider logging cache hits to aid debugging.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% The comment appears unnecessary because: 1. Aborted fetch errors are already handled by the catch block that logs all errors 2. The cache implementation already has proper error handling and state management 3. Adding cache hit logging would be a minor enhancement that doesn't fix any actual issues 4. The comment starts with "Ensure that..." which is a red flag per the rules The code could potentially benefit from more specific error handling for aborted requests vs other types of errors. And cache hit metrics could help with monitoring. While those enhancements might be nice-to-have, they aren't critical issues. The current error handling and caching implementation is already robust and production-ready. Delete this comment. It starts with "Ensure that..." which violates the rules, and it suggests enhancements to systems that are already properly implemented.
3. backend/plugins/frontline_api/src/modules/integrations/facebook/utils.ts:196
  • Draft comment:
    The manual cache invalidation function 'invalidateUploadConfigCache' is a useful addition—ensure it is properly invoked when upload configurations change.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% The comment is asking the author to ensure that a specific function is invoked under certain conditions. This falls under the category of asking the author to ensure behavior, which is against the rules. The comment does not provide a specific suggestion or point out a specific issue with the code.
4. backend/plugins/frontline_api/src/modules/integrations/facebook/controller/controller.ts:181
  • Draft comment:
    There's an extra space in the string literal (" controller integration"). Consider removing the leading space, e.g., "controller integration", for clarity.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% This is an extremely minor formatting issue on a debug console.log statement. Console.log statements are typically temporary debugging code and not production code. The space doesn't affect functionality. This seems like unnecessary nitpicking that doesn't improve code quality in any meaningful way. The comment is technically correct - there is an inconsistency in spacing. And consistent formatting can make code more readable. While consistency is good, this is too minor of an issue on temporary debug code to warrant a comment. It creates unnecessary noise in the review. Delete this comment as it's an extremely minor formatting issue on temporary debug code that doesn't meaningfully impact code quality.
5. backend/plugins/frontline_api/src/modules/integrations/facebook/controller/controller.ts:190
  • Draft comment:
    There's an extra leading space in the log message string (' controller facebookAccounts'). Consider removing the leading space for consistency, e.g. use 'controller facebookAccounts'.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% This is an extremely minor stylistic issue about a debug log statement. Console.log statements are typically temporary debugging code and not part of the production codebase. The leading space doesn't affect functionality at all. This seems like unnecessary nitpicking that doesn't improve code quality in any meaningful way. Maybe consistent formatting of debug messages could help with log parsing or readability? Maybe there's a team style guide that specifies log message formatting? Even if there were style guidelines for logs, this is too minor to warrant a PR comment. Console.logs are typically temporary debug code anyway. This comment should be deleted as it focuses on an extremely minor stylistic issue in temporary debug code that doesn't meaningfully impact code quality.

Workflow ID: wflow_2TY3sem9rcf3VFjf

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

_args,
{ models }: IContext,
) {
console.log(integration, 'channel integration');
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove the raw console.log; use a proper logger (or gate it behind a debug flag) to avoid leaking sensitive data in production.

Suggested change
console.log(integration, 'channel integration');

],
});

console.log(integration, ' controller integration');
Copy link
Contributor

Choose a reason for hiding this comment

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

Avoid logging the full integration object with console.log; use a proper debug logger or remove it before production.

Suggested change
console.log(integration, ' controller integration');

const facebookAccounts = await models.FacebookAccounts.getAccount({
_id: integration.accountId,
});
console.log(facebookAccounts, ' controller facebookAccounts');
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove or gate the console.log of facebookAccounts; logging full account details might expose sensitive information.

Suggested change
console.log(facebookAccounts, ' controller facebookAccounts');

text: activity.message?.text || '',
};
debugFacebook(`Processing activity: ${JSON.stringify(activityData)}`);
console.log(activityData, ' controller activityData');
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove the debug console.log for activityData to prevent potential leakage of sensitive information; rely on a proper logging mechanism instead.

Suggested change
console.log(activityData, ' controller activityData');

activity: Activity,
) => {
try {
console.log(activity, 'activity');
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove the console.log for 'activity'; use a dedicated logging library to control debug output in production.

Suggested change
console.log(activity, 'activity');

) => {
try {
console.log(activity, 'activity');
console.log(integration, 'integration');
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove the console.log for 'integration'; avoid logging sensitive objects directly.

Suggested change
console.log(integration, 'integration');

Comment on lines +169 to +172
redirect: 'error', // Prevent redirects that could bypass our validation
});

// response.body → instead use arrayBuffer() to get binary data
const arrayBuffer = await response.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);

const uploadParams = {
Bucket: AWS_BUCKET,
Key: mediaFile,
Body: buffer,
ACL: 'public-read',
ContentDisposition: 'inline',
ContentType: video ? 'video/mp4' : 'image/jpeg',
};

const data = await s3.upload(uploadParams).promise();
return data.Location;
if (!response.ok) throw new Error(`HTTP ${response.status}`);

Check failure

Code scanning / CodeQL

Server-side request forgery Critical

The
URL
of this request depends on a
user-provided value
.
Copy link

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
backend/plugins/frontline_api/src/modules/inbox/graphql/resolvers/customResolvers/integration.ts (1)

48-55: Replace console.log with debug logger and sanitize fields

Logging the whole integration object risks leaking PII/tokens and violates our “Avoid console logs” rule. Use the existing debugFacebook and log only safe identifiers. As per coding guidelines.

Apply:

+import { debugFacebook } from '@/integrations/facebook/debuggers';
@@
-    console.log(integration, 'channel integration');
+    debugFacebook(`channel integration: ${integration?._id} -> channelId=${integration?.channelId || ''}`);
backend/plugins/frontline_api/src/modules/integrations/facebook/controller/controller.ts (1)

181-186: Do not log full integration objects

Swap console.log for debugFacebook and only log safe IDs. As per coding guidelines.

-      console.log(integration, ' controller integration');
+      debugFacebook(`controller integration: ${integration?._id} pageId=${pageId}`);
🧹 Nitpick comments (4)
backend/plugins/frontline_api/src/modules/integrations/facebook/utils.ts (4)

112-117: Cache design: add single-flight to prevent parallel config fetches

isFetchingConfig + current condition allows multiple concurrent fetches when cache is empty/expired. Use a pending promise to dedupe requests.

-type UploadConfig = { AWS_BUCKET: string };
-let cachedUploadConfig: UploadConfig | null = null;
-let isFetchingConfig = false; // Concurrency control
-let lastFetchTime = 0; // Time-based cache invalidation
-const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
+type UploadConfig = {
+  AWS_BUCKET: string;
+  AWS_ACCESS_KEY_ID?: string;
+  AWS_SECRET_ACCESS_KEY?: string;
+  AWS_COMPATIBLE_SERVICE_ENDPOINT?: string;
+  AWS_FORCE_PATH_STYLE?: string | boolean;
+  UPLOAD_SERVICE_TYPE?: string;
+};
+let cachedUploadConfig: UploadConfig | null = null;
+let pendingUploadConfig: Promise<UploadConfig> | null = null; // single-flight
+let lastFetchTime = 0;
+const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes

127-149: Deduplicate TRPC config fetches and harden error handling

Make fetch single-flight and await the same promise; avoid stampede and ensure consistent null handling.

-  if (
-    !cachedUploadConfig ||
-    (Date.now() - lastFetchTime > CACHE_TTL_MS && !isFetchingConfig)
-  ) {
-    try {
-      isFetchingConfig = true;
-      cachedUploadConfig = await sendTRPCMessage({
-        subdomain,
-        pluginName: 'core',
-        method: 'query',
-        module: 'configs',
-        action: 'getFileUploadConfigs',
-        input: {},
-      });
-      lastFetchTime = Date.now();
-    } catch (err) {
-      debugError(`Failed to fetch upload config: ${err.message}`);
-      return null;
-    } finally {
-      isFetchingConfig = false;
-    }
-  }
+  if (!cachedUploadConfig || Date.now() - lastFetchTime > CACHE_TTL_MS) {
+    if (!pendingUploadConfig) {
+      pendingUploadConfig = sendTRPCMessage({
+        subdomain,
+        pluginName: 'core',
+        method: 'query',
+        module: 'configs',
+        action: 'getFileUploadConfigs',
+        input: {},
+      })
+        .then((cfg) => {
+          cachedUploadConfig = cfg as UploadConfig;
+          lastFetchTime = Date.now();
+          return cachedUploadConfig!;
+        })
+        .catch((err) => {
+          debugError(
+            `Failed to fetch upload config: ${
+              err instanceof Error ? err.message : String(err)
+            }`,
+          );
+          throw err;
+        })
+        .finally(() => {
+          pendingUploadConfig = null;
+        });
+    }
+    try {
+      await pendingUploadConfig;
+    } catch {
+      return null;
+    }
+  }

158-189: Reuse S3 client per subdomain; avoid per-call init

createAWS re-fetches configs and instantiates S3 on every upload. Memoize an S3 instance keyed by subdomain/config fingerprint to cut latency and load. Also derive content-type/extension from response headers instead of a boolean flag.

-  const { AWS_BUCKET } = cachedUploadConfig;
+  const { AWS_BUCKET } = cachedUploadConfig;
   try {
-    const s3 = await createAWS(subdomain);
+    const s3 = await createAWS(subdomain); // consider memoizing per subdomain
@@
-      const response = await fetch(url, {
+      const response = await fetch(url, {
         signal: controller.signal,
         redirect: 'error', // Prevent redirects that could bypass our validation
       });
 
       if (!response.ok) throw new Error(`HTTP ${response.status}`);
 
-      const buffer = Buffer.from(await response.arrayBuffer());
+      const contentType =
+        response.headers.get('content-type') || (video ? 'video/mp4' : 'image/jpeg');
+      const ext = (contentType.split('/')[1] || '').split(';')[0] || (video ? 'mp4' : 'jpg');
+      const mediaFile = `uploads/${randomAlphanumeric(16)}.${ext}`;
+      const buffer = Buffer.from(await response.arrayBuffer());
       const data = await s3
         .upload({
           Bucket: AWS_BUCKET,
           Key: mediaFile,
           Body: buffer,
           ACL: 'public-read',
-          ContentType: video ? 'video/mp4' : 'image/jpeg',
+          ContentType: contentType,
         })
         .promise();

195-200: Invalidate pending promise too

Clear the in-flight promise on manual invalidation to avoid resolving stale data.

 export const invalidateUploadConfigCache = () => {
   cachedUploadConfig = null;
   lastFetchTime = 0;
+  pendingUploadConfig = null;
 };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 55cbfcf and 35b4644.

📒 Files selected for processing (5)
  • backend/plugins/frontline_api/src/modules/inbox/graphql/resolvers/customResolvers/integration.ts (1 hunks)
  • backend/plugins/frontline_api/src/modules/integrations/facebook/controller/controller.ts (3 hunks)
  • backend/plugins/frontline_api/src/modules/integrations/facebook/controller/receiveMessage.ts (1 hunks)
  • backend/plugins/frontline_api/src/modules/integrations/facebook/meta/automation/messages/utils.ts (0 hunks)
  • backend/plugins/frontline_api/src/modules/integrations/facebook/utils.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • backend/plugins/frontline_api/src/modules/integrations/facebook/meta/automation/messages/utils.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Write concise, technical TypeScript code
Use functional and declarative programming patterns; avoid classes
Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
Avoid console logs
Always use absolute paths for imports
Use TypeScript for all code (no .js/.jsx)
Prefer interfaces over types for object shapes
Avoid enums; use maps instead
Use the function keyword for pure functions
Avoid unnecessary curly braces in simple conditionals; use concise syntax

Files:

  • backend/plugins/frontline_api/src/modules/integrations/facebook/controller/controller.ts
  • backend/plugins/frontline_api/src/modules/inbox/graphql/resolvers/customResolvers/integration.ts
  • backend/plugins/frontline_api/src/modules/integrations/facebook/controller/receiveMessage.ts
  • backend/plugins/frontline_api/src/modules/integrations/facebook/utils.ts
🧬 Code graph analysis (4)
backend/plugins/frontline_api/src/modules/integrations/facebook/controller/controller.ts (1)
backend/plugins/frontline_api/src/modules/inbox/graphql/resolvers/customResolvers/conversation.ts (1)
  • integration (26-34)
backend/plugins/frontline_api/src/modules/inbox/graphql/resolvers/customResolvers/integration.ts (1)
backend/plugins/frontline_api/src/modules/inbox/graphql/resolvers/customResolvers/conversation.ts (1)
  • integration (26-34)
backend/plugins/frontline_api/src/modules/integrations/facebook/controller/receiveMessage.ts (1)
backend/plugins/frontline_api/src/modules/inbox/graphql/resolvers/customResolvers/conversation.ts (1)
  • integration (26-34)
backend/plugins/frontline_api/src/modules/integrations/facebook/utils.ts (1)
backend/plugins/frontline_api/src/modules/inbox/utils.ts (1)
  • debugError (7-7)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Sourcery review
  • GitHub Check: frontline_api-ci
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
backend/plugins/frontline_api/src/modules/integrations/facebook/utils.ts (1)

151-156: Keep, but narrow log message

Null-guard is good. Minor: ensure consistent error level and message phrasing; current log is fine. No change required.

Comment on lines 187 to 193
const facebookAccounts = await models.FacebookAccounts.getAccount({
_id: integration.accountId,
});
console.log(facebookAccounts, ' controller facebookAccounts');

if (!facebookAccounts) {
debugFacebook(
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Avoid logging full account documents

Accounts may include tokens. Log only the account _id. As per coding guidelines.

-      console.log(facebookAccounts, ' controller facebookAccounts');
+      debugFacebook(`controller facebookAccount: ${facebookAccounts?._id}`);
🤖 Prompt for AI Agents
In
backend/plugins/frontline_api/src/modules/integrations/facebook/controller/controller.ts
around lines 187 to 193, a console.log prints the entire facebookAccounts
document (which may include sensitive tokens); remove that full-document log and
replace it with a safe log that only emits the account _id (e.g., use
debugFacebook or processLogger to log facebookAccounts?._id or
integration.accountId), ensuring you never print token fields or other sensitive
properties and handle null/undefined safely.

Comment on lines 228 to 232
debugFacebook(`Processing activity: ${JSON.stringify(activityData)}`);
console.log(activityData, ' controller activityData');

await receiveMessage(models, subdomain, integration, activityData);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Replace raw activity dump with sanitized debug log

Large objects in logs increase risk; keep only essentials. As per coding guidelines.

-      console.log(activityData, ' controller activityData');
+      debugFacebook(
+        `controller activityData: from=${activityData.from.id} recipient=${activityData.recipient.id} ts=${activityData.timestamp.toISOString()}`
+      );
🤖 Prompt for AI Agents
In
backend/plugins/frontline_api/src/modules/integrations/facebook/controller/controller.ts
around lines 228 to 232, replace the raw JSON dump and console.log of
activityData with a sanitized debug log that extracts only essential fields
(e.g., sender id, recipient id, timestamp, message text/type, and any attachment
metadata) and omits sensitive or large payloads; remove console.log and use
debugFacebook to log a compact, structured message (avoid JSON.stringify of the
whole object), and if additional detail is needed include a debug-only flag or a
size-limited serialization function to truncate large fields.

Comment on lines +22 to +24
console.log(activity, 'activity');
console.log(integration, 'integration');

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Remove raw console logs; use debugFacebook with redaction

Avoid console.log of full activity/integration objects. Log minimal, non-sensitive fields via debugFacebook. As per coding guidelines.

@@
-    console.log(activity, 'activity');
-    console.log(integration, 'integration');
+    debugFacebook(
+      `activity: from=${activity?.from?.id} recipient=${activity?.recipient?.id} mid=${activity?.channelData?.message?.mid || activity?.channelData?.postback?.mid || ''}`
+    );
+    debugFacebook(`integration: ${integration?._id} erxesApiId=${integration?.erxesApiId || ''}`);

Run to ensure no stray console logs remain:


🏁 Script executed:

#!/bin/bash
rg -nP --type=ts --type=tsx -C1 'console\.(log|warn|error)\(' backend/plugins/frontline_api/src/modules

Length of output: 27


🏁 Script executed:

#!/bin/bash
# Check the exact content at lines 22-24 in the target file
echo "=== Target file content (lines 20-30) ==="
sed -n '20,30p' backend/plugins/frontline_api/src/modules/integrations/facebook/controller/receiveMessage.ts

echo ""
echo "=== Checking for debugFacebook import/availability ==="
head -30 backend/plugins/frontline_api/src/modules/integrations/facebook/controller/receiveMessage.ts

echo ""
echo "=== Sweeping for console.* in the module (corrected) ==="
rg -nP --type=ts -C1 'console\.(log|warn|error)\(' backend/plugins/frontline_api/src/modules/integrations/facebook/

Length of output: 9374


Remove raw console logs; use debugFacebook with redaction

Lines 22–23 log full activity and integration objects, exposing sensitive data. Replace with debugFacebook calls extracting only non-sensitive fields per coding guidelines.

  try {
-   console.log(activity, 'activity');
-   console.log(integration, 'integration');
+   debugFacebook(
+     `activity: from=${activity?.from?.id} recipient=${activity?.recipient?.id} mid=${activity?.channelData?.message?.mid || activity?.channelData?.postback?.mid || ''}`
+   );
+   debugFacebook(`integration: ${integration?._id} erxesApiId=${integration?.erxesApiId || ''}`);

Also address console.log at lines 62 and 130 in the same file.

Committable suggestion skipped: line range outside the PR's diff.

@enkhtuvshinD enkhtuvshinD merged commit 1c10fea into main Oct 28, 2025
9 of 11 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Nov 6, 2025
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