syntax = "proto3";

// Package order.v1 is the contract-first API surface for the Orders service.
// The .proto file is authoritative: Go types in gen/order/v1 are generated
// from it with `buf generate` (or the protoc fallback in the Makefile).
package order.v1;

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

// go_package controls the import path + package name of the generated Go code.
option go_package = "github.com/nabin747/go-from-zero/projects/05-grpc-microservice/gen/order/v1;orderv1";

// OrderStatus models the lifecycle of an order. Field numbers are stable and
// must never be reused so the schema can evolve without breaking clients.
enum OrderStatus {
  ORDER_STATUS_UNSPECIFIED = 0;
  ORDER_STATUS_PENDING     = 1;
  ORDER_STATUS_CONFIRMED   = 2;
  ORDER_STATUS_SHIPPED     = 3;
  ORDER_STATUS_DELIVERED   = 4;
  ORDER_STATUS_CANCELLED   = 5;
}

// OrderItem is a single line item. Money is expressed in integer cents to
// avoid floating-point rounding errors.
message OrderItem {
  string sku              = 1;
  string name             = 2;
  int32  quantity         = 3;
  int64  unit_price_cents = 4;
}

// Order is the aggregate root. total_cents is computed server-side from the
// items and is output-only: clients cannot set it.
message Order {
  string                    id          = 1;
  string                    customer_id = 2;
  repeated OrderItem        items       = 3;
  OrderStatus               status      = 4;
  int64                     total_cents = 5;
  google.protobuf.Timestamp created_at  = 6;
  google.protobuf.Timestamp updated_at  = 7;
}

// OrderEvent is delivered over the WatchOrders server stream.
message OrderEvent {
  enum Type {
    TYPE_UNSPECIFIED    = 0;
    TYPE_CREATED        = 1;
    TYPE_UPDATED        = 2;
    TYPE_STATUS_CHANGED = 3;
    TYPE_CANCELLED      = 4;
  }
  Type                      type       = 1;
  Order                     order      = 2;
  google.protobuf.Timestamp emitted_at = 3;
}

message CreateOrderRequest {
  string             customer_id = 1;
  repeated OrderItem items       = 2;
}
message CreateOrderResponse {
  Order order = 1;
}

message GetOrderRequest {
  string id = 1;
}
message GetOrderResponse {
  Order order = 1;
}

message ListOrdersRequest {
  string      customer_id = 1; // optional filter
  OrderStatus status      = 2; // optional filter
  int32       page_size   = 3;
  string      page_token  = 4; // opaque cursor
}
message ListOrdersResponse {
  repeated Order orders          = 1;
  string         next_page_token = 2;
}

message UpdateOrderRequest {
  string                    id          = 1;
  repeated OrderItem        items       = 2;
  google.protobuf.FieldMask update_mask = 3;
}
message UpdateOrderResponse {
  Order order = 1;
}

message CancelOrderRequest {
  string id = 1;
}
message CancelOrderResponse {
  Order order = 1;
}

message WatchOrdersRequest {
  string customer_id = 1; // empty = all customers
}

// OrderService exposes five unary RPCs and one server-streaming RPC.
service OrderService {
  rpc CreateOrder(CreateOrderRequest) returns (CreateOrderResponse);
  rpc GetOrder(GetOrderRequest) returns (GetOrderResponse);
  rpc ListOrders(ListOrdersRequest) returns (ListOrdersResponse);
  rpc UpdateOrder(UpdateOrderRequest) returns (UpdateOrderResponse);
  rpc CancelOrder(CancelOrderRequest) returns (CancelOrderResponse);
  rpc WatchOrders(WatchOrdersRequest) returns (stream OrderEvent);
}
