Skip to content

feat(sync): S3-compatible cloud backup sync#1741

Merged
zerob13 merged 3 commits into
devfrom
feat/cloud-sync-s3
Jun 7, 2026
Merged

feat(sync): S3-compatible cloud backup sync#1741
zerob13 merged 3 commits into
devfrom
feat/cloud-sync-s3

Conversation

@zhangmo8
Copy link
Copy Markdown
Collaborator

@zhangmo8 zhangmo8 commented Jun 5, 2026

5699df81bf22e86e8f1ee9473c183c8c

背景 / 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。
  • SyncPresentertestCloudConnection / uploadLatestBackupToCloud / pullLatestBackupFromCloud(拉取复用现有 importFromSync,享受 temp 备份/失败回滚)。
  • ConfigPresenter:云配置读写;secret 经 safeStorage 加密落盘,视图脱敏(仅 hasSecret),渲染层永不收到明文。
  • 凭证机器本地化:云配置从备份中剥离、导入时保留本机值 —— 一次「拉取」不会覆盖/破坏本机云凭证。
  • IPC:新增 5 个路由契约(含真正的 zod 入参校验)+ SyncClient / pinia store。
  • UI:数据设置内新增「云同步 (S3 兼容)」区块,纯手动按钮:保存 / 测试连接 / 上传到云 / 从云拉取最新。
  • i18n:全语言补齐 cloudSync.*sync.* 云端文案。
  • 顺带修复DataImporter 增量导入时误写 FTS5 虚拟表/影子表导致 "table X may not be modified"(本地导入同样受影响)。改为按虚拟表名前缀排除,索引由触发器重建。

UI(数据设置 · 同步卡片内)

BEFORE                              AFTER
┌─ 数据同步 ───────────┐           ┌─ 数据同步 ───────────────────┐
│ 启用同步   [x]        │           │ 启用同步   [x]                │
│ 同步文件夹 [____]     │           │ 同步文件夹 [____]             │
│ [立即备份] [导入数据] │           │ [立即备份] [导入数据]         │
└──────────────────────┘           ├─ 云同步 (S3 兼容) ───────────┤
                                    │ Endpoint/Bucket/Region/...    │
                                    │ AccessKeyId / SecretAccessKey │
                                    │ [保存] [测试连接]             │
                                    │ [上传到云] [从云拉取最新] ○增量│
                                    └──────────────────────────────┘

安全 / Security

  • secret 用 Electron safeStorage(系统密钥链)加密,密文落盘;不可用时拒绝保存并提示。
  • 云凭证不进备份,避免 accessKeyId/endpoint 泄露到云端备份文件。

测试 / Verification

  • pnpm run typecheck / format / lint / i18n 全绿。
  • 待真实 R2 凭证人工验证:测试连接 → 上传 → 另一设备拉取 → 数据恢复;切 MinIO endpoint 验证 S3 兼容。

文档:docs/features/cloud-sync-s3/docs/issues/import-fts-shadow-table/

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Cloud Sync (S3-compatible): configure endpoint/bucket/region/prefix and credentials, test connection, securely store secret via system keychain, manually upload latest backup and pull latest backup with import mode options; UI and store support added; multilingual UI strings updated.
  • Bug Fixes

    • Fixed incremental database imports failing when FTS5 shadow tables were included.
  • Documentation

    • Added architecture, spec and task docs describing the cloud sync feature and rollout plan.

zhangmo8 added 2 commits June 5, 2026 15:11
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
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 5, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 991a9b07-4f3b-4a24-99ad-0b913ca51dab

📥 Commits

Reviewing files that changed from the base of the PR and between e9c60a4 and 848ff6a.

📒 Files selected for processing (14)
  • docs/features/cloud-sync-s3/plan.md
  • docs/features/cloud-sync-s3/tasks.md
  • docs/issues/import-fts-shadow-table/spec.md
  • src/main/presenter/configPresenter/index.ts
  • src/main/presenter/syncPresenter/cloudStorageService.ts
  • src/main/presenter/syncPresenter/index.ts
  • src/renderer/settings/components/DataSettings.vue
  • 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/stores/sync.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • test/main/presenter/SyncPresenter.test.ts
