Skip to content

Conversation

@chris-bes
Copy link
Contributor

@chris-bes chris-bes commented Oct 2, 2025

Changes:

Fix various sync bugs


Note

Strengthens sync persistence (dependency-ordered writes, granular error surfacing), updates survey response permission APIs, improves Datatrak sync flow/tests, enables streaming in nginx, prevents overlapping scheduled tasks, and updates schemas/SQL.

  • Sync reliability:
    • Order snapshot persistence by FK dependencies via sortModelsByDependencyOrder and use in saveIncomingSnapshotChanges.
    • Make saveCreates/Updates/Deletes resilient with per-record fallbacks and clearer error messages; use updateById.
    • Improve dependency discovery using pg catalogs in getDependencyOrder.
  • Survey response permissions:
    • Switch to model methods surveyResponse.assertCanImport(models, ...) and assertCanSubmit(models, ...) across imports/submissions/resubmissions.
    • Central model now extends base SurveyResponseModel from @tupaia/database.
  • Datatrak Web (offline/sync):
    • Add clientSyncManager.triggerSync/triggerUrgentSync, remove projects-in-sync hook; add project to sync on login/route; close DB connections on unmount.
    • Expand Jest setup/mocks (matchMedia, DB, contexts) and adjust tests (user id/accessPolicy).
  • Infra/ops:
    • Disable nginx proxy buffering for sync-api and datatrak-web-api to support streaming.
    • ScheduledTask: prevent overlapping runs via isRunning flag.
  • Database/SQL:
    • Leaderboard query casing fixes and internal project handling; update related tests.
    • addRecentEntities: validate entities individually and write via SQL; update tests to use real models.
    • buildSyncLookupSelect: simplify params (remove userIds).
  • API/types:
    • Add updated_at_sync_tick to several schemas (e.g., Country) and new task/raw result schemas; adjust enums/req-res schemas.
    • @tupaia/superset-api: add @tupaia/utils dependency.
  • Misc:
    • api-client service subdomains include sync-api consistently.
    • Task filter formatting: adjust due date range calculation and equality handling.

Written by Cursor Bugbot for commit 46f4730. This will update automatically on new commits. Configure here.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @chris-bes, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses various synchronization-related bugs and introduces several enhancements to improve the reliability, performance, and maintainability of the sync process across both the client and server. Key changes include optimizing how sync snapshots are generated for new versus existing projects, bolstering error handling for database batch operations, and refining client-side sync management. Additionally, it prevents concurrent execution of scheduled tasks and improves database dependency ordering for more robust data handling.

Highlights

  • Optimized Sync Snapshots: The central sync manager now intelligently distinguishes between existing and new projects during snapshot creation, performing full syncs only for new projects and incremental syncs for existing ones, significantly improving efficiency.
  • Robust Database Operations: Enhanced error handling for batch create, update, and delete operations in the sync process, allowing individual record retries to pinpoint and report specific failures.
  • Client-Side Sync Refactor: Streamlined client-side sync management by centralizing sync triggering and removing deprecated database effect hooks, leading to a cleaner and more maintainable codebase.
  • Prevented Concurrent Scheduled Tasks: Implemented a mechanism in ScheduledTask to prevent multiple instances of the same task from running concurrently, ensuring data integrity and resource management.
  • Improved Database Dependency Ordering: Updated the SQL query for determining database table dependencies and introduced a utility to sort models accordingly, preventing foreign key constraint issues during data saving.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces several fixes and refactorings related to the sync mechanism. Key changes include:

  • Implementing a more robust sync strategy that performs a full sync for new projects and a delta sync for existing ones.
  • Improving error handling in database save operations to provide more specific error messages, which will greatly aid in debugging.
  • Ensuring database changes are saved in an order that respects foreign key constraints by sorting models based on their dependencies.
  • Preventing concurrent execution of scheduled tasks.
  • Adding cleanup for database connections to prevent resource leaks.

The changes are well-implemented and significantly improve the robustness and debuggability of the sync process. I have a couple of suggestions for further improvement: one to simplify an async call and another to make date filtering logic more robust.

cursor[bot]

This comment was marked as outdated.

@chris-bes chris-bes changed the base branch from rn-1545-remove-user-id to rn-1545-allow-switching-project October 5, 2025 22:56
Copy link
Contributor

@jaskfla jaskfla left a comment

Choose a reason for hiding this comment

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

Neat! Super appreciate this PR 🧡🍪

Only request is the naming convention for the ExcludedFieldsFromSync property; but that’s minuscule so pre-approving. Rest are all optional 😄

Comment on lines 42 to 46
await queryClient.invalidateQueries(['getUser']);
// If the user changes their project, we need to invalidate the entity descendants query so that recent entities are updated if they change back to the previous project without refreshing the page
if (variables.projectId) {
queryClient.invalidateQueries(['entityDescendants']);
queryClient.invalidateQueries(['tasks']);

await queryClient.invalidateQueries(['entityDescendants']);
await queryClient.invalidateQueries(['tasks']);
Copy link
Contributor

Choose a reason for hiding this comment

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

Did these cause issues? 👀

From memory TkDodo (TanStack contributor) had a blog post suggesting that we can “fire and forget” these and let it update in the background


const importSurveyResponsePermissionsChecker = async accessPolicy => {
await models.surveyResponse.assertCanImport(accessPolicy, entitiesBySurveyCode);
await models.surveyResponse.assertCanImport(models, accessPolicy, entitiesBySurveyCode);
Copy link
Contributor

Choose a reason for hiding this comment

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

Keep out of scope for me to do; but if we need to pass models in, it’ll be cleaner to make this a static method SurveyResponseModel.assertCanImport()

Copy link
Contributor

Choose a reason for hiding this comment

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

Bit late in the project for me to say this, but next time don’t hesitate to make me fix my own regressions 😅🙏

Thanks so much for fixing this

Comment on lines 1 to 5
/**
* This is the Jest-sanctioned workaround
* @see https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
*/
Object.defineProperty(window, 'matchMedia', {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice, centralising this is much cleaner 🙏

chris-bes and others added 2 commits October 6, 2025 11:31
… into rn-1545-fix-bugs

# Conflicts:
#	packages/central-server/src/apiV2/import/importStriveLabResults/importStriveLabResults.js
#	packages/central-server/src/permissions/assertions.js
#	packages/central-server/src/tests/apiV2/entities/EditEntity.test.js
#	packages/database/src/core/modelClasses/SurveyResponse/SurveyResponse.js
#	packages/tsutils/src/task/formatFilters.ts
#	packages/types/src/types/models.ts
cursor[bot]

This comment was marked as outdated.

… into rn-1545-fix-bugs

# Conflicts:
#	packages/central-server/src/apiV2/meditrakApp/postChanges.js
cursor[bot]

This comment was marked as outdated.

… into rn-1545-fix-bugs

# Conflicts:
#	packages/central-server/src/tests/apiV2/import/importSurveyResponses/assertCanImportSurveyResponses.test.js
#	packages/database/src/__tests__/modelClasses/User/addRecentEntities.test.js
cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

jaskfla added a commit that referenced this pull request Oct 9, 2025
Base automatically changed from rn-1545-allow-switching-project to rn-1545-epic-datatrak-offline October 21, 2025 22:35
@chris-bes chris-bes merged commit 1fa6e63 into rn-1545-epic-datatrak-offline Oct 21, 2025
6 of 8 checks passed
@chris-bes chris-bes deleted the rn-1545-fix-bugs branch October 21, 2025 22:46
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