syntax = "proto3";

package aerodrome.v1;

import "google/protobuf/timestamp.proto";

// Lightweight lifecycle event published to ace.graph.events.{tenant_id}.{action}
// Actions: node.create, node.update, node.delete, node.bulk_delete,
//          edge.create, edge.delete, edge.bulk_delete
message GraphEvent {
  string tenant_id = 1;   // UUID
  string action = 2;
}

// Rich before/after change published to ace.graph.changes.{tenant_id}
message GraphChange {
  string id = 1;           // UUID — unique change ID
  string tenant_id = 2;    // UUID
  google.protobuf.Timestamp timestamp = 3;
  ChangeActor actor = 4;
  ChangeOperation operation = 5;
}

message ChangeActor {
  optional string user_id = 1;      // UUID
  optional string api_key_id = 2;   // UUID
}

message ChangeOperation {
  oneof op {
    CreateNode create_node = 1;
    UpdateNode update_node = 2;
    DeleteNode delete_node = 3;
    CreateEdge create_edge = 4;
    DeleteEdge delete_edge = 5;
  }
}

message CreateNode { NodeSnapshot node = 1; }
message UpdateNode {
  string id = 1;  // UUID
  NodeSnapshot before = 2;
  NodeSnapshot after = 3;
}
message DeleteNode { NodeSnapshot node = 1; }
message CreateEdge { EdgeSnapshot edge = 1; }
message DeleteEdge { EdgeSnapshot edge = 1; }

// Point-in-time capture of a node
message NodeSnapshot {
  string id = 1;                // UUID
  string node_type = 2;
  optional string label = 3;
}

// Point-in-time capture of an edge
message EdgeSnapshot {
  string id = 1;                // UUID
  string source_id = 2;        // UUID
  string target_id = 3;        // UUID
  string edge_type = 4;
  string provenance = 5;
  double confidence = 6;
  optional string inferred_by = 7;
}

// Full graph state serialized to S3 snapshots
message FullGraphSnapshot {
  string tenant_id = 1;        // UUID
  int64 version = 2;
  google.protobuf.Timestamp timestamp = 3;
  repeated NodeSnapshot nodes = 4;
  repeated EdgeSnapshot edges = 5;
}
