Skip to content

Conversation

@shubham1g5
Copy link
Contributor

@shubham1g5 shubham1g5 commented Oct 30, 2025

This updates the super linter to work correctly for Java files, I have disabled some linters to remove noise as we start implementing lint checks on PRs and we can enable them one by one in future if we feel the need to add additional validation.

Some linters doesn't really support operating just on changed files but scan the entire codebase, I have disabled them too except markdown one as there are not many markdown files in the repo, I have formatted the markdown correctly so that it passes the check and doesn't cause issues on the PR.

I have also formatted a few Java files to induce changes in the PR in a way to demonstrate that it's working correctly for Java files.

Safery Story

  • No functional changes

@coderabbitai
Copy link

coderabbitai bot commented Oct 30, 2025

📝 Walkthrough

Walkthrough

This PR replaces the PNApiSyncWorkerManager/PNApiSyncWorker architecture with a new NotificationsSyncWorkerManager/NotificationsSyncWorker implementation for push-notification synchronization. It adds the new manager and worker classes, updates CommCareApplication to schedule periodic notification syncs at startup, integrates scheduling into PersonalIdManager for sign-in/forget flows, updates CommCareFirebaseMessagingService and PushNotificationViewModel to use the new manager, deletes PNApiSyncWorkerManager and PNApiSyncWorker, and updates CI linting workflow (.github/workflows/linter.yml) to newer actions and super-linter version with targeted PR linting.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant App as CommCareApplication
    participant PM as PersonalIdManager
    participant NSWM as NotificationsSyncWorkerManager
    participant WM as WorkManager
    participant NSW as NotificationsSyncWorker

    User->>App: App starts (onCreate)
    App->>NSWM: schedulePeriodicPushNotificationRetrieval
    NSWM->>WM: enqueueUniquePeriodicWork

    User->>PM: Sign in
    PM->>NSWM: schedulePeriodicPushNotificationRetrievalChecked
    NSWM->>PM: init + check logged in
    NSWM->>WM: Schedule periodic work

    rect rgb(200, 220, 255)
        Note over WM,NSW: Periodic execution (interval-based)
        WM->>NSW: Execute notification sync
        NSW->>NSW: Parse input & route by ACTION
        NSW->>NSW: Execute specific sync (Opportunity/PersonalId/Delivery/Learning)
        NSW->>NSW: Return Result (success/retry/failure)
    end

    User->>PM: Logout/Forget
    PM->>NSWM: cancelPeriodicPushNotificationRetrieval
    NSWM->>WM: Cancel periodic work
Loading
sequenceDiagram
    participant FCM as CommCareFirebaseMessagingService
    participant NSWM as NotificationsSyncWorkerManager
    participant WM as WorkManager
    participant NSW as NotificationsSyncWorker

    FCM->>FCM: onMessageReceived(RemoteMessage)
    FCM->>NSWM: new NotificationsSyncWorkerManager(context, pns, true, true)
    NSWM->>NSWM: Initialize with payload
    FCM->>NSWM: startPNApiSync()

    rect rgb(255, 220, 200)
        Note over NSWM,NSW: Immediate execution (one-time work)
        NSWM->>WM: enqueueUniqueWork(OneTimeWorkRequest)
        WM->>NSW: Execute worker
        NSW->>NSW: Parse and validate input
        NSW->>NSW: Execute sync based on ACTION
        NSW->>NSW: Return Result with payload
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45–60 minutes

  • Areas requiring extra attention:
    • app/src/org/commcare/pn/workermanager/NotificationsSyncWorkerManager.kt — new manager: multiple constructors, scheduling helpers, routing/enqueue logic, backoff and constraints
    • app/src/org/commcare/pn/workers/NotificationsSyncWorker.kt — new CoroutineWorker: four sync paths, retry semantics, connectivity gating, notification raising
    • Deletions: PNApiSyncWorkerManager.kt and PNApiSyncWorker.kt — ensure no remaining references or import residues
    • Integration points: CommCareApplication.onCreate(), PersonalIdManager.completeSignin()/forgetUser(), CommCareFirebaseMessagingService changes, PushNotificationViewModel updates
    • CI workflow: .github/workflows/linter.yml — verify linter inputs and disabled linters are intentional

