spacedrive/.tasks/LSYNC-007-syncable-trait.md
2025-10-15 07:02:36 -07:00

3.0 KiB

id, title, status, assignee, parent, priority, tags, design_doc, last_updated
id title status assignee parent priority tags design_doc last_updated
LSYNC-007 Syncable Trait (Device Ownership Aware) Done james LSYNC-000 High
sync
trait
codegen
macro
core/src/infra/sync/NEW_SYNC.md 2025-10-14

Description

Create the Syncable trait that database models implement to enable automatic sync. In the leaderless model, the trait must distinguish between device-owned and shared resources.

Architecture Update: Trait now indicates ownership to determine sync strategy (state-based vs log-based).

Implementation Steps

  1. Define Syncable trait with:
    • SYNC_MODEL: &'static str - Model identifier
    • sync_id() -> Uuid - Global resource ID
    • is_device_owned() -> bool - Determines sync strategy
    • device_id() -> Option<Uuid> - Owner device (if device-owned)
    • exclude_fields() - Optional field exclusion
  2. Create #[derive(Syncable)] macro
  3. Implement for device-owned models: Location, Entry, Volume
  4. Implement for shared models: Tag, Album
  5. Document ownership patterns

Technical Details

  • Location: core/src/infra/sync/syncable.rs
  • Macro location: crates/sync-derive/src/lib.rs
  • Must integrate with SeaORM models
  • Ownership determines: state-based (device-owned) vs log-based (shared)

Example Usage

Device-Owned Resource

impl Syncable for locations::Model {
    const SYNC_MODEL: &'static str = "location";

    fn sync_id(&self) -> Uuid { self.uuid }

    fn is_device_owned(&self) -> bool { true }

    fn device_id(&self) -> Option<Uuid> { Some(self.device_id) }

    fn exclude_fields() -> Option<&'static [&'static str]> {
        Some(&["id", "created_at", "updated_at"])
    }
}

// Sync strategy: State broadcast (no log)

Shared Resource

impl Syncable for tags::Model {
    const SYNC_MODEL: &'static str = "tag";

    fn sync_id(&self) -> Uuid { self.uuid }

    fn is_device_owned(&self) -> bool { false }  // Shared!

    fn device_id(&self) -> Option<Uuid> { None }

    fn exclude_fields() -> Option<&'static [&'static str]> {
        Some(&["id", "created_at"])
    }
}

// Sync strategy: HLC-based log

TransactionManager Integration

impl TransactionManager {
    pub async fn commit<M: Syncable>(&self, model: M) -> Result<M> {
        if model.is_device_owned() {
            self.commit_device_owned(model).await  // State-based
        } else {
            self.commit_shared(model).await        // Log-based with HLC
        }
    }
}

Acceptance Criteria

  • Syncable trait defined with ownership methods
  • Works with SeaORM models
  • Device-owned models: location, entry, volume, device
  • Shared models: tag, collection, content_identity, user_metadata
  • Field exclusion functional
  • FK mappings for integer FKs to UUIDs
  • Registry for dynamic dispatch
  • Integration tests validate sync (10 tests passing)

References

  • core/src/infra/sync/NEW_SYNC.md - Data ownership classification
  • Device-owned examples: Lines 58-126
  • Shared examples: Lines 130-179