Skip to content

fix: Close calculation and sync gaps between mobile and web #209

Description

@nfebe

The mobile app produces different numbers from web for the same account, in two ways. First, it withholds locally-created data from the server: the transaction sync gate refuses to push a transaction while any linked category, party, wallet, or group still lacks a server id (transaction_sync_handler.dart:84-100). The gate itself is correct, but the dependency records are not synced to the server ahead of (or together with) the transaction, so a transaction logged under a not-yet-synced custom category does not reach the server until that dependency happens to sync, and until then anything server-side (stats, the AI) reports it as missing, e.g. a category reads as zero spend. If the dependency never syncs, the gap is permanent. Second, the on-device Reports and Month-in-Review recompute locally instead of reading server stats the way web does, and drift: transfers get counted as spending, the recap can land on an older active month when the current month is empty, and amounts are summed across currencies without conversion.

Constraint: the server (/stats) is the source of truth; mobile should match it, not maintain a second divergent calculation.

Checklist

Synchronization

  • Sync a transaction's dependencies (category, party, wallet, group) to the server before or in the same pass as the transaction, so the gate (transaction_sync_handler.dart:84-100) passes and the transaction reaches the server promptly instead of waiting on an unrelated later sync.
  • Confirm a transaction deferred by the gate is retried once its dependencies sync and is never left permanently local. Add a test for the offline flow: new custom category, then a transaction under it, then sync.

Calculations (align on-device reports with server /stats)

  • Exclude transfer legs (transferId != null) from Reports and Month-in-Review. Web already filters these, and budgets and financial position do too.
  • Anchor Month-in-Review to the current month like web, instead of walking back to the most recent active month (month_in_review_data.dart:68-86).
  • Convert amounts to the primary currency before summing across wallets (report_data.dart).

Acceptance criteria

  • The same account shows matching income and expense totals on web and mobile.
  • A category the user spent in never reads zero on the server side once sync has settled.

Related

  • Reference behavior: useReportData.ts in the web app (trakli/webui)
  • Source of truth: trakli/webservice /api/v1/stats

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions