feat(sync): S3-compatible cloud backup sync#1741
Conversation
FTS5 shadow tables carry a real CREATE TABLE sql in sqlite_master and cannot be written by a column-copy INSERT, raising "table X may not be modified". Exclude virtual tables and their <vtab>_* shadow tables by name prefix; the external-content FTS index is rebuilt by triggers when the content table rows are imported.
Add an optional cloud layer on top of the existing local zip backup so data can move between machines. Uploads the latest local backup to an S3-compatible bucket (Cloudflare R2 / MinIO / AWS S3 / B2) and pulls the latest one back, reusing the existing import flow. - CloudStorageService wraps @aws-sdk/client-s3 (path-style, region auto) - Credentials stored via safeStorage; secret never returned to renderer - Cloud config is machine-local: stripped from backups, preserved on import, so a pull never clobbers local credentials - New manual buttons in Data settings: save / test / upload / pull
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (14)
✅ Files skipped from review due to trivial changes (7)
🚧 Files skipped from review as they are similar to previous changes (5)
📝 WalkthroughWalkthroughThis PR implements a complete S3-compatible cloud backup synchronization feature alongside a critical fix for FTS5 shadow table handling in incremental imports. The cloud sync adds manual upload/download operations with encrypted credential storage, while the import fix prevents SQLite modification errors on virtual tables. ChangesCloud Sync (S3-compatible) Feature
FTS5 Shadow Table Import Fix
Sequence Diagram(s)sequenceDiagram
participant User as User/DataSettings.vue
participant SyncStore as sync Store
participant SyncClient as SyncClient<br/>(Renderer)
participant IPC as Main IPC Route
participant ConfigPresenter as ConfigPresenter
participant SyncPresenter as SyncPresenter
participant S3 as S3-Compatible<br/>Endpoint
User->>User: Save cloud config<br/>(endpoint, bucket, etc.)
User->>SyncStore: saveCloudConfig(config)
SyncStore->>SyncClient: setCloudConfig(input)
SyncClient->>IPC: bridge route<br/>syncSetCloudConfigRoute
IPC->>ConfigPresenter: setCloudSyncConfig(config)<br/>encrypt & store secret
ConfigPresenter-->>IPC: CloudSyncConfigView
IPC-->>SyncClient: result
SyncClient-->>SyncStore: return view
SyncStore-->>User: success toast
User->>SyncStore: testCloudConnection()
SyncStore->>SyncClient: testCloudConnection()
SyncClient->>IPC: syncTestCloudRoute
IPC->>SyncPresenter: testCloudConnection()
SyncPresenter->>S3: ListObjectsV2 (probe)
S3-->>SyncPresenter: success/error
SyncPresenter-->>IPC: CloudSyncResult
IPC-->>SyncClient: result
SyncClient-->>SyncStore: return
SyncStore-->>User: success/error toast
User->>SyncStore: uploadLatestBackupToCloud()
SyncStore->>SyncClient: uploadToCloud()
SyncClient->>IPC: syncUploadToCloudRoute
IPC->>SyncPresenter: uploadLatestBackupToCloud()
SyncPresenter->>SyncPresenter: get resolved config<br/>(decrypt secret)
SyncPresenter->>SyncPresenter: build S3 client
SyncPresenter->>SyncPresenter: read latest local zip
SyncPresenter->>S3: PutObjectCommand<br/>(backup-*.zip)
S3-->>SyncPresenter: upload complete
SyncPresenter-->>IPC: CloudSyncResult
IPC->>IPC: recordSettingsActivity<br/>(backup created)
IPC-->>SyncClient: result
SyncClient-->>SyncStore: return
SyncStore-->>User: success toast
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
🟡 Minor comments (33)
src/main/presenter/configPresenter/index.ts-1922-1941 (1)
1922-1941:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winDon’t derive
hasSecretfrom ciphertext presence alone.If decryption fails in Lines 1927-1932, Line 1939 still reports
hasSecret: truejust because the wrapped blob exists. The renderer will keep masking the field even though sync can no longer authenticate. Base this flag on successful decryption, or surface a separate invalid-secret state.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/presenter/configPresenter/index.ts` around lines 1922 - 1941, The getCloudSyncConfig() currently sets hasSecret based only on presence of the stored blob, which can be false-positive if decryption failed in getCloudSyncSecret(); change the logic so hasSecret reflects successful decryption: update getCloudSyncSecret() to return null (or an empty string) on failure and/or expose a boolean (e.g., return { secret: string|null, valid: boolean }), then in getCloudSyncConfig() call getCloudSyncSecret() (or check the returned valid flag) and set hasSecret = true only when decryption succeeded; alternatively add a distinct flag like hasValidSecret/invalidSecret to surface the failed-decryption state to the renderer. Ensure you update references to CLOUD_SYNC_SECRET_KEY, getCloudSyncSecret, and getCloudSyncConfig accordingly.src/renderer/src/i18n/da-DK/sync.json-4-7 (1)
4-7:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate new cloud sync messages in
da-DK/sync.json.The added cloud success/error messages are English, so Danish users will see non-localized toast content.
Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/da-DK/sync.json` around lines 4 - 7, The new cloud sync message values (keys cloudConnected, cloudUploaded, cloudPulled and the similar entries around lines 22-27) are still in English; replace their values with Danish translations so Danish users see localized toast text—locate the entries for cloudConnected, cloudUploaded, cloudPulled (and the duplicate group referenced at lines ~22-27) in da-DK/sync.json and update the string values to Danish equivalents, keeping the same keys unchanged.src/renderer/src/i18n/da-DK/settings.json-323-342 (1)
323-342:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize the new
cloudSyncstrings forda-DK.The newly added Danish locale block is currently English, which causes mixed-language UI for Danish users.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/da-DK/settings.json` around lines 323 - 342, The da-DK locale block for the cloudSync keys remains in English; translate each key value in the diff (e.g., "title", "description", "endpoint", "bucket", "region", "prefix", "accessKeyId", "secretAccessKey", "secretConfigured", "safeStorageUnavailable", "save", "test", "upload", "pull", "savedTitle", "testSuccessTitle", "testFailedTitle", "uploadSuccessTitle", "uploadFailedTitle", "pullSuccessTitle") into Danish and replace the English strings in the existing settings.json cloudSync section so the Danish UI shows fully localized text.src/renderer/src/i18n/de-DE/settings.json-453-472 (1)
453-472:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize the new
cloudSyncblock forde-DE.These new strings are English in the German locale file, leading to inconsistent language in the settings UI.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/de-DE/settings.json` around lines 453 - 472, The new cloudSync block in the de-DE locale still contains English strings; translate each key (e.g., "title", "description", "endpoint", "bucket", "region", "prefix", "accessKeyId", "secretAccessKey", "secretConfigured", "safeStorageUnavailable", "save", "test", "upload", "pull", "savedTitle", "testSuccessTitle", "testFailedTitle", "uploadSuccessTitle", "uploadFailedTitle", "pullSuccessTitle") into German and replace the English values in src/renderer/src/i18n/de-DE/settings.json so the settings UI displays German text for the Cloud Sync (S3-compatible) section.src/renderer/src/i18n/de-DE/sync.json-4-7 (1)
4-7:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate the new cloud sync toast/error strings in
de-DE/sync.json.These entries are currently English, so cloud sync feedback will appear in mixed language for German users.
Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/de-DE/sync.json` around lines 4 - 7, The German locale file contains English messages for the cloud sync keys "cloudConnected", "cloudUploaded", and "cloudPulled" (and duplicate/related entries later in the same file); replace them with proper German translations — e.g. "cloudConnected": "Cloud-Verbindung erfolgreich", "cloudUploaded": "In die Cloud hochgeladen", "cloudPulled": "Neueste Sicherung aus der Cloud heruntergeladen" — and scan the rest of the same file for the similar English entries (the ones referenced as also applies to 22-27) and translate them consistently.src/renderer/src/i18n/es-ES/sync.json-4-6 (1)
4-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize cloud sync success/error strings in
es-ES.These newly added messages are English, which will produce mixed-language sync notifications/errors for Spanish users. Please translate them to Spanish for locale consistency.
Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/es-ES/sync.json` around lines 4 - 6, The three sync notification strings cloudConnected, cloudUploaded, and cloudPulled are still in English; replace their values with Spanish translations (e.g., "Conexión con la nube exitosa", "Subido a la nube", "Se descargó la copia de seguridad más reciente desde la nube") and make the same replacements for the duplicate entries later in the file (the other set of cloud sync keys present around lines 22-27) so the es-ES locale contains only Spanish text for these keys.src/renderer/src/i18n/es-ES/settings.json-452-472 (1)
452-472:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate the new
cloudSynclabels/messages to Spanish.This
es-ESblock is currently English-only, so Spanish users will see mixed-language UI in Settings. Please localize the fullcloudSyncsection in this locale file.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/es-ES/settings.json` around lines 452 - 472, The cloudSync section contains English strings; translate every key under "cloudSync" into Spanish so the UI is fully localized for es-ES. Specifically update the values for cloudSync.title, cloudSync.description, cloudSync.endpoint, cloudSync.bucket, cloudSync.region, cloudSync.prefix, cloudSync.accessKeyId, cloudSync.secretAccessKey, cloudSync.secretConfigured, cloudSync.safeStorageUnavailable, cloudSync.save, cloudSync.test, cloudSync.upload, cloudSync.pull, cloudSync.savedTitle, cloudSync.testSuccessTitle, cloudSync.testFailedTitle, cloudSync.uploadSuccessTitle, cloudSync.uploadFailedTitle and cloudSync.pullSuccessTitle to appropriate Spanish phrases while keeping the keys unchanged.src/renderer/src/i18n/fr-FR/settings.json-389-409 (1)
389-409:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate
cloudSynclabels/messages in the fr-FR bundleAt Line 390–409, all newly added
cloudSyncstrings are English. Please provide French translations so the settings page remains fully localized.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/fr-FR/settings.json` around lines 389 - 409, The fr-FR bundle's cloudSync section contains English strings; update each key under "cloudSync" (e.g., "title", "description", "endpoint", "bucket", "region", "prefix", "accessKeyId", "secretAccessKey", "secretConfigured", "safeStorageUnavailable", "save", "test", "upload", "pull", "savedTitle", "testSuccessTitle", "testFailedTitle", "uploadSuccessTitle", "uploadFailedTitle", "pullSuccessTitle") with proper French translations so the settings page is fully localized while preserving the same keys and JSON structure.src/renderer/src/i18n/fa-IR/settings.json-389-409 (1)
389-409:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize
cloudSyncstrings for the fa-IR bundleAt Line 390–409, the newly added
cloudSyncvalues are still English. In Persian UI this will render mixed-language settings and toasts.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/fa-IR/settings.json` around lines 389 - 409, The cloudSync localization block still contains English values; update the "cloudSync" object keys (title, description, endpoint, bucket, region, prefix, accessKeyId, secretAccessKey, secretConfigured, safeStorageUnavailable, save, test, upload, pull, savedTitle, testSuccessTitle, testFailedTitle, uploadSuccessTitle, uploadFailedTitle, pullSuccessTitle) with Persian translations so the fa-IR bundle is fully localized; ensure translations preserve meaning and placeholders (if any) and follow existing Persian phrasing style used elsewhere in the file.src/renderer/src/i18n/fr-FR/sync.json-4-6 (1)
4-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize new cloud sync messages in fr-FR
At Line 4–6 and Line 22–27, cloud sync success/error messages are still English. These should be translated to French for consistent locale behavior.
Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/fr-FR/sync.json` around lines 4 - 6, Translate the English cloud sync strings to French by replacing the values for the keys cloudConnected, cloudUploaded, and cloudPulled with appropriate French text; also locate and translate the other cloud sync-related keys in the same locale JSON (the remaining cloud success/error messages) so all cloud sync messages are localized to fr-FR. Ensure you only change the string values (keep the JSON keys intact) and preserve punctuation/formatting consistent with other entries in the file.src/renderer/src/i18n/fa-IR/sync.json-4-6 (1)
4-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winNew cloud sync success/error messages are not localized in fa-IR
At Line 4–6 and Line 22–27, the new cloud sync messages are English. These should be translated to Persian to avoid mixed-language sync notifications/errors.
Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/fa-IR/sync.json` around lines 4 - 6, The fa-IR localization file contains English strings for new cloud sync messages—update the JSON values for the keys "cloudConnected", "cloudUploaded", "cloudPulled" and the other cloud sync success/error keys later in the file (the new cloud-related messages at lines 22–27) with proper Persian translations; preserve the existing JSON keys, punctuation and comma placement so only the string values change, and ensure wording is idiomatic Persian and consistent with other fa-IR entries.src/renderer/src/i18n/it-IT/sync.json-4-6 (1)
4-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate cloud sync status/error strings in Italian sync locale.
Line 4-Line 6 and Line 22-Line 27 are English in
it-IT/sync.json, so Italian users will see untranslated operation feedback.Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/it-IT/sync.json` around lines 4 - 6, The Italian locale file has untranslated English values for the cloud sync keys; update the values (not the keys) for "cloudConnected", "cloudUploaded", "cloudPulled" in src/renderer/src/i18n/it-IT/sync.json to proper Italian equivalents and likewise translate the subsequent English strings in the same file around lines 22–27 (keep the JSON keys intact, only replace the English text with Italian translations).src/renderer/src/i18n/ko-KR/settings.json-389-409 (1)
389-409:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate new
cloudSyncsettings strings for Korean locale.Line 390-Line 409 are English in
ko-KR/settings.json, causing mixed-language UX in the new cloud sync settings section.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/ko-KR/settings.json` around lines 389 - 409, The ko-KR locale has untranslated English strings under the "cloudSync" object (keys like "title", "description", "endpoint", "bucket", "region", "prefix", "accessKeyId", "secretAccessKey", "secretConfigured", "safeStorageUnavailable", "save", "test", "upload", "pull", "savedTitle", "testSuccessTitle", "testFailedTitle", "uploadSuccessTitle", "uploadFailedTitle", "pullSuccessTitle"); replace each English value with the correct Korean translation so the entire "cloudSync" section in src/renderer/src/i18n/ko-KR/settings.json is fully localized and consistent with surrounding entries.src/renderer/src/i18n/ko-KR/sync.json-4-6 (1)
4-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize cloud sync messages in Korean sync resource.
The new cloud-related success and error messages are still English (Line 4-Line 6, Line 22-Line 27), so Korean users will get partial untranslated feedback.
Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/ko-KR/sync.json` around lines 4 - 6, Translate the English cloud sync strings in the Korean resource: replace the values for "cloudConnected", "cloudUploaded", and "cloudPulled" with their proper Korean translations and also localize the other cloud-related success/error message entries around lines 22-27 (the additional cloud_* keys) so all cloud sync messages in src/renderer/src/i18n/ko-KR/sync.json are fully translated into Korean while keeping the original JSON keys intact.src/renderer/src/i18n/ja-JP/settings.json-389-409 (1)
389-409:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize
cloudSyncsection for Japanese UI.The newly added block (Line 390-Line 409) is English in
ja-JP/settings.json, which breaks locale consistency in the settings page and cloud sync toasts.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/ja-JP/settings.json` around lines 389 - 409, The cloudSync locale block is still in English; translate every key under "cloudSync" (title, description, endpoint, bucket, region, prefix, accessKeyId, secretAccessKey, secretConfigured, safeStorageUnavailable, save, test, upload, pull, savedTitle, testSuccessTitle, testFailedTitle, uploadSuccessTitle, uploadFailedTitle, pullSuccessTitle) into natural Japanese and replace the English strings so the ja-JP/settings.json remains fully localized; keep keys unchanged and preserve punctuation/formatting (e.g., parentheses) and meaning (e.g., "S3-compatible", "leave blank to keep") when providing the Japanese strings.src/renderer/src/i18n/ja-JP/sync.json-4-6 (1)
4-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate cloud sync outcome/error messages in
ja-JP/sync.json.Line 4-Line 6 and Line 22-Line 27 should be Japanese to keep operation feedback fully localized.
Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/ja-JP/sync.json` around lines 4 - 6, Replace the English values for the JSON keys cloudConnected, cloudUploaded, and cloudPulled with Japanese translations (suggestions: "クラウド接続に成功しました", "クラウドへアップロードしました", "クラウドから最新のバックアップを取得しました") and likewise translate all English strings in the JSON block on lines 22-27 to Japanese so feedback is fully localized; locate these keys (cloudConnected, cloudUploaded, cloudPulled and the entries in the 22-27 block) and update their value strings accordingly.src/renderer/src/i18n/it-IT/settings.json-452-472 (1)
452-472:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize new
cloudSynclabels/messages for Italian locale.Lines 453-472 are currently English in the
it-ITresource, which will show mixed-language UI in Italian settings and toast titles.💡 Suggested patch shape
- "title": "Cloud Sync (S3-compatible)", + "title": "Sincronizzazione cloud (compatibile S3)", ... - "test": "Test Connection", + "test": "Testa connessione", ... - "uploadSuccessTitle": "Upload succeeded", + "uploadSuccessTitle": "Caricamento riuscito"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/it-IT/settings.json` around lines 452 - 472, The Italian locale file contains untranslated English strings under the cloudSync object (keys: "cloudSync", and its children "title", "description", "endpoint", "bucket", "region", "prefix", "accessKeyId", "secretAccessKey", "secretConfigured", "safeStorageUnavailable", "save", "test", "upload", "pull", "savedTitle", "testSuccessTitle", "testFailedTitle", "uploadSuccessTitle", "uploadFailedTitle", "pullSuccessTitle"); translate each of these values into Italian and replace the English text so the UI and toast titles are fully localized in it-IT while keeping the key names unchanged. Ensure translations are concise and context-appropriate for settings and toast messages.src/renderer/src/i18n/ms-MY/settings.json-452-473 (1)
452-473:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize the new
cloudSyncstrings forms-MY.Line 453-Line 472 are still English in the Malay locale file, so the new cloud sync UI will render mixed-language text.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/ms-MY/settings.json` around lines 452 - 473, The ms-MY locale is missing Malay translations for the new cloudSync section: find the "cloudSync" object in src/renderer/src/i18n/ms-MY/settings.json and replace the English values for keys like "title", "description", "endpoint", "bucket", "region", "prefix", "accessKeyId", "secretAccessKey", "secretConfigured", "safeStorageUnavailable", "save", "test", "upload", "pull", "savedTitle", "testSuccessTitle", "testFailedTitle", "uploadSuccessTitle", "uploadFailedTitle", and "pullSuccessTitle" with appropriate Malay translations while keeping the keys unchanged and preserving JSON structure/escaping.src/renderer/src/i18n/ms-MY/sync.json-3-6 (1)
3-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate cloud sync status/error messages in
ms-MYlocale.Line 4-Line 6 and Line 22-Line 27 are English-only, which will show inconsistent language in Malay sync notifications and errors.
Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/ms-MY/sync.json` around lines 3 - 6, Translate the English sync messages in the Malay locale by replacing the values for the keys "cloudConnected", "cloudUploaded", and "cloudPulled" with proper Malay translations (matching the style of "importComplete"), and also translate the remaining English-only sync/status strings found in the same file block (lines 22-27) to Malay so all sync notifications/errors are consistent in ms-MY.src/renderer/src/i18n/pl-PL/sync.json-3-6 (1)
3-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate cloud sync success/error strings for Polish locale.
Line 4-Line 6 and Line 22-Line 27 are English and should be localized to keep sync feedback consistent in
pl-PL.Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/pl-PL/sync.json` around lines 3 - 6, Replace the English sync messages in this Polish locale file by translating the values for the keys "cloudConnected", "cloudUploaded", and "cloudPulled" into Polish (so UI feedback is localized), and also translate the English entries referenced at lines 22-27; update the string values only (keep the JSON keys unchanged) to appropriate Polish phrases consistent with "importComplete" style.src/renderer/src/i18n/pl-PL/settings.json-452-473 (1)
452-473:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize
cloudSynclabels/messages inpl-PL.Line 453-Line 472 are English strings in the Polish locale file, causing mixed-language UI in the Data settings cloud sync section.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/pl-PL/settings.json` around lines 452 - 473, The cloudSync object contains English strings in the Polish locale—replace the values for the "cloudSync" keys (title, description, endpoint, bucket, region, prefix, accessKeyId, secretAccessKey, secretConfigured, safeStorageUnavailable, save, test, upload, pull, savedTitle, testSuccessTitle, testFailedTitle, uploadSuccessTitle, uploadFailedTitle, pullSuccessTitle) with their Polish translations so the Data settings cloud sync UI is fully localized in pl-PL; update each string value under the "cloudSync" object accordingly (e.g., translate the title, description and all labels/messages to Polish).src/renderer/src/i18n/ru-RU/sync.json-4-6 (1)
4-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize new cloud sync runtime messages in ru-RU
The newly added cloud sync success/error messages are still English, so ru-RU users get mixed-language feedback during operations.
Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/ru-RU/sync.json` around lines 4 - 6, The three cloud sync message values (cloudConnected, cloudUploaded, cloudPulled) are still in English; replace their English text with Russian translations consistent with the file's style and tone, and likewise translate the other cloud sync-related entries later in the same file (the additional cloud sync messages around the other entries) so all related keys are fully localized for ru-RU users.src/renderer/src/i18n/ru-RU/settings.json-389-409 (1)
389-409:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate
cloudSyncblock for ru-RUThe added
data.cloudSyncstrings are English in the ru-RU locale file, causing mixed-language settings UI.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/ru-RU/settings.json` around lines 389 - 409, The cloudSync localization block contains English strings in the ru-RU locale; replace the English values for the "cloudSync" object keys (title, description, endpoint, bucket, region, prefix, accessKeyId, secretAccessKey, secretConfigured, safeStorageUnavailable, save, test, upload, pull, savedTitle, testSuccessTitle, testFailedTitle, uploadSuccessTitle, uploadFailedTitle, pullSuccessTitle) with appropriate Russian translations, ensuring you keep the same JSON keys and valid string quoting/escaping so the settings UI displays fully localized Russian text.src/renderer/src/i18n/pt-BR/settings.json-389-409 (1)
389-409:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize new
cloudSynclabels/messages to pt-BRThe new
data.cloudSyncvalues are still in English, so pt-BR users will see mixed-language UI in the new Cloud Sync section.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/pt-BR/settings.json` around lines 389 - 409, The cloudSync localization entries are still English; update all keys under "cloudSync" (title, description, endpoint, bucket, region, prefix, accessKeyId, secretAccessKey, secretConfigured, safeStorageUnavailable, save, test, upload, pull, savedTitle, testSuccessTitle, testFailedTitle, uploadSuccessTitle, uploadFailedTitle, pullSuccessTitle) to idiomatic Portuguese (pt-BR), keeping any UI punctuation/parentheses intact and preserving meaning (e.g., "Cloud Sync (S3-compatible)" → "Sincronização na Nuvem (compatível com S3)", "Endpoint" → "Endpoint", "Access Key ID" → "ID da chave de acesso", "Secret Access Key" → "Chave de acesso secreta", "Configured (leave blank to keep)" → "Configurado (deixe em branco para manter)", and translate status/title messages likewise) so the Cloud Sync UI displays fully localized pt-BR text.src/renderer/src/i18n/pt-BR/sync.json-4-6 (1)
4-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate cloud sync success/error messages in pt-BR bundle
success.cloud*anderror.cloud*messages are English, which breaks locale consistency for runtime toasts/errors.Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/pt-BR/sync.json` around lines 4 - 6, The pt-BR sync bundle contains English values for keys "cloudConnected", "cloudUploaded", and "cloudPulled" (and other success.cloud* / error.cloud* entries); replace those English strings with Portuguese translations so runtime toasts/errors are localized — e.g., set "cloudConnected" -> "Conexão com a nuvem bem-sucedida", "cloudUploaded" -> "Carregado para a nuvem", "cloudPulled" -> "Baixado o último backup da nuvem" and update the corresponding success.cloud* and error.cloud* keys elsewhere in the file to equivalent pt-BR strings.src/renderer/src/i18n/vi-VN/settings.json-452-473 (1)
452-473:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate
data.cloudSyncstrings to Vietnamese (vi-VN).The entire new cloud sync block is English, causing mixed-language UI in the Vietnamese Settings page.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/vi-VN/settings.json` around lines 452 - 473, The cloudSync localization block (object "cloudSync" with keys like "title", "description", "endpoint", "bucket", "region", "prefix", "accessKeyId", "secretAccessKey", "secretConfigured", "safeStorageUnavailable", "save", "test", "upload", "pull", "savedTitle", "testSuccessTitle", "testFailedTitle", "uploadSuccessTitle", "uploadFailedTitle", "pullSuccessTitle") is still in English; translate each value into Vietnamese so the Settings UI is fully localized (replace the English strings with their Vietnamese equivalents while keeping the same keys and JSON structure).src/renderer/src/i18n/vi-VN/sync.json-4-6 (1)
4-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winVietnamese sync cloud messages are still English.
Please localize these new cloud sync success/error strings so
vi-VNstays fully translated.Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/vi-VN/sync.json` around lines 4 - 6, The JSON keys cloudConnected, cloudUploaded, and cloudPulled currently contain English messages; replace their values with Vietnamese translations (e.g., "Kết nối đám mây thành công", "Đã tải lên đám mây", "Đã kéo bản sao lưu mới nhất từ đám mây") and likewise locate and translate the related strings mentioned around lines 22-27 so the vi-VN sync cloud messages are fully localized while preserving the same keys.src/renderer/src/i18n/tr-TR/settings.json-452-473 (1)
452-473:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate
data.cloudSyncvalues to Turkish (tr-TR).This new block is still in English, so Turkish users will see mixed-language UI in Settings.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/tr-TR/settings.json` around lines 452 - 473, Translate the data.cloudSync block values into Turkish by replacing each English string for keys title, description, endpoint, bucket, region, prefix, accessKeyId, secretAccessKey, secretConfigured, safeStorageUnavailable, save, test, upload, pull, savedTitle, testSuccessTitle, testFailedTitle, uploadSuccessTitle, uploadFailedTitle and pullSuccessTitle with their Turkish equivalents (e.g., title -> "Bulut Senkronizasyonu (S3 uyumlu)", description -> "Yedekleri Cloudflare R2 gibi S3 uyumlu depolamaya yükleyin ve başka bir cihazda en son yedeği çekin.", endpoint -> "Uç Nokta", bucket -> "Kova", region -> "Bölge", prefix -> "Yol Öneki", accessKeyId -> "Erişim Anahtarı ID", secretAccessKey -> "Gizli Erişim Anahtarı", secretConfigured -> "Yapılandırıldı (kullanmak için boş bırakın)", safeStorageUnavailable -> "Sistem anahtar zinciri kullanılamıyor; gizli anahtar güvenli şekilde saklanamaz.", save -> "Kaydet", test -> "Bağlantıyı Test Et", upload -> "Buluta Yükle", pull -> "Buluttan En Sonu Çek", savedTitle -> "Bulut yapılandırması kaydedildi", testSuccessTitle -> "Bağlantı başarılı", testFailedTitle -> "Bağlantı başarısız", uploadSuccessTitle -> "Yükleme başarılı", uploadFailedTitle -> "Yükleme başarısız", pullSuccessTitle -> "Çekme başarılı"); preserve the existing JSON keys and formatting/escaping while updating only the string values under data.cloudSync.src/renderer/src/i18n/tr-TR/sync.json-4-6 (1)
4-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winCloud sync status/error messages are not localized to Turkish.
These strings are English in
tr-TR, which causes mixed-language toast/error output in the sync flow.Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/tr-TR/sync.json` around lines 4 - 6, The tr-TR locale contains English values for the sync keys "cloudConnected", "cloudUploaded" and "cloudPulled"; replace those values with Turkish translations (e.g. "cloudConnected" => "Bulut bağlantısı başarıyla kuruldu", "cloudUploaded" => "Buluta yüklendi", "cloudPulled" => "Buluttan en son yedek çekildi") and ensure you also translate the other cloud sync/status keys elsewhere in the same file (the remaining cloud-related sync messages) so all sync/toast/error strings are fully localized.src/renderer/src/i18n/zh-TW/sync.json-4-6 (1)
4-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate cloud sync status/error messages in zh-TW locale file.
At Line 4-6 and Line 22-27, these new values are English and will show mixed-language sync feedback to zh-TW users.
Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/zh-TW/sync.json` around lines 4 - 6, The zh-TW locale file contains English messages for cloud sync keys; update the values for "cloudConnected", "cloudUploaded", "cloudPulled" (and the similar keys around lines 22-27) to their Traditional Chinese translations so zh-TW users see consistent localized feedback; locate these keys in src/renderer/src/i18n/zh-TW/sync.json and replace the English strings with appropriate zh-TW phrases (e.g., translated equivalents for "Cloud connection succeeded", "Uploaded to cloud", "Pulled the latest backup from cloud") ensuring punctuation and tone match other entries.src/renderer/src/i18n/zh-TW/settings.json-390-409 (1)
390-409:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize
cloudSyncsettings copy for zh-TW.The new block (Line 390-409) is English, which causes mixed-language UI in the zh-TW settings experience.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/zh-TW/settings.json` around lines 390 - 409, The zh-TW settings.json contains an untranslated "cloudSync" block (keys like "title", "description", "endpoint", "bucket", "region", "prefix", "accessKeyId", "secretAccessKey", "secretConfigured", "safeStorageUnavailable", "save", "test", "upload", "pull", "savedTitle", "testSuccessTitle", "testFailedTitle", "uploadSuccessTitle", "uploadFailedTitle", "pullSuccessTitle")—translate each of these English values into Traditional Chinese (zh-TW) so the Cloud Sync (S3-compatible) UI displays consistently in zh-TW; keep the JSON keys unchanged and preserve any placeholders/punctuation in the original strings.src/renderer/src/i18n/zh-HK/sync.json-4-6 (1)
4-6:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate new cloud sync success/error messages for zh-HK locale.
At Line 4-6 and Line 22-27, the newly added messages are English and will produce mixed-language toast/error feedback in zh-HK.
Also applies to: 22-27
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/zh-HK/sync.json` around lines 4 - 6, The zh-HK locale file contains English strings for the cloud sync keys cloudConnected, cloudUploaded, cloudPulled (and additional new keys around lines 22–27); replace those English messages with proper Traditional Chinese (Hong Kong) translations so toast/error UI is fully localized—update the values for "cloudConnected", "cloudUploaded", "cloudPulled" and the other new keys in src/renderer/src/i18n/zh-HK/sync.json to appropriate zh-HK strings (use Traditional Chinese phrasing consistent with the project's existing translations).src/renderer/src/i18n/zh-HK/settings.json-390-409 (1)
390-409:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize the new
cloudSynccopy in zh-HK to avoid mixed-language UI.At Line 390 and the related labels/actions through Line 409, the new strings are English while this is a Traditional Chinese locale file. This will render a mixed-language settings panel for zh-HK users.
Suggested direction
- "title": "Cloud Sync (S3-compatible)", + "title": "雲端同步(S3 相容)", - "save": "Save", + "save": "儲存", - "test": "Test Connection", + "test": "測試連線"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/zh-HK/settings.json` around lines 390 - 409, The zh-HK locale contains English strings for the Cloud Sync section (keys like "title", "description", "endpoint", "bucket", "region", "prefix", "accessKeyId", "secretAccessKey", "secretConfigured", "safeStorageUnavailable", "save", "test", "upload", "pull", "savedTitle", "testSuccessTitle", "testFailedTitle", "uploadSuccessTitle", "uploadFailedTitle", "pullSuccessTitle"); replace each English value with appropriate Traditional Chinese (zh-HK) translations so the cloudSync UI is fully localized and no mixed-language text appears in the settings panel.
🧹 Nitpick comments (3)
docs/features/cloud-sync-s3/plan.md (1)
6-11: ⚡ Quick winAdd language identifier to fenced code block.
The ASCII diagram should specify a language identifier (e.g.,
textorplaintext) to satisfy markdown linters.📝 Proposed fix
-``` +```text DataSettings.vue ─► sync store ─► SyncClient ─► [route] ─► SyncPresenter ─► CloudStorageService 保存/测试/上传/拉取 │ │ ConfigPresenter R2 / S3 桶🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/features/cloud-sync-s3/plan.md` around lines 6 - 11, The fenced ASCII diagram block lacks a language identifier; update the markdown fenced code block that contains the diagram (the block starting with the diagram referencing DataSettings.vue → sync store → SyncClient → SyncPresenter → CloudStorageService and ConfigPresenter) to include a plain text language tag (e.g., ```text or ```plaintext) so linters recognize it as a text/code block while preserving the diagram content.src/shared/types/presenters/legacy.presenters.d.ts (1)
2066-2074: 💤 Low valueVerify omission of
enabledfield inResolvedCloudSyncConfig.
CloudSyncConfigViewextendsCloudSyncConfigBase(which includes theenabledfield), butResolvedCloudSyncConfigredefines all fields explicitly and omitsenabled. This creates an inconsistency in the type hierarchy.If
enabledis intentionally excluded because it's a UI toggle rather than an operational S3 parameter, consider documenting this design decision in a comment. Otherwise, consider includingenabledfor consistency.📋 Suggested clarification
+/** Fully resolved config (with decrypted secret) used inside the main process only. + * Note: 'enabled' is omitted as it's a UI toggle, not an S3 operation parameter. */ export interface ResolvedCloudSyncConfig { endpoint: string🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/shared/types/presenters/legacy.presenters.d.ts` around lines 2066 - 2074, ResolvedCloudSyncConfig currently redefines all fields for the internal S3 config but omits the enabled flag present on CloudSyncConfigBase/CloudSyncConfigView; either add enabled: boolean to the ResolvedCloudSyncConfig interface (to keep the type hierarchy consistent) or add a one-line comment above the ResolvedCloudSyncConfig declaration explaining why enabled is intentionally excluded (e.g., "UI-only toggle, not used by runtime sync operations") so readers understand the design decision. Ensure the change references the ResolvedCloudSyncConfig, CloudSyncConfigView and CloudSyncConfigBase symbols so it's clear which types are affected.docs/issues/import-fts-shadow-table/spec.md (1)
6-9: ⚡ Quick winAdd language specifier to code fence.
The fenced code block should specify a language identifier for proper syntax highlighting and to satisfy markdown linting rules.
📝 Proposed fix
-``` +```text Failed to import database: Failed to import table deepchat_search_documents_fts_config: table deepchat_search_documents_fts_config may not be modified</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@docs/issues/import-fts-shadow-table/spec.mdaround lines 6 - 9, The code
fence in the spec.md file currently lacks a language identifier; update the
fenced block containing the error message "Failed to import database: Failed to
import table deepchat_search_documents_fts_config: table
deepchat_search_documents_fts_config may not be modified" to include a language
specifier (e.g., usetext orconsole) so markdown linting and syntax
highlighting work correctly; locate the fenced block in
docs/issues/import-fts-shadow-table/spec.md and add the identifier immediately
after the opening triple backticks.</details> </blockquote></details> </blockquote></details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: defaults **Review profile**: CHILL **Plan**: Pro **Run ID**: `ccbd09a3-a374-428d-af59-d60c2ae85ce2` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between b60b5812550c75ff86dfb1ef21be57d111a921a0 and e9c60a4f65c1947f02830d58b8fe1de7c8ec30d4. </details> <details> <summary>📒 Files selected for processing (56)</summary> * `docs/features/cloud-sync-s3/plan.md` * `docs/features/cloud-sync-s3/spec.md` * `docs/features/cloud-sync-s3/tasks.md` * `docs/issues/import-fts-shadow-table/spec.md` * `package.json` * `src/main/presenter/configPresenter/index.ts` * `src/main/presenter/sqlitePresenter/importData.ts` * `src/main/presenter/syncPresenter/cloudStorageService.ts` * `src/main/presenter/syncPresenter/index.ts` * `src/main/routes/index.ts` * `src/renderer/api/SyncClient.ts` * `src/renderer/settings/components/DataSettings.vue` * `src/renderer/src/i18n/da-DK/settings.json` * `src/renderer/src/i18n/da-DK/sync.json` * `src/renderer/src/i18n/de-DE/settings.json` * `src/renderer/src/i18n/de-DE/sync.json` * `src/renderer/src/i18n/en-US/settings.json` * `src/renderer/src/i18n/en-US/sync.json` * `src/renderer/src/i18n/es-ES/settings.json` * `src/renderer/src/i18n/es-ES/sync.json` * `src/renderer/src/i18n/fa-IR/settings.json` * `src/renderer/src/i18n/fa-IR/sync.json` * `src/renderer/src/i18n/fr-FR/settings.json` * `src/renderer/src/i18n/fr-FR/sync.json` * `src/renderer/src/i18n/he-IL/settings.json` * `src/renderer/src/i18n/he-IL/sync.json` * `src/renderer/src/i18n/id-ID/settings.json` * `src/renderer/src/i18n/id-ID/sync.json` * `src/renderer/src/i18n/it-IT/settings.json` * `src/renderer/src/i18n/it-IT/sync.json` * `src/renderer/src/i18n/ja-JP/settings.json` * `src/renderer/src/i18n/ja-JP/sync.json` * `src/renderer/src/i18n/ko-KR/settings.json` * `src/renderer/src/i18n/ko-KR/sync.json` * `src/renderer/src/i18n/ms-MY/settings.json` * `src/renderer/src/i18n/ms-MY/sync.json` * `src/renderer/src/i18n/pl-PL/settings.json` * `src/renderer/src/i18n/pl-PL/sync.json` * `src/renderer/src/i18n/pt-BR/settings.json` * `src/renderer/src/i18n/pt-BR/sync.json` * `src/renderer/src/i18n/ru-RU/settings.json` * `src/renderer/src/i18n/ru-RU/sync.json` * `src/renderer/src/i18n/tr-TR/settings.json` * `src/renderer/src/i18n/tr-TR/sync.json` * `src/renderer/src/i18n/vi-VN/settings.json` * `src/renderer/src/i18n/vi-VN/sync.json` * `src/renderer/src/i18n/zh-CN/settings.json` * `src/renderer/src/i18n/zh-CN/sync.json` * `src/renderer/src/i18n/zh-HK/settings.json` * `src/renderer/src/i18n/zh-HK/sync.json` * `src/renderer/src/i18n/zh-TW/settings.json` * `src/renderer/src/i18n/zh-TW/sync.json` * `src/renderer/src/stores/sync.ts` * `src/shared/contracts/routes.ts` * `src/shared/contracts/routes/sync.routes.ts` * `src/shared/types/presenters/legacy.presenters.d.ts` </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
背景 / Why
现有「同步」只把数据库+配置打包成
backup-<时间戳>.zip写入本地文件夹,导入也只从本地读取,多设备之间数据无法流转。本 PR 在现有备份产物之上叠加一个最小的云层:把最新本地备份上传到 S3 兼容对象存储,并能拉取最新备份还原 —— 主用例为 Cloudflare R2,通过 S3 兼容协议同时支持 MinIO / AWS S3 / B2。改动 / What
CloudStorageService(@aws-sdk/client-s3,path-style +region: auto):test / upload / list / downloadLatest。SyncPresenter:testCloudConnection/uploadLatestBackupToCloud/pullLatestBackupFromCloud(拉取复用现有importFromSync,享受 temp 备份/失败回滚)。ConfigPresenter:云配置读写;secret 经safeStorage加密落盘,视图脱敏(仅hasSecret),渲染层永不收到明文。SyncClient/ pinia store。cloudSync.*与sync.*云端文案。DataImporter增量导入时误写 FTS5 虚拟表/影子表导致 "table X may not be modified"(本地导入同样受影响)。改为按虚拟表名前缀排除,索引由触发器重建。UI(数据设置 · 同步卡片内)
安全 / Security
safeStorage(系统密钥链)加密,密文落盘;不可用时拒绝保存并提示。accessKeyId/endpoint 泄露到云端备份文件。测试 / Verification
pnpm run typecheck/format/lint/i18n全绿。文档:
docs/features/cloud-sync-s3/、docs/issues/import-fts-shadow-table/。🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Documentation