syntax = "proto3";
package angzarr;
option go_package = "github.com/angzarr/angzarr/proto/angzarr";
option java_package = "dev.angzarr";
option java_multiple_files = true;
option csharp_namespace = "Angzarr";
option ruby_package = "Angzarr";

import "angzarr/types.proto";
import "angzarr/process_manager.proto";

// AggregateService: client logic that processes commands and emits events
// Also known as Command Handler in CQRS terminology
// client logic doesn't care about sync - coordinator decides
service AggregateService {
  // Self-description: component type, subscribed domains, handled command types
  rpc GetDescriptor (GetDescriptorRequest) returns (ComponentDescriptor);
  rpc Handle (ContextualCommand) returns (BusinessResponse);
}

// AggregateCoordinatorService: orchestrates command processing for aggregates
service AggregateCoordinatorService {
  // Async processing - fire and forget
  rpc Handle (CommandBook) returns (CommandResponse);
  // Sync processing - waits for completion based on sync_mode
  rpc HandleSync (SyncCommandBook) returns (CommandResponse);
  // Dry-run: execute against temporal state without persisting.
  rpc DryRunHandle (DryRunRequest) returns (CommandResponse);
}

// Speculative execution service - execute without persisting side effects.
// Supports "what-if" scenarios for commands, projectors, sagas, and process managers.
service SpeculativeService {
  // Execute command against temporal state without persisting.
  // Returns speculative events only — no side effects.
  rpc DryRunCommand(DryRunRequest) returns (CommandResponse);

  // Execute projector against provided events without persisting.
  // Returns projection result.
  rpc SpeculateProjector(SpeculateProjectorRequest) returns (Projection);

  // Execute saga against provided events without persisting.
  // Returns commands that would be produced.
  rpc SpeculateSaga(SpeculateSagaRequest) returns (SagaResponse);

  // Execute process manager against provided context without persisting.
  // Returns commands and PM events that would be produced.
  rpc SpeculateProcessManager(SpeculatePmRequest) returns (ProcessManagerHandleResponse);
}

// Request to speculatively execute a projector.
message SpeculateProjectorRequest {
  // Name of the projector to execute.
  string projector_name = 1;
  // Events to project.
  EventBook events = 2;
}

// Request to speculatively execute a saga.
message SpeculateSagaRequest {
  // Name of the saga to execute.
  string saga_name = 1;
  // Source events that trigger the saga.
  EventBook source = 2;
  // Pre-fetched destination state (optional).
  // If empty, saga will run with empty destinations.
  repeated EventBook destinations = 3;
}

// Request to speculatively execute a process manager.
message SpeculatePmRequest {
  // Name of the process manager to execute.
  string pm_name = 1;
  // Triggering events.
  EventBook trigger = 2;
  // Current process manager state (optional).
  EventBook process_state = 3;
  // Pre-fetched destination state (optional).
  repeated EventBook destinations = 4;
}
