@startuml
title Indexer — Peer A discover Peer B (GetPeerRecord + handleNodeGet)

participant "NATS A" as NATSA
participant "DB Pair A (oc-lib)" as DBA
participant "Node A" as NodeA
participant "IndexerService (partagé)" as Indexer
participant "DHT Kademlia" as DHT
participant "NATS A (retour)" as NATSA2

note over NodeA: Trigger : NATS PB_SEARCH PEER\nor callback SubscribeToSearch

NodeA -> DBA: (PEER).Search(DID_B or PeerID_B)
DBA --> NodeA: Local Peer B (if known) → solve DID_B + PeerID_B\nor use search value

loop For every Peer A Binded Indexer 
    NodeA -> Indexer: TempStream /opencloud/record/get/1.0 -> streamAI
    NodeA -> Indexer: streamAI.Encode(GetValue{Key: DID_B, PeerID: PeerID_B})

    Indexer -> Indexer: key = "/node/" + DID_B
    Indexer -> DHT: SearchValue(ctx 10s, "/node/"+DID_B)
    DHT --> Indexer: channel de bytes (PeerRecord B)

    loop Pour every results in DHT
        Indexer -> Indexer: read → PeerRecord B
        alt PeerRecord.PeerID == PeerID_B
            Indexer -> Indexer: resp.Found=true, resp.Records[PeerID_B]=PeerRecord B
            Indexer -> Indexer: StreamRecord B.LastSeen = now (if active heartbeat)
        end
    end

    Indexer -> NodeA: streamAI.Encode(GetResponse{Found:true, Records:{PeerID_B: PeerRecord B}})
end

loop For every PeerRecord founded
    NodeA -> NodeA: rec.Verify() → valid B signature
    NodeA -> NodeA: rec.ExtractPeer(ourDID_A, DID_B, pubKey_B)

    alt ourDID_A == DID_B (it's our proper entry)
        note over NodeA: Republish to refresh TTL
        NodeA -> Indexer: publishPeerRecord(rec) [refresh 2 min]
    end

    NodeA -> NATSA2: SetNATSPub(CREATE_RESOURCE, {PEER, Peer B JSON,\nSearchAttr:"peer_id"})
    NATSA2 -> DBA: Upsert Peer B in DB A
    DBA --> NATSA2: ok
end

NodeA --> NodeA: []*peer.Peer → [Peer B]

@enduml
