syntax = "proto3";

package nexuscrm.catalog.v1;

import "common/v1/common.proto";

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

// ConsumerViewService serves only caller-authorized immutable projections. It
// has no repository, latest, global, or unscoped method. All methods are
// hosted on the same phase-one private L0 endpoint as the Runtime services.
service ConsumerViewService {
  rpc GetAppMetadataView(GetAppMetadataViewRequest) returns (GetAppMetadataViewResponse);
  rpc WatchAppMetadataView(WatchAppMetadataViewRequest) returns (stream WatchAppMetadataViewResponse);
  rpc GetAppMetadataViewV2(GetAppMetadataViewV2Request) returns (GetAppMetadataViewV2Response);
  rpc WatchAppMetadataViewV2(WatchAppMetadataViewV2Request) returns (stream WatchAppMetadataViewV2Response);
  rpc GetIntegrationBindingView(GetIntegrationBindingViewRequest) returns (GetIntegrationBindingViewResponse);
  rpc WatchIntegrationBindingView(WatchIntegrationBindingViewRequest) returns (stream WatchIntegrationBindingViewResponse);
}

// AppMetadataViewV3Service carries the separately versioned V3 capability
// without changing the published ConsumerViewService Go client interface. It
// is registered on the same private L0 endpoint; this is not another serving
// process, network hop, or Catalog authority.
service AppMetadataViewV3Service {
  rpc GetAppMetadataViewV3(GetAppMetadataViewV3Request) returns (GetAppMetadataViewV3Response);
  rpc WatchAppMetadataViewV3(WatchAppMetadataViewV3Request) returns (stream WatchAppMetadataViewV3Response);
}

message ConsumerViewLineage {
  uint64 catalog_revision = 1;
  uint64 schema_generation = 2;
  uint64 engine_generation = 3;
  string source_snapshot_digest = 4;
  // view_digest is the domain-separated, length-prefixed semantic v1 digest
  // defined by the Catalog consumer contract, never a transport serialization.
  string view_digest = 5;
}

message GetAppMetadataViewRequest {
  optional uint64 min_catalog_revision = 1;
}

message WatchAppMetadataViewRequest {
  optional uint64 after_catalog_revision = 1;
}

message AppMetadataComponent {
  string component_id = 1;
  string component_kind = 2;
  uint32 component_format_version = 3;
  string namespace_id = 4;
  string business_key = 5;
  string definition_version = 6;
  string content_digest = 7;
  bytes canonical_behavior = 8;
}

message AppMetadataView {
  string org_id = 1;
  string app_installation_id = 2;
  string app_id = 3;
  string app_release_digest = 4;
  ConsumerViewLineage lineage = 5;
  repeated AppMetadataComponent components = 6;
  nexuscrm.common.v1.ConsistencyReceipts receipts = 7;
}

message GetAppMetadataViewResponse {
  AppMetadataView view = 1;
}

message WatchAppMetadataViewResponse {
  AppMetadataView view = 1;
}

message GetAppMetadataViewV2Request {
  optional uint64 min_catalog_revision = 1;
}

message WatchAppMetadataViewV2Request {
  optional uint64 after_catalog_revision = 1;
}

message EffectiveMetadataComponent {
  string component_kind = 1;
  uint32 component_format_version = 2;
  string business_key = 3;
  string content_digest = 4;
  bytes canonical_behavior = 5;
}

message AppMetadataViewV2 {
  string org_id = 1;
  string app_installation_id = 2;
  string app_id = 3;
  string app_release_digest = 4;
  ConsumerViewLineage lineage = 5;
  repeated AppMetadataComponent app_components = 6;
  repeated EffectiveMetadataComponent effective_components = 7;
  nexuscrm.common.v1.ConsistencyReceipts receipts = 8;
}

message GetAppMetadataViewV2Response {
  AppMetadataViewV2 view = 1;
}

message WatchAppMetadataViewV2Response {
  AppMetadataViewV2 view = 1;
}

message GetAppMetadataViewV3Request {
  optional uint64 min_catalog_revision = 1;
}

message WatchAppMetadataViewV3Request {
  optional uint64 after_catalog_revision = 1;
}

// AppMetadataViewV3 preserves the complete V2 fact shape under the separately
// versioned V3 capability identity. V1 and V2 remain wire-compatible and keep
// their published semantic response ceilings.
message AppMetadataViewV3 {
  string org_id = 1;
  string app_installation_id = 2;
  string app_id = 3;
  string app_release_digest = 4;
  ConsumerViewLineage lineage = 5;
  repeated AppMetadataComponent app_components = 6;
  repeated EffectiveMetadataComponent effective_components = 7;
  nexuscrm.common.v1.ConsistencyReceipts receipts = 8;
}

message GetAppMetadataViewV3Response {
  AppMetadataViewV3 view = 1;
}

message WatchAppMetadataViewV3Response {
  AppMetadataViewV3 view = 1;
}

message GetIntegrationBindingViewRequest {
  optional uint64 min_catalog_revision = 1;
}

message WatchIntegrationBindingViewRequest {
  optional uint64 after_catalog_revision = 1;
}

enum IntegrationBindingKind {
  INTEGRATION_BINDING_KIND_UNSPECIFIED = 0;
  INTEGRATION_BINDING_KIND_CONNECTOR_INBOUND_ROUTE = 1;
  INTEGRATION_BINDING_KIND_CONNECTOR_CALLOUT_PROFILE = 2;
  INTEGRATION_BINDING_KIND_CONNECTOR_FIELD_MAPPING = 3;
  INTEGRATION_BINDING_KIND_CONNECTOR_PUSH_CONTRACT = 4;
}

// IntegrationBinding is an exact-generation resolution reference inside its
// authorized view, not standalone proof of installation or authority. It
// deliberately carries no connector config or credential value.
message IntegrationBinding {
  IntegrationBindingKind kind = 1;
  string owner_pack = 2;
  string pack_installation_id = 3;
  string pack_payload_digest = 4;
  string business_key = 5;
  uint64 definition_version = 6;
  repeated string credential_refs = 7;
  RuntimeCommandBinding runtime_command = 8;
}

// RuntimeCommandBinding carries the exact neutral Runtime command and immutable
// definition identity authorized for one Integration route. Dynamic provider
// payload remains outside Catalog.
message RuntimeCommandBinding {
  string command_kind = 1;
  uint32 payload_format_version = 2;
  string definition_ref = 3;
  string definition_version = 4;
}

message IntegrationBindingView {
  string org_id = 1;
  string app_installation_id = 2;
  string authorized_workload_id = 3;
  ConsumerViewLineage lineage = 4;
  repeated IntegrationBinding bindings = 5;
  nexuscrm.common.v1.ConsistencyReceipts receipts = 6;
}

message GetIntegrationBindingViewResponse {
  IntegrationBindingView view = 1;
}

message WatchIntegrationBindingViewResponse {
  IntegrationBindingView view = 1;
}
