kanban-persistence
Persistence layer for the kanban project management tool. Handles JSON storage, format versioning, and data migration.
Installation
Add to your Cargo.toml:
[]
= { = "../kanban-persistence" }
Features
Progressive Auto-Save
- Dirty Flag Tracking: Changes are marked and queued for persistence
- Debounced Saving: 500ms minimum interval between disk writes to prevent excessive I/O
- Atomic Writes: Temporary file writes with atomic rename for crash safety
- Command Audit Log: All commands are tracked for audit trails
Format Versioning
- V2 JSON Format: Structured format with metadata and version tracking
- Automatic V1→V2 Migration: Legacy files are transparently upgraded on first load
- Backup Creation: V1 files backed up as
.v1.backupbefore migration - Version Detection: Automatic format detection without user intervention
Multi-Instance Support
- Instance IDs: Each application instance has a unique ID for coordination
- Last-Write-Wins: Concurrent modifications resolved by latest timestamp
- File Watching: Detects external changes for reload prompts
- Conflict Resolution: Automatic merging strategies for safe concurrent access
API Reference
JsonFileStore
Main persistence store implementation:
use ;
// Create store
let store = new;
// Get instance ID
let instance_id = store.instance_id;
// Save data
let snapshot = StoreSnapshot ;
store.save.await?;
// Load data (automatically migrates V1 to V2)
let = store.load.await?;
StateManager (kanban-tui)
Manages state mutations and persistence:
use StateManager;
use Command;
let mut manager = new;
// Execute command (sets dirty flag)
manager.execute_with_context?;
// Periodically save (respects 500ms debounce)
manager.save_if_needed.await?;
// Force save immediately (bypasses debounce)
manager.save_now.await?;
Architecture
kanban-core
↑
└── kanban-domain
↑
└── kanban-persistence
↑
└── kanban-tui (StateManager uses persistence)
Command Pattern Flow
- Event Handler collects data and creates Command
- Command is executed via StateManager::execute_command()
- CommandContext applies mutation to data
- Dirty Flag is set by StateManager
- Periodic Timer calls save_if_needed()
- Debounce Check ensures 500ms minimum interval
- Atomic Write saves to disk with temp file + rename
Data Flow
User Input
↓
Event Handler
↓
Command Creation
↓
StateManager::execute_command()
↓
CommandContext::execute()
↓
Data Mutation
↓
Dirty Flag = true
↓
[500ms timer]
↓
StateManager::save_if_needed()
↓
JsonFileStore::save()
↓
Atomic Write
↓
Disk (persisted)
Format Specification
V2 Format
V1 Format (Deprecated)
Legacy format without version field or metadata:
Migration automatically adds metadata and wraps data.
Migration Strategy
Automatic V1→V2 Migration
- Detection:
Migrator::detect_version()checks forversionfield - Backup: Original V1 file copied to
.v1.backup - Transform: Data wrapped with V2 metadata
- Write: Migrated file written atomically
- Logging: Migration progress logged for user visibility
Manual Migration
use ;
// Detect current version
let version = detect_version.await?;
// Migrate if needed
if version == V1
Performance Characteristics
Debouncing Benefits
- Reduced I/O: Prevents disk thrashing during rapid edits
- Better Responsiveness: 500ms debounce balances persistence with UI responsiveness
- Predictable Load: Steady-state save frequency ~2 saves/second maximum
Atomic Write Safety
- Crash Safety: Incomplete writes cannot corrupt file
- Two-Phase Commit: Write to temp, then atomic rename
- Recovery: Interrupted writes leave original file intact
Examples
Setting up Progressive Save
use StateManager;
use ;
let mut manager = new;
// Periodic save task (runs in background)
spawn;
Handling Concurrent Modifications
// When file is modified externally (multi-instance editing)
// JsonFileStore detects the change via file watching
// Application can prompt user for reload with conflict resolution
// Last-write-wins strategy automatically applied
Error Handling
All public APIs return KanbanResult<T>:
use JsonFileStore;
match store.load.await
Dependencies
kanban-core- Foundation types and traitskanban-domain- Domain modelsserde,serde_json- Serializationtokio- Async runtimeuuid- ID generationchrono- Timestampsasync-trait- Async trait supportthiserror- Error handlingnotify- File watching
License
Apache 2.0 - See LICENSE.md for details