Skip to content

Adds Task Persistance Layer#3785

Merged
shubham1g5 merged 9 commits into
masterfrom
ccct-2539_data_layer_tasks
Jul 8, 2026
Merged

Adds Task Persistance Layer#3785
shubham1g5 merged 9 commits into
masterfrom
ccct-2539_data_layer_tasks

Conversation

@shubham1g5

@shubham1g5 shubham1g5 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Product Description

https://dimagi.atlassian.net/browse/CCCT-2539
No visible UI changes

Technical Summary

Implements first part of OCS task spec
Stores tasks in DB and migrate current preferences methods to use DB instead.

Safety Assurance

Safety story

Verified locally that all current tasks behavious works as today and the PR doesn't cause any changes in current functionality around tasks

Automated test coverage

Tests are added for new functionality on DB and parse layers.

Labels and Review

  • Do we need to enhance the manual QA test coverage ? If yes, RELEASES.md is updated accordingly
  • Does the PR introduce any major changes worth communicating ? If yes, RELEASES.md is updated accordingly
  • Risk label is set correctly
  • The set of people pinged as reviewers is appropriate for the level of risk of the change

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 15d11568-1e95-4bb1-a2ac-60bcfd79918f

📥 Commits

Reviewing files that changed from the base of the PR and between beb94f9 and 2e6dd2e.

📒 Files selected for processing (14)
  • app/src/org/commcare/activities/StandardHomeActivityUIController.java
  • app/src/org/commcare/android/database/connect/models/ConnectJobPaymentRecord.java
  • app/src/org/commcare/android/database/connect/models/ConnectJobRecord.java
  • app/src/org/commcare/android/database/connect/models/ConnectTaskRecord.kt
  • app/src/org/commcare/connect/database/ConnectTaskUtils.kt
  • app/src/org/commcare/connect/network/connect/models/DeliveryAppProgressResponseModel.kt
  • app/src/org/commcare/connect/network/connect/models/ParsedConnectTask.kt
  • app/src/org/commcare/connect/network/connect/parser/DeliveryAppProgressResponseParser.kt
  • app/src/org/commcare/fragments/connect/ConnectDeliveryProgressFragment.java
  • app/src/org/commcare/models/database/connect/ConnectDatabaseUpgrader.java
  • app/src/org/commcare/models/database/connect/DatabaseConnectOpenHelper.java
  • app/src/org/commcare/preferences/ConnectJobPreferences.kt
  • app/src/org/commcare/utils/JsonExtensions.kt
  • app/src/org/commcare/views/connect/ConnectViewUtils.kt
💤 Files with no reviewable changes (1)
  • app/src/org/commcare/connect/network/connect/models/ParsedConnectTask.kt
👮 Files not reviewed due to content moderation or server errors (13)
  • app/src/org/commcare/activities/StandardHomeActivityUIController.java
  • app/src/org/commcare/android/database/connect/models/ConnectJobRecord.java
  • app/src/org/commcare/android/database/connect/models/ConnectJobPaymentRecord.java
  • app/src/org/commcare/preferences/ConnectJobPreferences.kt
  • app/src/org/commcare/connect/database/ConnectTaskUtils.kt
  • app/src/org/commcare/models/database/connect/DatabaseConnectOpenHelper.java
  • app/src/org/commcare/models/database/connect/ConnectDatabaseUpgrader.java
  • app/src/org/commcare/connect/network/connect/parser/DeliveryAppProgressResponseParser.kt
  • app/src/org/commcare/fragments/connect/ConnectDeliveryProgressFragment.java
  • app/src/org/commcare/views/connect/ConnectViewUtils.kt
  • app/src/org/commcare/utils/JsonExtensions.kt
  • app/src/org/commcare/android/database/connect/models/ConnectTaskRecord.kt
  • app/src/org/commcare/connect/network/connect/models/DeliveryAppProgressResponseModel.kt

📝 Walkthrough

[!WARNING]

Walkthrough skipped

File diffs could not be summarized.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ccct-2539_data_layer_tasks

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.

@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 26.14%. Comparing base (09f6484) to head (9bacba5).
⚠️ Report is 173 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #3785      +/-   ##
============================================
+ Coverage     25.95%   26.14%   +0.19%     
- Complexity     4406     4462      +56     
============================================
  Files           953      954       +1     
  Lines         57334    57383      +49     
  Branches       6823     6830       +7     
============================================
+ Hits          14879    15002     +123     
+ Misses        40623    40545      -78     
- Partials       1832     1836       +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@shubham1g5 shubham1g5 added the skip-integration-tests Skip android tests. label Jul 3, 2026
@shubham1g5 shubham1g5 force-pushed the ccct-2539_data_layer_tasks branch 2 times, most recently from cfc92b7 to 7741e3c Compare July 3, 2026 11:38
@shubham1g5 shubham1g5 force-pushed the ccct-2539_data_layer_tasks branch from 256106e to 7d599a9 Compare July 3, 2026 13:18
@shubham1g5 shubham1g5 changed the base branch from master to connect_db_wiring_change July 3, 2026 13:19
shubham1g5 and others added 5 commits July 3, 2026 19:02
- ConnectTaskRecord: DB model with all fields; fromJson uses correct JSON
  key names (assigned_task_id, task_name, etc.) and parses date_created
  via ConnectDateUtils.parseServerTimestamp