Possibly related PRs

Suggested labels

High Risk, QA Note, Release Note

Suggested reviewers

  • Jignesh-dimagi
  • OrangeAndGreen

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description is entirely absent—no description was provided by the author. The required template expects sections including Product Description, Technical Summary (with ticket links and design rationale), Feature Flag, Safety Assurance (with safety story, test coverage, and QA plan), and Labels and Review guidance. Without any of this information, reviewers lack critical context about the purpose, design decisions, testing approach, and risk assessment for these substantial changes to the notification synchronization system and linter workflow. A description must be added that addresses the required template sections. At minimum, provide a technical summary explaining the rationale for replacing PNApiSyncWorkerManager with NotificationsSyncWorkerManager, include safety assurance details documenting how the changes were tested, and clarify the scope and intent of the linter workflow updates. Also link to any related tickets or design documents that motivated these changes.
Docstring Coverage ⚠️ Warning Docstring coverage is 11.76% 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
Title Check ✅ Passed The PR title "Update Super Linter" is partially related to the changeset as it accurately refers to a real part of the changes: the .github/workflows/linter.yml file was modified to upgrade super-linter from v5 to v8.2.1. However, the majority of the changeset involves a substantial refactoring of the push notification system, including replacing PNApiSyncWorkerManager with NotificationsSyncWorkerManager, creating new worker classes, and updating multiple service files to use the new notification manager. The title does not capture this primary and most voluminous part of the work, focusing instead on a secondary change.
✨ 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 testLinter

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

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

🧹 Nitpick comments (3)
app/src/org/commcare/pn/workers/NotificationsSyncWorker.kt (1)

70-74: Use a string-typed TypeToken when rehydrating the payload.

We expect this payload to stay Map<String, String> so downstream consumers (e.g. FirebaseMessagingUtil.handleNotification) never see non-string values. Feeding Gson a HashMap<String, Any> type allows it to materialize numbers/booleans as non-string types, which can trip later casts. Please deserialize with a HashMap<String, String> TypeToken instead.

-        if (notificationPayloadJson != null) {
-            val mapType = object : TypeToken<HashMap<String, Any>>() {}.type
-            notificationPayload = Gson().fromJson<HashMap<String, String>>(notificationPayloadJson, mapType)
-        }
+        if (notificationPayloadJson != null) {
+            val mapType = object : TypeToken<HashMap<String, String>>() {}.type
+            notificationPayload = Gson().fromJson(notificationPayloadJson, mapType)
+        }
app/src/org/commcare/pn/workermanager/NotificationsSyncWorkerManager.kt (2)

200-220: Consider safer Map access pattern.

Lines 202 and 213 use .get() which returns a nullable String?. While the containing checks at lines 201 and 212 ensure the key exists, using the safe access operator or non-null assertion would make the null-safety more explicit and prevent potential issues if the code is refactored.

Apply this diff:

 private fun startLearningSyncWorker(notificationPayload: Map<String, String>) {
     if (notificationPayload.containsKey(OPPORTUNITY_ID) && cccCheckPassed(context)) {
-        val opportunityId = notificationPayload.get(OPPORTUNITY_ID)
+        val opportunityId = notificationPayload[OPPORTUNITY_ID]!!
         startWorkRequest(
             notificationPayload,
             SyncAction.SYNC_LEARNING_PROGRESS,
             SyncAction.SYNC_LEARNING_PROGRESS.toString() + "-$opportunityId"
         )
     }
 }

 private fun startDeliverySyncWorker(notificationPayload: Map<String, String>) {
     if (notificationPayload.containsKey(OPPORTUNITY_ID) && cccCheckPassed(context)) {
-        val opportunityId = notificationPayload.get(OPPORTUNITY_ID)
+        val opportunityId = notificationPayload[OPPORTUNITY_ID]!!
         startWorkRequest(
             notificationPayload,
             SyncAction.SYNC_DELIVERY_PROGRESS,
             SyncAction.SYNC_DELIVERY_PROGRESS.toString() + "-$opportunityId"
         )
     }
 }

