docs: Add cloud sync and web access evaluation report#48
Conversation
Created a comprehensive design document evaluating cloud sync architectures, data synchronization mechanisms, authentication, encryption, and a phased implementation plan for adding cloud capabilities to the money2 app. Co-authored-by: Max97k <14903047+Max97k@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive technical evaluation and implementation plan for adding cloud sync and web access to the money2 Android application, proposing a Cloudflare Workers + D1 backend with an offline-first architecture. The review feedback highlights critical design improvements: correcting the database schema to store encrypted data (such as transaction amounts) as TEXT instead of REAL, documenting the architectural trade-offs of client-side decryption (e.g., lack of server-side aggregation), and refining the conflict resolution mechanism by recommending a revision-number approach over server-side arrival time to prevent data loss.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| id TEXT PRIMARY KEY, -- 使用 UUID 取代本地 AutoGenerate Long ID,確保跨裝置唯一性 | ||
| userId TEXT NOT NULL, | ||
| title TEXT, | ||
| amount REAL, |
There was a problem hiding this comment.
There is a mismatch between the proposed database schema in Section 2.2 and the End-to-End Encryption (E2EE) design in Section 3.2.
In Section 3.2, it is stated that sensitive fields such as the transaction amount (amount) will be encrypted on the client side using AES-GCM before being uploaded to the server. However, in the SQLite schema on line 38, amount is defined as REAL.
Since encrypted data is binary or a Base64/Hex-encoded string, it cannot be stored in a REAL (floating-point) column without causing database errors or data corruption. To support E2EE, the amount column in the cloud database schema must be changed to TEXT or BLOB to store the ciphertext.
| amount REAL, | |
| amount TEXT, |
| 為確保敏感的財務資料不被伺服器管理者窺探,應實作端對端加密: | ||
| - 用戶在啟用同步時,需產生或設定一組**主密碼 (Master Password)** 或**恢復金鑰 (Recovery Key)**。 | ||
| - 該金鑰不應上傳至伺服器。利用 Android 的 `EncryptedSharedPreferences` 儲存在本地。 | ||
| - 資料在上傳至 API 之前(例如交易金額、備註等欄位),在客戶端使用 AES-GCM 演算法進行加密。伺服器(D1 或 Firestore)只儲存加密後的字串與 `updatedAt`。 |
There was a problem hiding this comment.
Enabling End-to-End Encryption (E2EE) for fields like amount and category has significant architectural and performance implications that should be highlighted in this evaluation report:
- No Server-Side Aggregation/Filtering: Since the server (Cloudflare Workers / D1) only sees encrypted ciphertexts, it cannot perform queries like
SUM(amount), group bycategory, or filter by specific categories/titles. - Client-Side Overhead: Both the Android app and the Web companion app must download all encrypted records (or a larger date-range subset) and decrypt them locally in memory to compute totals, render charts, or perform searches. For users with large transaction histories, this will increase network payload sizes and client-side CPU/memory usage.
It is recommended to document these trade-offs in Section 3.2 or Section 4, and consider storing non-sensitive metadata (like coarse-grained categories or transaction types) unencrypted if server-side indexing/filtering is deemed necessary, or explicitly accept client-side aggregation as a design constraint.
| - **同步標記 (Sync Markers)**:在每個 Entity(如 `TransactionEntity`, `HoldingEntity`)中加入兩個控制欄位: | ||
| - `updatedAt` (Long): 資料最後修改的時間戳記。 | ||
| - `syncStatus` (Int): 標記資料狀態(0: 已同步, 1: 待新增, 2: 待更新, 3: 待刪除)。 | ||
| - **衝突處理機制 (Conflict Resolution)**:採用 **Last-Write-Wins (LWW, 最後寫入者獲勝)** 原則。當設備嘗試同步資料到雲端時,比對雲端資料庫中的 `updatedAt`。若設備端的 `updatedAt` 較新,則覆蓋雲端資料;若雲端較新,則設備端下載並更新本地資料。為了防止時鐘不同步,推薦使用伺服器端時間作為最終判定標準,或引入單調遞增的修訂號 (Revision Number)。 |
There was a problem hiding this comment.
Using the server-side arrival time as the final standard for Last-Write-Wins (LWW) in an offline-first application can lead to unexpected behavior.
If two devices make offline edits, the device that syncs later will always overwrite the changes of the device that synced earlier, regardless of the actual chronological order of the user's edits.
To resolve this without relying on fragile client-side clocks, it is highly recommended to use a Revision Number (or Sequence/Version ID) approach:
- Each record has a
versioninteger. - When a client updates a record, it increments the
version. - During sync, if the client's base version matches the server's version, the update is accepted and the version is incremented. If they mismatch, a conflict is detected and can be resolved (e.g., prompting the user or merging).
This avoids the pitfalls of both client-side clock skew and server-side sync-order bias.
Adds a new documentation file
docs/cloud_sync_and_web_access_evaluation.mdevaluating architectures, data sync mechanisms, authentication, and a phased implementation plan for adding cloud sync and web access to the money2 app.PR created automatically by Jules for task 6655596512406654254 started by @Max97k