✅ Files skipped from review due to trivial changes (7)
  • docs/features/cloud-sync-s3/plan.md
  • src/renderer/src/i18n/id-ID/settings.json
  • docs/features/cloud-sync-s3/tasks.md
  • src/renderer/src/i18n/he-IL/sync.json
  • docs/issues/import-fts-shadow-table/spec.md
  • src/renderer/src/i18n/id-ID/sync.json
  • src/renderer/src/i18n/he-IL/settings.json
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/main/presenter/configPresenter/index.ts
  • src/renderer/src/stores/sync.ts
  • src/shared/types/presenters/legacy.presenters.d.ts
  • src/renderer/settings/components/DataSettings.vue
  • src/main/presenter/syncPresenter/index.ts

📝 Walkthrough

Walkthrough

This 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.

Changes

Cloud Sync (S3-compatible) Feature

Layer / File(s) Summary
Type System & Route Contracts
src/shared/types/presenters/legacy.presenters.d.ts, src/shared/contracts/routes/sync.routes.ts, src/shared/contracts/routes.ts
Defines Cloud Sync types (CloudSyncConfigBase, CloudSyncConfigView, CloudSyncConfigInput, ResolvedCloudSyncConfig, CloudSyncResult), Zod schemas for route contracts, and five new route exports (sync.getCloudConfig, sync.setCloudConfig, sync.testCloud, sync.uploadToCloud, sync.pullFromCloud).
AWS SDK Dependency
package.json
Adds @aws-sdk/client-s3 at v3.1062.0 for S3 API interactions.
CloudStorageService S3 Operations
src/main/presenter/syncPresenter/cloudStorageService.ts
Implements S3-compatible cloud operations: test connection via ListObjectsV2, upload backup zip via PutObjectCommand, list remote backups with pagination and newest-first sorting, and download latest backup with safe file writes.
ConfigPresenter Cloud Configuration
src/main/presenter/configPresenter/index.ts
Adds config view/input getters, secret encryption/storage via Electron safeStorage, resolved config builder that decrypts secrets, and safeStorage availability check.
SyncPresenter Cloud Sync Operations
src/main/presenter/syncPresenter/index.ts
Implements test cloud connection, upload latest local backup, pull and import latest cloud backup with configurable import mode; strips/preserves cloud credentials in app-settings backup/restore.
Main Process Route Dispatch
src/main/routes/index.ts
Dispatches five new IPC routes, calling config/sync presenters for cloud operations; records settings activity on successful upload/pull.
Renderer API Client
src/renderer/api/SyncClient.ts
Adds getCloudConfig, setCloudConfig, testCloudConnection, uploadToCloud, pullFromCloud methods following existing bridge route pattern.
Renderer Store Cloud State & Methods
src/renderer/src/stores/sync.ts
Extends sync store with cloudConfig and isCloudBusy state, cloud config load/save/test/upload/pull methods, concurrency guarding, and backup refresh after cloud pull.
Renderer UI: Cloud Sync Settings
src/renderer/settings/components/DataSettings.vue
Adds cloud sync configuration UI with endpoint/bucket/region/prefix/credential inputs, test/upload/pull action buttons, pull mode radio group, safe-storage warning, and async handlers with toast notifications.
Internationalization
src/renderer/src/i18n/*/settings.json, src/renderer/src/i18n/*/sync.json (16 languages)
Cloud sync UI labels, field descriptions, action buttons, success/failure messages, and error strings across en-US, zh-CN, de-DE, fr-FR, ja-JP, ko-KR, pt-BR, ru-RU, es-ES, it-IT, pl-PL, tr-TR, vi-VN, zh-HK, zh-TW, and da-DK.
Feature Documentation
docs/features/cloud-sync-s3/plan.md, docs/features/cloud-sync-s3/spec.md, docs/features/cloud-sync-s3/tasks.md
Architecture overview, upload/pull data flows, encryption/demasking strategies, safeStorage credential handling, and boundary decisions.

FTS5 Shadow Table Import Fix