242-245: Consider using isNotEmpty() for better readability.

Line 242 uses isEmpty() with negation. Using isNotEmpty() would be more idiomatic Kotlin.

Apply this diff:

-        if (!notificationPayload.isEmpty()) {
+        if (notificationPayload.isNotEmpty()) {
             val pnJsonString = Gson().toJson(notificationPayload)
             inputDataBuilder.putString(NOTIFICATION_PAYLOAD, pnJsonString)
         }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 50bf05b and 08da34f.

📒 Files selected for processing (9)
  • .github/workflows/linter.yml (1 hunks)
  • app/src/org/commcare/CommCareApplication.java (4 hunks)
  • app/src/org/commcare/activities/connect/viewmodel/PushNotificationViewModel.kt (3 hunks)
  • app/src/org/commcare/connect/PersonalIdManager.java (3 hunks)
  • app/src/org/commcare/pn/workermanager/NotificationsSyncWorkerManager.kt (1 hunks)
  • app/src/org/commcare/pn/workermanager/PNApiSyncWorkerManager.kt (0 hunks)
  • app/src/org/commcare/pn/workers/NotificationsSyncWorker.kt (1 hunks)
  • app/src/org/commcare/pn/workers/PNApiSyncWorker.kt (0 hunks)
  • app/src/org/commcare/services/CommCareFirebaseMessagingService.java (2 hunks)
💤 Files with no reviewable changes (2)
  • app/src/org/commcare/pn/workermanager/PNApiSyncWorkerManager.kt
  • app/src/org/commcare/pn/workers/PNApiSyncWorker.kt
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: shubham1g5
PR: dimagi/commcare-android#0
File: :0-0
Timestamp: 2025-05-08T11:08:18.530Z
Learning: PR #3048 "Phase 4 Connect PR" introduces a substantial feature called "Connect" to the CommCare Android app, which includes messaging, job management, delivery tracking, payment processing, authentication flows, and learning modules. It follows a modern architecture using Navigation Components with three navigation graphs, segregated business logic in Manager classes, and proper database persistence.
📚 Learning: 2025-05-08T11:08:18.530Z
Learnt from: shubham1g5
PR: dimagi/commcare-android#0
File: :0-0
Timestamp: 2025-05-08T11:08:18.530Z
Learning: PR #3048 "Phase 4 Connect PR" introduces a substantial feature called "Connect" to the CommCare Android app, which includes messaging, job management, delivery tracking, payment processing, authentication flows, and learning modules. It follows a modern architecture using Navigation Components with three navigation graphs, segregated business logic in Manager classes, and proper database persistence.

Applied to files:

  • app/src/org/commcare/pn/workers/NotificationsSyncWorker.kt
  • app/src/org/commcare/connect/PersonalIdManager.java
  • app/src/org/commcare/CommCareApplication.java
  • app/src/org/commcare/services/CommCareFirebaseMessagingService.java
🧬 Code graph analysis (4)
app/src/org/commcare/pn/workermanager/NotificationsSyncWorkerManager.kt (1)
app/src/org/commcare/utils/PushNotificationApiHelper.kt (1)
  • convertPNRecordsToPayload (84-92)
app/src/org/commcare/connect/PersonalIdManager.java (2)
app/src/org/commcare/pn/workermanager/NotificationsSyncWorkerManager.kt (2)
  • schedulePeriodicPushNotificationRetrieval (61-92)
  • cancelPeriodicPushNotificationRetrieval (98-103)
app/src/org/commcare/CommCareApplication.java (1)
  • CommCareApplication (158-1282)
app/src/org/commcare/CommCareApplication.java (1)
app/src/org/commcare/pn/workermanager/NotificationsSyncWorkerManager.kt (1)
  • schedulePeriodicPushNotificationRetrievalChecked (48-55)
app/src/org/commcare/services/CommCareFirebaseMessagingService.java (1)
app/src/org/commcare/pn/workermanager/NotificationsSyncWorkerManager.kt (1)
  • startPNApiSync (142-144)
⏰ 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). (1)
  • GitHub Check: Lint Code Base
