syntax = "proto3";

import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";

package services.outbox.v1;

service OutboxService {
  rpc Subscribe (SubscribeRequest) returns (stream CalaLedgerEvent) {}
}

message SubscribeRequest {
  optional uint64 after_sequence = 1;
}

message CalaLedgerEvent {
  string id = 1;
  uint64 sequence = 2;
  google.protobuf.Timestamp recorded_at = 3;
  oneof payload {
    bool empty = 4;
    AccountCreated account_created = 5;
    AccountUpdated account_updated = 6;
    AccountSetCreated account_set_created = 7;
    AccountSetUpdated account_set_updated = 8;
    AccountSetMemberCreated account_set_member_created = 9;
    AccountSetMemberRemoved account_set_member_removed = 10;
    JournalCreated journal_created = 11;
    JournalUpdated journal_updated = 12;
    TxTemplateCreated tx_template_created = 13;
    TransactionCreated transaction_created = 14;
    TransactionUpdated transaction_updated = 15;
    EntryCreated entry_created = 16;
    BalanceCreated balance_created = 17;
    BalanceUpdated balance_updated = 18;
  }
}

enum DebitOrCredit {
  DEBIT = 0;
  CREDIT = 1;
}

enum Status {
  ACTIVE = 0;
  LOCKED = 1;
}

enum Layer {
  SETTLED = 0;
  PENDING = 1;
  ENCUMBRANCE = 2;
}

message AccountCreated {
  string data_source_id = 1;
  Account account = 2;
}

message AccountUpdated {
  string data_source_id = 1;
  Account account = 2;
  repeated string fields = 3;
}

message Account {
  string id = 1;
  uint32 version = 2;
  string code = 3;
  string name = 4;
  DebitOrCredit normal_balance_type = 5;
  Status status = 6;
  optional string external_id = 7;
  optional string description = 8;
  optional google.protobuf.Struct metadata = 9;
  AccountConfig config = 10;
}

message AccountConfig {
  bool is_account_set = 1;
  bool eventually_consistent = 2;
}

message AccountSetCreated {
  string data_source_id = 1;
  AccountSet account_set = 2;
}

message AccountSetUpdated {
  string data_source_id = 1;
  AccountSet account_set = 2;
  repeated string fields = 3;
}

message AccountSet {
  string id = 1;
  uint32 version = 2;
  string journal_id = 3;
  string name = 4;
  DebitOrCredit normal_balance_type = 5;
  optional string external_id = 6;
  optional string description = 7;
  optional google.protobuf.Struct metadata = 8;
}

message AccountSetMemberCreated {
  string data_source_id = 1;
  AccountSetMember member = 2;
}

message AccountSetMember {
  string account_set_id = 1;
  oneof member {
    string member_account_id = 2;
    string member_account_set_id = 3;
  }
}

message AccountSetMemberRemoved {
  string data_source_id = 1;
  AccountSetMember member = 2;
}

message JournalCreated {
  string data_source_id = 1;
  Journal journal = 2;
}

message JournalUpdated {
  string data_source_id = 1;
  Journal journal = 2;
  repeated string fields = 3;
}

message Journal {
  string id = 1;
  uint32 version = 2;
  string name = 3;
  Status status = 4;
  optional string code = 5;
  optional string description = 6;
  JournalConfig config = 7;
}

message JournalConfig {
  bool enable_effective_balances = 1;
}

message TxTemplateCreated {
  string data_source_id = 1;
  TxTemplate tx_template = 2;
}

message TxTemplate {
  string id = 1;
  uint32 version = 2;
  string code = 3;
  repeated ParamDefinition params = 4;
  TxTemplateTransaction transaction = 5;
  repeated TxTemplateEntry entries = 6;
  optional string description = 7;
  optional google.protobuf.Struct metadata = 8;
}

message TxTemplateEntry {
  string entry_type = 1;
  string account_id = 2;
  string layer = 3;
  string direction = 4;
  string units = 5;
  string currency = 6;
  optional string description = 7;
  optional string metadata = 8;
}

message TxTemplateTransaction {
  string effective = 1;
  string journal_id = 2;
  optional string correlation_id = 3;
  optional string external_id = 4;
  optional string description = 5;
  optional string metadata = 6;
}

message ParamDefinition {
  string name = 1;
  ParamDataType data_type = 2;
  optional string default = 3;
  optional string description = 4;
}

enum ParamDataType {
  STRING = 0;
  INTEGER = 1;
  DECIMAL = 2;
  BOOLEAN = 3;
  UUID = 4;
  DATE = 5;
  TIMESTAMP = 6;
  JSON = 7;
}

message TransactionCreated {
  string data_source_id = 1;
  Transaction transaction = 2;
}

message TransactionUpdated {
  string data_source_id = 1;
  Transaction transaction = 2;
  repeated string fields = 3;
}

message Transaction {
  string id = 1;
  uint32 version = 2;
  google.protobuf.Timestamp created_at = 3;
  google.protobuf.Timestamp modified_at = 4;
  string journal_id = 5;
  string tx_template_id = 6;
  string effective = 7;
  string correlation_id = 8;
  optional string voided_by = 9;
  optional string void_of = 10;
  repeated string entry_ids = 11;
  optional string external_id = 12;
  optional string description = 13;
  optional google.protobuf.Struct metadata = 14;
}

message EntryCreated {
  string data_source_id = 1;
  Entry entry = 2;
}

message Entry {
  string id = 1; 
  uint32 version = 2;
  string transaction_id = 3;
  string journal_id = 4;
  string account_id = 5;
  string entry_type = 6;
  uint32 sequence = 7;
  Layer layer = 8;
  string units = 9;
  string currency = 10;
  DebitOrCredit direction = 11;
  optional string description = 12;
  optional google.protobuf.Struct metadata = 13;
}

message BalanceCreated {
  string data_source_id = 1;
  Balance balance = 2;
}

message BalanceUpdated {
  string data_source_id = 1;
  Balance balance = 2;
}

message Balance {
  string journal_id = 1;
  string account_id = 2;
  string currency = 3;
  uint32 version = 4;
  google.protobuf.Timestamp created_at = 5;
  google.protobuf.Timestamp modified_at = 6;
  string entry_id = 7;
  BalanceAmount settled = 8;
  BalanceAmount pending = 9;
  BalanceAmount encumbrance = 10;
}

message BalanceAmount {
  string dr_balance = 1;
  string cr_balance = 2;
  string entry_id = 3;
  google.protobuf.Timestamp modified_at = 4;
}
