syntax = "proto3";

package nexuscrm.common.v1;

option go_package = "github.com/pingcap-inc/nexuscrm-contract/wire-go/gen/common/v1;commonv1";

message ProtocolVersion {
  uint32 major = 1;
  uint32 minor = 2;
}

message CapabilityVersion {
  string name = 1;
  uint32 major = 2;
  uint32 minor = 3;
}

message ConsistencyReceipts {
  ProtocolVersion protocol_version = 1;
  uint64 catalog_revision = 2;
  uint64 schema_generation = 3;
  uint64 engine_generation = 4;
  uint64 security_epoch = 5;
  CapabilityVersion capability_version = 6;
}

enum ErrorCategory {
  ERROR_CATEGORY_UNSPECIFIED = 0;
  ERROR_CATEGORY_INVALID_REQUEST = 1;
  ERROR_CATEGORY_UNAUTHENTICATED = 2;
  ERROR_CATEGORY_FORBIDDEN = 3;
  ERROR_CATEGORY_MISSING = 4;
  ERROR_CATEGORY_CANCELED = 5;
  ERROR_CATEGORY_DEADLINE_EXCEEDED = 6;
  ERROR_CATEGORY_RESOURCE_EXHAUSTED = 7;
  ERROR_CATEGORY_INCOMPATIBLE = 8;
  ERROR_CATEGORY_STALE_STATE = 9;
  ERROR_CATEGORY_UNAVAILABLE = 10;
  ERROR_CATEGORY_INTERNAL_FAILURE = 11;
  ERROR_CATEGORY_CONFLICT = 12;
}

enum InvalidComponent {
  INVALID_COMPONENT_UNSPECIFIED = 0;
  INVALID_COMPONENT_OBJECT_ID = 1;
  INVALID_COMPONENT_RECORD_ID = 2;
  INVALID_COMPONENT_SELECTED_ROOT_FIELD = 3;
  INVALID_COMPONENT_DEADLINE = 4;
  INVALID_COMPONENT_RESPONSE = 5;
  INVALID_COMPONENT_APP_INSTALLATION_ID = 6;
  INVALID_COMPONENT_RUNTIME_CAPABILITY = 7;
  INVALID_COMPONENT_COMMAND_ID = 8;
  INVALID_COMPONENT_OPERATION = 9;
  INVALID_COMPONENT_FIELD_VALUE = 10;
  INVALID_COMPONENT_BATCH_MODE = 11;
  INVALID_COMPONENT_COMMAND_DATA = 12;
  INVALID_COMPONENT_QUERY_PLAN = 13;
  INVALID_COMPONENT_QUERY_PREDICATE = 14;
  INVALID_COMPONENT_QUERY_SELECTION = 15;
  INVALID_COMPONENT_RELATIONSHIP_FIELD = 16;
  INVALID_COMPONENT_SAVED_VIEW_ID = 17;
}

enum LimitKind {
  LIMIT_KIND_UNSPECIFIED = 0;
  LIMIT_KIND_SELECTED_FIELDS = 1;
  LIMIT_KIND_SEMANTIC_REQUEST_BYTES = 2;
  LIMIT_KIND_SEMANTIC_RESPONSE_BYTES = 3;
  LIMIT_KIND_OBJECT_IDENTIFIER_BYTES = 4;
  LIMIT_KIND_FIELD_IDENTIFIER_BYTES = 5;
  LIMIT_KIND_RECORD_IDENTIFIER_BYTES = 6;
  LIMIT_KIND_ADMISSION = 7;
  LIMIT_KIND_RECORD_COUNT = 8;
  LIMIT_KIND_APP_INSTALLATION_IDENTIFIER_BYTES = 9;
  LIMIT_KIND_CAPABILITY_COUNT = 10;
  LIMIT_KIND_CAPABILITY_IDENTIFIER_BYTES = 11;
  LIMIT_KIND_OPERATION_COUNT = 12;
  LIMIT_KIND_COMMAND_IDENTIFIER_BYTES = 13;
  LIMIT_KIND_WIRE_FRAME_BYTES = 14;
  LIMIT_KIND_FIELD_COUNT = 15;
  LIMIT_KIND_QUERY_PREDICATE_NODES = 16;
  LIMIT_KIND_QUERY_NESTING_DEPTH = 17;
  LIMIT_KIND_QUERY_ORDER_BY_COUNT = 18;
  LIMIT_KIND_QUERY_SUBQUERY_COUNT = 19;
  LIMIT_KIND_QUERY_OFFSET = 20;
  LIMIT_KIND_UPLOAD_BYTES = 21;
}

enum StaleAxis {
  STALE_AXIS_UNSPECIFIED = 0;
  STALE_AXIS_CATALOG_REVISION = 1;
  STALE_AXIS_SECURITY_EPOCH = 2;
}

message InvalidRequestDetail {
  InvalidComponent component = 1;
  string canonical_field_name = 2;
}

message LimitViolationDetail {
  LimitKind kind = 1;
  uint64 approved_maximum = 2;
  // Optional producer pacing advice for an ADMISSION capacity rejection.
  // Capability-specific semantic policy decides whether direct retry is safe.
  uint64 retry_after_milliseconds = 3;
}

message CompatibilityDetail {
  string required_capability = 1;
  uint32 supported_protocol_major = 2;
  uint32 supported_protocol_minor_min = 3;
  uint32 supported_protocol_minor_max = 4;
}

message StaleStateDetail {
  StaleAxis axis = 1;
  uint64 required_revision = 2;
  uint64 served_revision = 3;
}

message UnavailableDetail {
  uint64 retry_after_milliseconds = 1;
}

message InternalFailureDetail {
  string request_id = 1;
}

enum ConflictReason {
  CONFLICT_REASON_UNSPECIFIED = 0;
  CONFLICT_REASON_REVISION_MISMATCH = 1;
  CONFLICT_REASON_REFERENCED = 2;
  CONFLICT_REASON_DEFAULT_REQUIRED = 3;
}

message ConflictDetail {
  ConflictReason reason = 1;
}

// RuntimeErrorDetail contains only reviewed safe details. Internal causes,
// SQL text, raw identifiers, authority, tokens, permission rules, and topology
// have no wire field.
message RuntimeErrorDetail {
  ErrorCategory category = 1;
  oneof detail {
    InvalidRequestDetail invalid_request = 2;
    LimitViolationDetail limit_violation = 3;
    CompatibilityDetail compatibility = 4;
    StaleStateDetail stale_state = 5;
    UnavailableDetail unavailable = 6;
    InternalFailureDetail internal_failure = 7;
    ConflictDetail conflict = 9;
  }
  ConsistencyReceipts receipts = 8;
}