Layer / File(s) Summary
Virtual Table & Shadow Table Exclusion
src/main/presenter/sqlitePresenter/importData.ts
DataImporter.getTablesInOrder() now detects virtual tables via CREATE VIRTUAL TABLE pattern matching and excludes both virtual tables and their shadow tables (prefixed with <vtab>_) from import operations.
Issue Specification
docs/issues/import-fts-shadow-table/spec.md
Documents root cause, fix strategy, affected scope (incremental import path only), and validation steps.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • ThinkInAIXYZ/deepchat#1052: Overlaps at src/main/presenter/sqlitePresenter/importData.ts where both PRs modify getTablesInOrder() logic for virtual/shadow table handling in imports.

Suggested labels

codex

Suggested reviewers

  • zerob13

Poem

🐰 Cloud whispers up, secrets tucked below,
S3 buckets catch our backup glow,
Shadow tables fade from import's way,
Sync streams flow—machines stay in play!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely summarizes the main feature addition: S3-compatible cloud backup sync. It directly reflects the primary change across the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 feat/cloud-sync-s3

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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 win

Don’t derive hasSecret from ciphertext presence alone.

If decryption fails in Lines 1927-1932, Line 1939 still reports hasSecret: true just 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 win

Translate 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 win

Localize the new cloudSync strings for da-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 win

Localize the new cloudSync block for de-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 win

Translate 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 win

Localize 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 win

Translate the new cloudSync labels/messages to Spanish.

This es-ES block is currently English-only, so Spanish users will see mixed-language UI in Settings. Please localize the full cloudSync section 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 win

Translate cloudSync labels/messages in the fr-FR bundle

At Line 390–409, all newly added cloudSync strings 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 win

Localize cloudSync strings for the fa-IR bundle

At Line 390–409, the newly added cloudSync values 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 win

Localize 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 win

New 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 win

Translate 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 win

Translate new cloudSync settings 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 win

Localize 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 win

Localize cloudSync section 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 win

Translate 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 win

Localize new cloudSync labels/messages for Italian locale.

Lines 453-472 are currently English in the it-IT resource, 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 win

Localize the new cloudSync strings for ms-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 win

Translate cloud sync status/error messages in ms-MY locale.

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 win

Translate 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 win

Localize cloudSync labels/messages in pl-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 win

Localize 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 win

Translate cloudSync block for ru-RU

The added data.cloudSync strings 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 win

Localize new cloudSync labels/messages to pt-BR

The new data.cloudSync values 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 win

Translate cloud sync success/error messages in pt-BR bundle

success.cloud* and error.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 win

Translate data.cloudSync strings 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 win

Vietnamese sync cloud messages are still English.

Please localize these new cloud sync success/error strings so vi-VN stays 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 win

Translate data.cloudSync values 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 win

Cloud 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 win

Translate 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 win

Localize cloudSync settings 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 win

Translate 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 win

Localize the new cloudSync copy 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 win

Add language identifier to fenced code block.

The ASCII diagram should specify a language identifier (e.g., text or plaintext) 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 value

Verify omission of enabled field in ResolvedCloudSyncConfig.

CloudSyncConfigView extends CloudSyncConfigBase (which includes the enabled field), but ResolvedCloudSyncConfig redefines all fields explicitly and omits enabled. This creates an inconsistency in the type hierarchy.

If enabled is intentionally excluded because it's a UI toggle rather than an operational S3 parameter, consider documenting this design decision in a comment. Otherwise, consider including enabled for 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 win

Add 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.md around 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., use text or console) 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 -->

Comment thread src/main/presenter/configPresenter/index.ts
Comment thread src/main/presenter/syncPresenter/cloudStorageService.ts
Comment thread src/main/presenter/syncPresenter/index.ts Outdated
Comment thread src/main/presenter/syncPresenter/index.ts
Comment thread src/renderer/src/i18n/he-IL/settings.json
Comment thread src/renderer/src/i18n/he-IL/sync.json Outdated
Comment thread src/renderer/src/i18n/id-ID/settings.json
Comment thread src/renderer/src/i18n/id-ID/sync.json Outdated
Comment thread src/renderer/src/stores/sync.ts
@zerob13 zerob13 merged commit fb7f841 into dev Jun 7, 2026
3 checks passed
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