- ConnectDatabaseSchemaManager: bumps to v27, adds connect_tasks table
- ConnectDatabaseUpgrader: adds v27 migration path
- ConnectDateUtils: adds parseServerTimestamp for ISO-8601 timestamps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Legacy relearn-task prefs (isRelearnTaskPending, setRelearnTaskPending,
getRelearnTasksCompletedTimeMs, setRelearnTasksCompletedTime) are
deprecated now that task state is persisted in ConnectTaskRecord.

Adds getTaskModifiedTime / updateTaskModifiedTime backed by
KEY_TASK_LAST_MODIFIED_TIME for ConnectTaskUtils to record when task
state last changed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ConnectTaskUtils provides storeTasks (insert/update/delete to match
incoming payload), hasPendingTask, getPendingTaskOfType,
hasPendingTaskOfType, and shouldShowTasksCompletedMessage — replacing
the equivalent logic that was inlined in ConnectJobRecord.

DeliveryAppProgressResponseParser now builds ConnectTaskRecord directly
via ConnectTaskRecord.fromJson (removing the ParsedConnectTask shim).
DeliveryAppProgressResponseModel.applyToJob calls
ConnectTaskUtils.storeTasks instead of syncRelearnTasksPrefs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ConnectTaskUtilsTest covers storeTasks (insert, update, no-op, delete),
query helpers, and shouldShowTasksCompletedMessage. Uses the real
in-memory Robolectric DB via CommCareTestApplication — no static mocks.

DeliveryAppProgressResponseParserTest covers JSON → ConnectTaskRecord
parsing end-to-end.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@shubham1g5 shubham1g5 force-pushed the ccct-2539_data_layer_tasks branch from 7d599a9 to 106bec4 Compare July 3, 2026 13:36
}
}

fun formatNotificationTime(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

changes in the method are formatting only and can be skipped while review

@shubham1g5 shubham1g5 marked this pull request as ready for review July 3, 2026 13:43
Comment on lines +95 to +111
val task = ConnectTaskRecord()
task.jobUUID = job.jobUUID
task.taskId = json.getString("assigned_task_id")
task.name = json.getString("task_name")
task.description = json.optString("task_description", "")
task.status = json.getString("status")
task.connectChannelId = json.optString("connect_channel_id", "")
task.type = json.optString("task_type", "")
if (json.hasNonNull("due_date")) {
task.dueDate = DateUtils.parseDate(json.getString("due_date"))
}
if (json.hasNonNull("date_created")) {
task.dateCreated = ConnectDateUtils.parseServerTimestamp(
json.getString("date_created"),
) ?: Date()
}
return task

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.

Should these keys be the same constants used on the Record's fields?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

not really, DB level fields and related constants are different from API payload and should not be used inter-changeably.

Base automatically changed from connect_db_wiring_change to master July 6, 2026 04:55
conroy-ricketts
conroy-ricketts previously approved these changes Jul 6, 2026

@conroy-ricketts conroy-ricketts 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.

All looks great to me, would love a second set of eyes before merge

Comment on lines +52 to +53
setRelearnTaskPending(incoming.any { it.status == "assigned" })
resetRelearnTasksCompletedTime()

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.

Since we are migrating from SharedPreferences to a local database, do we still need to store these specific values in preferences?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

These preferences are still in use to provide backward compatibility for some edge cases as currently we can't make sure whether someone has re-synced tasks after taking an update or not, once we release 2.64 these can be removed.

Comment on lines +46 to +49
for (orphan in existing.filter { it.taskId !in incomingIds }) {
storage.remove(orphan)
changed = true
}

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.

Now that orphan tasks are removed from the DB during sync, if the payload stops sending the completed task the banner disappears immediately. In the previous implementation it was kept for up to 6 hours after completion.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Can confirm here that the server payload does retain completed tasks.

Comment on lines +91 to +99
fun shouldShowTasksCompletedMessage(
context: Context,
job: ConnectJobRecord,
): Boolean {
if (hasPendingTask(context, job.jobUUID)) return false
val mostRecent = getMostRecentlyCompletedTask(context, job.jobUUID) ?: return false
val timeElapsed = Date().time - mostRecent.dateModified.time
return timeElapsed < TASKS_COMPLETED_MESSAGE_WINDOW_MS && job.status == ConnectJobRecord.STATUS_DELIVERING
}

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.

ConnectTaskRecord.fromJson parses date_created but not date_modified. The deleted ParsedConnectTask.fromJson did parse it.
This function measures the 6h window from now (dateModified) and not when the worker actually completed it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I am checking with server team if it's possible to get date_modified in the payload (we do not currently) . If they confirm, I will update the parsing to account for date_modified.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Although even without date, the dateModified is written to the db row based on whether a task model has changed in storeTasks so this implementation should still be correct as dateModified is derived locally by comparing the model fields for task and detecting a change. As such the net effect here would be that the completed message banner would appear to the user until 6 hour since they synced a completed task which I think is acceptable behaviour. Thoughts ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I am now parsing date_modified from server payload - 7fe8ea9

task.dueDate = DateUtils.parseDate(json.getString("due_date"))
}
if (json.hasNonNull("date_created")) {
task.dateCreated = ConnectDateUtils.parseServerTimestamp(

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.

Can we use DateUtils.parseDateTime as its achieving same thing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

makes sense - ae89fa6

conroy-ricketts
conroy-ricketts previously approved these changes Jul 7, 2026

@Jignesh-dimagi Jignesh-dimagi 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.

LGTM

@shubham1g5 shubham1g5 merged commit bad2663 into master Jul 8, 2026
10 checks passed
@shubham1g5 shubham1g5 deleted the ccct-2539_data_layer_tasks branch July 8, 2026 11:05
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.

3 participants