fix(watcher): copy files instead of moving them, leave originals for Obsidian
Some checks failed
cd / Build and deploy (push) Successful in 10s
CI / Lint / Test / Vet (push) Failing after 5s
CI / Mirror to GitHub (push) Has been skipped

Files dropped into brain/raw/ are now copied to processed/ or failed/ rather
than moved. A .processed or .failed marker is written next to the original so
the watcher skips it on subsequent polls without deleting it. This keeps
Syncthing-synced Obsidian vaults intact after ingestion.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mathias Bergqvist
2026-04-23 14:47:50 +02:00
parent e74320a8e8
commit 6928907d79
2 changed files with 61 additions and 17 deletions

View File

@@ -81,11 +81,15 @@ func TestStart_ProcessesFile(t *testing.T) {
}
time.Sleep(20 * time.Millisecond)
}
require.True(t, found, "file should be moved to processed/")
require.True(t, found, "file should be copied to processed/")
// Original file should be gone.
// Original file should still exist (copy, not move — keeps Obsidian vault intact).
_, err := os.Stat(rawFile)
assert.True(t, os.IsNotExist(err), "original file should be gone from raw/")
assert.NoError(t, err, "original file should remain in raw/")
// A .processed marker should exist next to the original.
_, err = os.Stat(rawFile + ".processed")
assert.NoError(t, err, ".processed marker should be written")
// Wiki page should exist.
wikiPath := filepath.Join(brainDir, "wiki", "sources", "shape-up-book.md")
@@ -130,11 +134,15 @@ func TestStart_MovesToFailedOnError(t *testing.T) {
}
time.Sleep(20 * time.Millisecond)
}
require.True(t, found, "file should be moved to failed/")
require.True(t, found, "file should be copied to failed/")
// Original file should be gone from raw/.
// Original file should still exist (copy, not move — keeps Obsidian vault intact).
_, err := os.Stat(rawFile)
assert.True(t, os.IsNotExist(err), "original file should be gone from raw/")
assert.NoError(t, err, "original file should remain in raw/")
// A .failed marker should exist next to the original.
_, err = os.Stat(rawFile + ".failed")
assert.NoError(t, err, ".failed marker should be written")
// log.md should contain a watcher error entry.
logContent, err := os.ReadFile(filepath.Join(brainDir, "log.md"))