🔇 Additional comments (2)
app/src/org/commcare/pn/workermanager/NotificationsSyncWorkerManager.kt (2)

113-136: LGTM!

The secondary constructors properly delegate to the primary constructor and initialize all necessary properties, including the conversion from PushNotificationRecord to payload format.


142-184: LGTM!

The routing logic correctly handles different notification types and the fallback notification sync (lines 179-182) ensures notifications are synced even when no CCC_MESSAGE action is present, which aligns with the stated intent.

Comment on lines 277 to 281
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
NotificationsSyncWorkerManager.schedulePeriodicPushNotificationRetrievalChecked(
CommCareApplication.instance());
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Honor the background-work toggle before queuing periodic PN sync.

HiddenPreferences.shouldDisableBackgroundWork() governs whether we schedule WorkManager jobs throughout this class. Calling schedulePeriodicPushNotificationRetrievalChecked() unconditionally will enqueue a periodic sync even when the user has disabled background work, undermining that preference. Please wrap this call in the same guard (and optionally cancel the work when the preference is off) so the notifications worker follows the existing background-work contract.

-        NotificationsSyncWorkerManager.schedulePeriodicPushNotificationRetrievalChecked(
-                CommCareApplication.instance());
+        if (!HiddenPreferences.shouldDisableBackgroundWork()) {
+            NotificationsSyncWorkerManager.schedulePeriodicPushNotificationRetrievalChecked(
+                    CommCareApplication.instance());
+        } else {
+            NotificationsSyncWorkerManager.cancelPeriodicPushNotificationRetrieval(
+                    CommCareApplication.instance());
+        }

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

🤖 Prompt for AI Agents
In app/src/org/commcare/CommCareApplication.java around lines 277 to 280, the
call to
NotificationsSyncWorkerManager.schedulePeriodicPushNotificationRetrievalChecked(...)
is executed unconditionally and ignores the
HiddenPreferences.shouldDisableBackgroundWork() flag; wrap that scheduling call
in the same guard that protects other WorkManager jobs (i.e., check
HiddenPreferences.shouldDisableBackgroundWork() and only schedule when
background work is enabled), and when the preference indicates background work
is disabled, ensure any existing periodic notification work is cancelled (call
the existing cancel/unschedule method on NotificationsSyncWorkerManager or add
one if missing) so notification sync respects the background-work toggle.

Comment on lines 207 to 202
personalIdSatus = PersonalIdStatus.LoggedIn;
scheduleHeartbeat();
NotificationsSyncWorkerManager.schedulePeriodicPushNotificationRetrieval(CommCareApplication.instance());
CrashUtil.registerUserData();
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Respect background-work disablement before scheduling PN worker.

We already honour HiddenPreferences.shouldDisableBackgroundWork() when wiring other background jobs (form submission, auto-update). Without the same guard here we will enqueue a periodic notifications sync even when the user explicitly disabled background work, defeating that setting. Please gate this call (and add the corresponding HiddenPreferences import) so we skip scheduling whenever background work is turned off, or cancel an existing schedule in that state.

-        NotificationsSyncWorkerManager.schedulePeriodicPushNotificationRetrieval(CommCareApplication.instance());
+        if (!HiddenPreferences.shouldDisableBackgroundWork()) {
+            NotificationsSyncWorkerManager.schedulePeriodicPushNotificationRetrieval(
+                    CommCareApplication.instance());
+        }
📝 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
personalIdSatus = PersonalIdStatus.LoggedIn;
scheduleHeartbeat();
NotificationsSyncWorkerManager.schedulePeriodicPushNotificationRetrieval(CommCareApplication.instance());
CrashUtil.registerUserData();
personalIdSatus = PersonalIdStatus.LoggedIn;
scheduleHeartbeat();
if (!HiddenPreferences.shouldDisableBackgroundWork()) {
NotificationsSyncWorkerManager.schedulePeriodicPushNotificationRetrieval(
CommCareApplication.instance());
}
CrashUtil.registerUserData();
🤖 Prompt for AI Agents
In app/src/org/commcare/connect/PersonalIdManager.java around lines 207 to 210,
add an import for HiddenPreferences and guard the call to
NotificationsSyncWorkerManager.schedulePeriodicPushNotificationRetrieval(CommCareApplication.instance())
so it only runs when !HiddenPreferences.shouldDisableBackgroundWork(); if
background work is disabled, call
NotificationsSyncWorkerManager.cancelPeriodicPushNotificationRetrieval(CommCareApplication.instance())
(or the equivalent cancel method) instead to remove any existing schedule.

