success no longer includes dedup-skipped mail, so without a
duplicates field ImportPerformed consumers could not tell an
all-duplicates batch from one that silently lost everything. Also
documents that ExtractOutcome::Imported covers mail dropped by
archive rules, which has always counted as a success.
rustfmt +nightly (imports_granularity, group_imports per
.rustfmt.toml) over the five files the fix touched, plus trailing
whitespace cleanup. No behavior change.
A BLAKE3 content-hash hit in extract_envelope_core returned the same
Ok(()) as a real import, so every import surface counted silently
skipped messages as successes and the documented duplicates field
stayed 0 forever.
Make the outcome explicit: extract_envelope_core now returns
ExtractOutcome::{Imported, Duplicate} and every import loop (batch
/import, upload EML, MBOX, PST) counts Duplicate into duplicates
instead of success. total = success + duplicates + failed holds on
every path; duplicates produce no failed_details entries and an
all-duplicates run reports Completed. The batch endpoint status check
treats duplicates as processed work so a duplicates-plus-failures run
keeps reporting Completed as before. The SMTP receiver and IMAP sync
ignore the outcome.
- Add SyncFull trigger and configurable IMAP socket read timeout
- Replace streaming UID FETCH with UID SEARCH ALL + batched fetch so per-message progress stays responsive and throttling servers can retry with reconnection
- Finalize stale Running sessions on startup so interrupted syncs no longer show a phantom "syncing" state
- Show a live syncing pill on the account row; add elapsed time, current folder, and slow-server warning styling in the dialog
- use a single Engine instance for email + attachment blobs
- add delete_batch, gc_if_needed, background flush to blob crate
- fix Entry.raw_size storing compressed length instead of original
- move fjall-dependent migration code from core to admin crate
- add STORAGE_VERSION file for layout version detection
- Replace bincode 3.0.0 (empty crate) with bincode_reloaded 3.1.10
- Add delete_batch for efficient grouped tombstone writes
- Add gc_if_needed to skip GC when no segment exceeds threshold
- Add flush() for lightweight fsync+meta checkpoint without compact
- Add Config::flush_interval_secs to spawn a background flush thread
- Remove per-put/per-delete fsync; persistence via background flush
- Split gc_segments into gc_prepare/gc_finish to reduce write lock hold time
- Make MBOX/PST upload size limits configurable via SETTINGS
(bichon_web_mbox_upload_limit_mb defaults to 1 GB,
bichon_web_pst_upload_limit_mb defaults to 2 GB)