Drafts vs. External Files
Relevant source files
The following files were used as context for generating this wiki page:
Augenblick distinguishes between internal Drafts and External Files (referred to as "Saved" notes in the codebase). Drafts are ephemeral, internal documents managed entirely by the application, while External Files are standard Markdown documents stored on the user's filesystem that the application has been granted permission to access.
This dual-storage architecture allows for a "temporary by default" workflow where users can capture thoughts quickly without managing files, while still providing a path for permanent storage through a conversion process known as "Save As."
Sources: README.md, plans/migration.inventory.md:152-153
Storage Architecture
The application categorizes notes based on their storage type, which is persisted in a local SQLite database.
| Feature | Drafts | External Files (Saved) |
|---|---|---|
| Location | app_data_dir/drafts/ | Anywhere on user filesystem |
| Persistence | Auto-saves every 500ms of idle time | Manual save only (Cmd+S) |
| File Management | Managed by the app; UUID-named | Managed by user; custom names |
| Permissions | Full app access | Requires Scoped Bookmarks (macOS) |
| Auto-Expiry | Subject to auto-deletion after inactivity | DB row expires; user file remains |
Sources: plans/migration.inventory.md:20-40, src/stores/notesStore.ts:161-177, src-tauri/src/notes/write.rs:10-48
Note Lifecycle Flow
The following diagram illustrates the transition from a new draft to an external file.
Internal Drafts
Drafts are created via the note_create command. The backend generates a unique UUID and creates an empty Markdown file in the application's internal drafts directory.
Auto-save Logic
The frontend maintains a draftSaveTimers map to handle independent debouncing for every open draft. When a user types, the application waits for 500ms of inactivity before invoking note_write_draft.
- Validation: The backend explicitly rejects auto-save requests for notes that are not marked as
storage: "draft". - Derivation: During every write, the system re-derives the note's
titleandpreviewfrom the first non-empty lines of the Markdown content.
Sources: src-tauri/src/notes/write.rs:80-84, src/stores/notesStore.ts:161-177, src/lib/tauri/shim.ts:117-133
External Files (Saved Notes)
A note becomes an "External File" through the Save As process or by Importing an existing file.
Scoped File Access
On macOS, accessing external files requires security-scoped bookmarks. The application uses a with_scoped_file utility to resolve these bookmarks before performing read or write operations.
- Importing: When a user opens a file via
Cmd+O, the backend reads the file, creates a bookmark (on macOS), and stores the path in the database. - Saving: Manual saves via
Cmd+Sfor external files do not trigger the system file picker; they write directly to the previously established path using the stored bookmark.
Sources: src-tauri/src/notes/import.rs:13-25, src-tauri/src/notes/write.rs:100-115, plans/migration.inventory.md:313-335
Transition: Draft to Saved
The save_as command handles the conversion. It performs the following sequence:
- Writes the content to the new user-defined path.
- Deletes the original internal draft file from
app_data_dir/drafts/. - Updates the database row's
storagefield to"saved". - Persists the new
file_pathand any generated securitybookmark.
pub(super) fn save_as(
conn: &Connection,
paths: &AppPaths,
id: &str,
new_path: &Path,
content: &str,
) -> Result<NoteMeta, String> {
// ... write to external path ...
if meta.storage == NoteStorage::Draft {
let _ = std::fs::remove_file(&meta.file_path);
}
// ... update DB storage to NoteStorage::Saved ...
}
Sources: src-tauri/src/notes/write.rs:130-145
Data Consistency and Safety
The system implements specific guards to prevent data loss or unintended file modification:
- Dirty Tracking: The frontend tracks "dirty" states only for Saved notes. Since drafts auto-save, they are never considered dirty. If a user attempts to trash a dirty saved note, the system prompts with a "Save changes?" dialog.
- Trash Behavior: When a Draft is trashed, its file is physically moved to an internal
trash/directory. When an External File is trashed, the user's file is left untouched on the filesystem; only the application's database reference is updated and eventually removed. - Duplicate Prevention: During import, the system checks if a note with the same
file_pathalready exists. If found, it restores the existing record instead of creating a duplicate.
Sources: src/routes/pageActions.ts:98-120, src-tauri/src/notes/import.rs:38-60, plans/migration.inventory.md:195-215
Conclusion
The distinction between Drafts and External Files is central to Augenblick's philosophy of clutter reduction. By keeping drafts internal and ephemeral, the app reduces the friction of note-taking, while the robust conversion and import systems ensure that important documentation can be securely managed as standard Markdown files.