Fix documentation and code inconsistencies found during audit

- CLAUDE.md: Fix drawer width unit (80vw -> 80cqi), clarify group-by-due-date
  is toggle-only (sorting not yet implemented), clarify Phase 4 status
- PLAN.md: Fix conflict resolution label (last-write-wins -> remote wins),
  add username to keyring key format, mark fallback credential storage as
  not yet implemented
- sync.rs: Fix comment table to say "conflict" instead of "last-write-wins"
  for both-modified and both-added cases (matches actual Conflict action)
- config.rs: Add temp file cleanup on atomic write rename failure to match
  the pattern already used in storage.rs

https://claude.ai/code/session_01YWvxpzeT3hEUxD9aNvfNuL
This commit is contained in:
Claude 2026-04-06 12:08:22 +00:00
parent fd1ebce9ce
commit 7c6001291c
No known key found for this signature in database
4 changed files with 12 additions and 9 deletions

View file

@ -49,7 +49,7 @@ Workspaces are plain folders. Each task list is a subfolder containing `.listdat
The GUI uses Svelte 5 runes mode (`$state`, `$derived`, `$effect`, `$props()`). Key UI patterns:
- **Sliding drawer**: Left panel (lists) slides with main content as one piece via `translateX`. 80vw wide. List items show checkmark for active list and chevron on hover.
- **Sliding drawer**: Left panel (lists) slides with main content as one piece via `translateX`. 80cqi wide (80% container query inline size). List items show checkmark for active list and chevron on hover.
- **Three-panel slide**: Main content area is 300% wide with three panels (task list, task detail, subtask detail) that slide via `translateX` using a `taskStack` array. Stack depth 0 = list, 1 = task detail, 2 = subtask detail.
- **Settings modal**: Per-workspace settings opened from workspace kebab menu. Shows WebDAV config (for webdav workspaces), sync controls, and theme selector.
- **Workspace switcher**: Custom drop-up menu in drawer footer (left), kebab menu per workspace (right) with Settings option.
@ -68,7 +68,7 @@ Pre-alpha. No users, no released builds, no data to migrate. Breaking changes to
- **Phase 1** (Core + CLI): Complete
- **Phase 2** (WebDAV sync): Complete — remote folder browsing, checksum-based conflict resolution, auto-sync lifecycle, per-workspace sync interval
- **Phase 3** (GUI MVP): Complete
- **Phase 4** (Mobile): Tauri Android cfg-gated with tauri-plugin-credentials and safe area insets; needs `tauri android init` + build
- **Phase 4** (Mobile): In progress — Android preliminaries done (file-watcher gating, tauri-plugin-credentials, safe area insets, Android targets configured); needs build verification and iOS setup
### GUI features done
@ -84,7 +84,7 @@ Pre-alpha. No users, no released builds, no data to migrate. Breaking changes to
- Due date picker/editor (DateTimePicker in new task + task detail); `has_time: bool` field tracks whether time is set
- Move task between lists (inline list in kebab menu, no submenu)
- List rename (inline input in main panel header via kebab)
- Group-by-due-date toggle per list (main panel kebab)
- Group-by-due-date toggle per list (main panel kebab; persists flag but display sorting not yet implemented)
- Delete completed tasks (main panel kebab + subtask kebab, with confirmation dialogs)
- Keyboard shortcuts (Escape priority chain: settings → detail → list menu → drawer → menus)
- Setup screen with 2-step mode selection (Local Folder vs WebDAV Server), window dragging, "Open Existing Folder" option, remote folder browsing

View file

@ -508,10 +508,10 @@ pub fn delete_credentials(domain: &str) -> Result<()>;
**Primary**: Platform Keychain via `keyring` crate
- Store WebDAV username + password in system keychain
- Key format: `com.onyx.webdav.{server-domain}`
- Key format: `com.onyx.webdav.{server-domain}::{username}` (the `::` separator prevents key collisions when usernames contain dots)
- Works on: Windows (Credential Manager), macOS (Keychain), Linux (Secret Service), iOS/Android (Keystore)
**Fallback**: Encrypted local storage if keychain unavailable
**Fallback**: Not yet implemented (planned: encrypted local storage if keychain unavailable)
### Dependencies
@ -527,7 +527,7 @@ keyring = "3.0"
- [x] WebDAV client implementation in core library
- [x] Credential storage (platform keychain)
- [x] Bi-directional sync (push/pull)
- [x] Conflict resolution (last-write-wins)
- [x] Conflict resolution (remote wins; local recovered as duplicate)
- [x] Offline queue for pending operations
- [x] CLI: `sync --setup` command
- [x] CLI: `sync --push` command

View file

@ -118,7 +118,10 @@ impl AppConfig {
// Atomic write: write to temp file then rename to prevent corruption on crash
let temp = path.with_extension("tmp");
std::fs::write(&temp, &content)?;
std::fs::rename(&temp, path)?;
if let Err(e) = std::fs::rename(&temp, path) {
let _ = std::fs::remove_file(&temp);
return Err(e.into());
}
Ok(())
}

View file

@ -135,10 +135,10 @@ pub struct RemoteFileSnapshot {
/// | unchanged | modified | download |
/// | deleted | unchanged | delete remote |
/// | unchanged | deleted | delete local |
/// | modified | modified | last-write-wins (compare timestamps) |
/// | modified | modified | conflict (remote wins; local recovered) |
/// | deleted | modified | download (remote wins) |
/// | modified | deleted | upload (local wins) |
/// | added | added | last-write-wins |
/// | added | added | conflict (remote wins; local recovered) |
pub fn compute_sync_actions(
local_files: &[LocalFileInfo],
remote_files: &[RemoteFileSnapshot],