*/
@JvmStatic
fun schedulePeriodicPushNotificationRetrievalChecked(context: Context) {
val perosnalIdManager = PersonalIdManager.getInstance()
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

Fix typo in variable name.

The variable name perosnalIdManager should be personalIdManager.

Apply this diff:

-            val perosnalIdManager = PersonalIdManager.getInstance()
-            perosnalIdManager.init(context)
-            if (perosnalIdManager.isloggedIn()) {
+            val personalIdManager = PersonalIdManager.getInstance()
+            personalIdManager.init(context)
+            if (personalIdManager.isloggedIn()) {

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

🤖 Prompt for AI Agents
In app/src/org/commcare/pn/workermanager/NotificationsSyncWorkerManager.kt
around line 50, the local variable is misspelled as `perosnalIdManager`; rename
it to `personalIdManager` and update all references in the same scope to use the
corrected name so the code compiles and reads clearly.

}
}

lateinit var notificationsPayload: ArrayList<Map<String, String>>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Potential UninitializedPropertyAccessException with lateinit var.

The notificationsPayload property is declared as lateinit var but the primary constructor does not initialize it. If code uses the primary constructor and then calls startPNApiSync(), it will crash when trying to iterate over the uninitialized property at line 148.

Consider one of these solutions:

  1. Initialize with an empty list by default:
-    lateinit var notificationsPayload: ArrayList<Map<String, String>>
+    var notificationsPayload: ArrayList<Map<String, String>> = ArrayList()
  1. Add a check in startSyncWorker():
 private fun startSyncWorker(): Boolean {
     var isNotificationSyncScheduled = false
+    if (!::notificationsPayload.isInitialized) {
+        return false
+    }
     for (notificationPayload in notificationsPayload) {
📝 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
lateinit var notificationsPayload: ArrayList<Map<String, String>>
var notificationsPayload: ArrayList<Map<String, String>> = ArrayList()
🤖 Prompt for AI Agents
In app/src/org/commcare/pn/workermanager/NotificationsSyncWorkerManager.kt
around line 106 (property) and line 148 (iteration), the lateinit var
notificationsPayload may be uninitialized causing a Potential
UninitializedPropertyAccessException when startPNApiSync() iterates it; fix by
initializing the property to an empty list (e.g., = ArrayList()) or make it
nullable and guard the iteration (or use ::notificationsPayload.isInitialized)
before iterating so startPNApiSync() never reads an uninitialized value; update
the property declaration and the iteration site accordingly.

@shubham1g5 shubham1g5 force-pushed the testLinter branch 3 times, most recently from 10ed9e5 to 69eeda9 Compare October 30, 2025 08:17
@shubham1g5 shubham1g5 added the skip-integration-tests Skip android tests. label Oct 30, 2025
@shubham1g5
Copy link
Contributor Author

@damagatchi retest this please

@shubham1g5 shubham1g5 changed the title Testing linter [ignore] Update Super Linter Oct 30, 2025
@shubham1g5 shubham1g5 marked this pull request as ready for review October 30, 2025 09:27
@shubham1g5
Copy link
Contributor Author

@damagatchi retest this please

Copy link
Contributor

@conroy-ricketts conroy-ricketts left a comment

Choose a reason for hiding this comment

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

I am very concerned about the readability of the code caused by formatting changes from the linter. Can we verify that this linter follows best/standard practices for writing Java code? I'm open to having a discussion about this with the team or just to hear other people's thoughts

Comment on lines +245 to +246
Thread.setDefaultUncaughtExceptionHandler(
new CommCareExceptionHandler(Thread.getDefaultUncaughtExceptionHandler(), this));
Copy link
Contributor

Choose a reason for hiding this comment

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

This is very interesting. We don't want closing parentheses to be on a new line in scenarios like this? Is that standard practice? For example:

Object.method(
    argument
);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't have strong thoughts on this lint, think we copied this from google checkstyle so I would think it's a standard practice. I do think Kotlin follows it more but is not opposed to us implementing it for Java as such.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd be okay with either here as well. In my personal experience I'm more accustomed to leaving those closing symbols on the same line as the previous. I like that it's a bit more visually compact, and it's difficult for bugs to slip through due to those characters missing (much more likely to be caught as a syntax error) so doesn't seem like it needs to be visually separated.

That being said, if it's more in line with Kotlin standards and we're moving more toward Kotlin anyway then making this change might be nice for consistency.

AndroidClassHasher.registerAndroidClassHashStrategy();

ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
ActivityManager am = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar comment here. Removing that space is standard practice? Doesn't that hinder readability?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a legacy thing where we don't want to change the style to standard because it will cause a lot of formatting changes in our code base.

Comment on lines 364 to 367
PerformanceTuningUtil.updateMaxPrefetchCaseBlock(
PerformanceTuningUtil.guessLargestSupportedBulkCaseFetchSizeFromHeap((long) memoryClass * 1024 * 1024));
PerformanceTuningUtil.guessLargestSupportedBulkCaseFetchSizeFromHeap(
(long)memoryClass * 1024 * 1024));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems a bit strange. Wouldn't something like this be more readable?:

        PerformanceTuningUtil.updateMaxPrefetchCaseBlock(
                PerformanceTuningUtil.guessLargestSupportedBulkCaseFetchSizeFromHeap(
                        (long) memoryClass * 1024 * 1024
                )
        );

I'm open for thoughts here

Comment on lines +668 to +671
public <T extends Persistable> HybridFileBackedSqlStorage<T> getFileBackedUserStorage(String storage,
Class<T> c) {
return new HybridFileBackedSqlStorage<>(storage, c, buildUserDbHandle(), getUserKeyRecordId(),
CommCareApplication.instance().getCurrentApp());
Copy link
Contributor

Choose a reason for hiding this comment

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

This could be a lot more readable too. For example:

Suggested change
public <T extends Persistable> HybridFileBackedSqlStorage<T> getFileBackedUserStorage(String storage,
Class<T> c) {
return new HybridFileBackedSqlStorage<>(storage, c, buildUserDbHandle(), getUserKeyRecordId(),
CommCareApplication.instance().getCurrentApp());
public <T extends Persistable> HybridFileBackedSqlStorage<T> getFileBackedUserStorage(
String storage,
Class<T> c
) {
return new HybridFileBackedSqlStorage<>(
storage,
c,
buildUserDbHandle(),
getUserKeyRecordId(),
CommCareApplication.instance().getCurrentApp()
);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agree, think we might not be enforcing single line arguments in case of multi-line arguments for Java.

@shubham1g5
Copy link
Contributor Author

shubham1g5 commented Oct 31, 2025

@conroy-ricketts think all your suggestions are valid here but think they are probably best taken separately out of scope of this PR. Also think you will be noticing a bunch of these as you work more with the code base and it would be nice to collate a list of suggestions in a doc or Jira ticket that we can decide on as a team.

@shubham1g5
Copy link
Contributor Author

@damagatchi retest this please

Copy link
Contributor

@conroy-ricketts conroy-ricketts left a comment

Choose a reason for hiding this comment

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

Updating my review to non-blocking. I'd like a second set of eyes on this before merging

@conroy-ricketts conroy-ricketts self-requested a review October 31, 2025 12:36
@shubham1g5 shubham1g5 merged commit 16fe4d0 into master Oct 31, 2025
11 checks passed
@shubham1g5 shubham1g5 deleted the testLinter branch October 31, 2025 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-integration-tests Skip android tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants