Repository navigation
Create NodeStore Trait Abstraction Layer #462
Copy link
Copy link
Closed
Description
Create NodeStore Trait Abstraction Layer
Parent Epic: #461 (SurrealDB Migration)
Phase: 1 - Abstraction Layer
Estimated Time: 3-4 days
Objective
Create a trait-based abstraction layer (NodeStore) that defines the complete database interface, enabling parallel implementations of Turso and SurrealDB without breaking existing code.
Implementation
1. Define NodeStore Trait
File: packages/desktop-app/src-tauri/src/datastore/trait.rs
use async_trait::async_trait;
use anyhow::Result;
use crate::models::{Node, NodeFilter, NodeUpdate};
#[async_trait]
pub trait NodeStore: Send + Sync {
// Core CRUD
async fn create_node(&self, node: Node) -> Result<Node>;
async fn get_node(&self, id: &str) -> Result<Option<Node>>;
async fn update_node(&self, id: &str, update: NodeUpdate) -> Result<Node>;
async fn delete_node(&self, id: &str) -> Result<()>;
// Querying
async fn query_nodes(&self, filter: NodeFilter) -> Result<Vec<Node>>;
async fn search_nodes(&self, query: &str) -> Result<Vec<Node>>;
// Hierarchy
async fn get_children(&self, parent_id: &str) -> Result<Vec<Node>>;
async fn move_node(&self, id: &str, new_parent: Option<&str>) -> Result<()>;
// Properties (SCHEMALESS support)
async fn set_property(&self, id: &str, key: &str, value: serde_json::Value) -> Result<()>;
async fn get_property(&self, id: &str, key: &str) -> Result<Option<serde_json::Value>>;
// Performance
async fn batch_create(&self, nodes: Vec<Node>) -> Result<Vec<Node>>;
async fn transaction<F, T>(&self, f: F) -> Result<T>
where
F: FnOnce() -> Result<T> + Send;
}2. Create Factory Pattern
File: packages/desktop-app/src-tauri/src/datastore/factory.rs
use anyhow::Result;
use std::sync::Arc;
use crate::datastore::NodeStore;
pub async fn create_store(config: &DatabaseConfig) -> Result<Arc<dyn NodeStore>> {
#[cfg(feature = "surrealdb")]
{
use crate::datastore::surreal::SurrealStore;
Ok(Arc::new(SurrealStore::new(config.path.clone()).await?))
}
#[cfg(not(feature = "surrealdb"))]
{
use crate::datastore::turso::TursoStore;
Ok(Arc::new(TursoStore::new(config.connection.clone()).await?))
}
}3. Add Feature Flags
File: packages/desktop-app/src-tauri/Cargo.toml
[features]
default = ["turso"]
turso = []
surrealdb = ["dep:surrealdb"]Acceptance Criteria
- NodeStore trait defined with complete interface
- Factory pattern implemented with feature flag support
- Trait compiles and passes clippy checks
- Feature flags properly configured in Cargo.toml
- Documentation added with usage examples
- All existing code still compiles (no breaking changes)
Testing
- Trait compiles with both feature flags
- Factory pattern correctly selects backend based on features
- No regressions in existing functionality
Dependencies
None - this is the foundation for all other migration work.
References
- Epic SurrealDB Migration - Hybrid Architecture (Desktop-Only) #461: SurrealDB Migration
- Architect's migration plan (trait abstraction section)
Reactions are currently unavailable
Activity
Complete SurrealDB Feasibility PoC - All GO Criteria Met (#460)
Add Epic #461 Phase 1 architectural planning documentation
SurrealDB Migration - Hybrid Architecture (Desktop-Only) (#467)
malibio commentedon Nov 11, 2025
Progress Update: NodeStore Trait Definition Complete ✅
Completed Work
Phase 1, Step 1/3: NodeStore trait abstraction layer has been successfully defined and committed.
packages/core/src/db/node_store.rswith 22 async trait methodspackages/core/src/db/mod.rsto expose NodeStore as public APITrait Method Categories
Commit
feature/issue-461-surrealdb-hybrid-migrationNext Steps
Phase 1, Step 2/3: Extract SQL operations from NodeService to DatabaseService
The next phase is complex and requires careful incremental work:
bun run test:allafter each extraction (zero regressions required)This is the most critical and risky step - SQL extraction must preserve exact semantics.
Estimated Time: 1-2 days for careful incremental extraction with validation
Reference
/docs/architecture/data/node-store-abstraction.md/docs/architecture/data/surrealdb-migration-guide.mdmalibio commentedon Nov 11, 2025
✅ Phase 1 Complete: NodeStore Trait Abstraction Layer
Summary
Successfully completed Issue #462 - Created NodeStore trait abstraction layer and extracted all SQL operations from NodeService to DatabaseService. This establishes the foundation for Phase 2 (SurrealDB migration).
Completed Work
1. NodeStore Trait Definition (22 methods)
2. SQL Extraction (16 methods extracted)
CRUD Operations (4 methods):
create_nodeget_nodeupdate_nodedelete_nodeQuery Operations (2 methods):
query_nodessearch_nodes_by_contentMention Operations (5 methods):
create_mentiondelete_mentionget_outgoing_mentions,get_incoming_mentions,get_mentioning_containersSchema Operation (1 method):
get_schemaBatch Operations (2 methods):
batch_create_nodesbatch_update_nodes3. SurrealDB Architecture Documentation
nodestable + type-specific tables (task,text,project, etc.)task:⟨uuid⟩,project:⟨uuid⟩Test Results
Final Status: ZERO Regressions
Architecture Pattern
Clean Separation:
Parameter Structs:
DbCreateNodeParams- For create_node (7 fields)DbUpdateNodeParams- For update_node (5 fields)Phase 2 Readiness
The abstraction layer is complete and ready for SurrealDB implementation:
Hybrid Schema Design:
nodestable for metadata + embeddingstask,text,project)task:⟨uuid⟩Benefits:
Next Steps (Phase 2)
Create Issue Implement NodeStore Trait for Turso Backend #463: Implement TursoStore wrapper
Create Issue Implement NodeStore Trait for SurrealDB Backend #464: Implement SurrealStore
Migration & Testing
Files Changed
Created:
packages/core/src/db/node_store.rs(758 lines) - Trait definitiondocs/architecture/data/surrealdb-schema-design.md(581 lines) - Schema designModified:
packages/core/src/db/mod.rs- Export NodeStore traitpackages/core/src/db/database.rs- Added 16db_*methods + 2 param structspackages/core/src/services/node_service.rs- Delegates to DatabaseService methodsBranch Status
feature/issue-461-surrealdb-hybrid-migrationReferences
/docs/architecture/data/node-store-abstraction.md/docs/architecture/data/surrealdb-schema-design.md/docs/architecture/data/surrealdb-migration-guide.mdPhase 1 Status: ✅ COMPLETE
Test Regressions: ✅ ZERO
Ready for Phase 2: ✅ YES
Define NodeStore trait abstraction layer (#462)
Extract create_node SQL to DatabaseService (#462)
Extract get_node SQL to DatabaseService (#462)
Extract update_node SQL to DatabaseService (#462)
Extract delete_node SQL to DatabaseService (#462)
Extract query_nodes SQL to DatabaseService (#462)
75 remaining items
Extract query_nodes SQL to DatabaseService (#462)
Extract search_nodes_by_content SQL to DatabaseService (#462)
Extract create_mention SQL to DatabaseService (#462)
Extract delete_mention SQL to DatabaseService (#462)
Extract mention query SQL to DatabaseService (#462)
Extract get_schema SQL to DatabaseService (#462)
Extract batch_create_nodes SQL to DatabaseService (#462)
Extract batch_update_nodes SQL to DatabaseService (#462)
Extract hierarchy SQL methods to DatabaseService (#462)
Extract remaining SQL methods to DatabaseService (#462)
Implement TursoStore wrapper for NodeStore trait (#462)
Fix TursoStore test failures - use TempDir and parse SQLite timestamps
Refactor NodeService to use NodeStore trait (#462)
Complete Phase 1b: Migrate 12 additional NodeStore methods (#462)
Implement A/B Testing Framework for Backend Comparison (#465)