Workflow: Transfer Ownership

This workflow handles changing the owner of an ObjectInstance (or any container object) through an offer / accept process, ensuring an auditable, atomic transfer.

Flow Steps

  1. Offer Creation – The current owner initiates a TransferOffer from the UI (Ownership tab → Transfer button). Optional escrow or price terms may be added.
  2. Offer Delivery – Backend creates a TransferOffer record and sends a notification to the target user (GraphQL Subscription or email).
  3. Acceptance – The buyer authenticates and clicks Accept; their client signs the offer (JWT) and calls acceptTransferOffer mutation.
  4. Atomic Update (Backend)
    a. Validate signatures, ensure both parties still have the required abilities via RLS.
    b. Update owner_id on the target object_instances (and implicitly all non-instantiated descendants).
    c. Insert TransferEvent audit row (from_owner, to_owner, timestamp).
    d. Commit transaction in both Supabase and Neo4j.
  5. Notification – Push a success toast via subscription to both parties; send email confirmation.

Bulk transfers (e.g., a whole pallet) still require only one ownership update because nested items inherit ownership.

GraphQL Operations

  • mutation createTransferOffer(objectId, toUserId, terms)
  • mutation acceptTransferOffer(offerId, signature)
  • subscription transferEvents(objectId) – optional real-time feed

Data Model Impact

  • Supabase – object_instances.owner_organization_id updated.
  • Neo4j – owner property updated on node.
  • transfer_events table (or audit_log) records history.

Open Items / TODO

  • Escrow smart-contract integration for paid transfers.
  • Support for fractional ownership (see Ownership Handling §6).
  • UI design for offer revisions / counter-offers.