gRPC de inventario
Contrato Protocol Buffers de inventory-service. Es la única llamada síncrona interna: order-service reserva, confirma y libera. Decisión en ADR-014.
syntax = "proto3";
package andesretail.inventory.v1;
option java_multiple_files = true;
option java_package = "com.andesretail.inventory.v1";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
// API interna de reservas. Unico punto sincrono entre servicios de dominio:
// order-service llama a inventory-service.
// Diseno en docs/to-be/03-stock-vendible-y-reservas.md.
// Todas las operaciones son idempotentes por order_id.
service InventoryService {
// Reserva todas las lineas o ninguna.
rpc Reserve(ReserveRequest) returns (ReserveResponse);
// Confirma tras el pago aprobado. Si la reserva vencio, intenta reservar de nuevo.
rpc Confirm(ConfirmRequest) returns (ConfirmResponse);
// Libera por pago rechazado, vencimiento o cancelacion.
rpc Release(ReleaseRequest) returns (ReleaseResponse);
rpc GetReservation(GetReservationRequest) returns (GetReservationResponse);
}
enum ReservationStatus {
RESERVATION_STATUS_UNSPECIFIED = 0;
RESERVATION_STATUS_HELD = 1;
RESERVATION_STATUS_CONFIRMED = 2;
RESERVATION_STATUS_RELEASED = 3;
RESERVATION_STATUS_EXPIRED = 4;
RESERVATION_STATUS_CONSUMED = 5;
}
enum ReserveOutcome {
RESERVE_OUTCOME_UNSPECIFIED = 0;
RESERVE_OUTCOME_HELD = 1;
RESERVE_OUTCOME_INSUFFICIENT_STOCK = 2;
RESERVE_OUTCOME_UNKNOWN_SKU = 3;
// El canal no vende desde la ubicación de la línea (política `locations` del canal).
RESERVE_OUTCOME_LOCATION_NOT_ALLOWED = 4;
}
message ReservationLine {
string sku = 1;
string location_id = 2;
int32 quantity = 3;
}
message ReserveRequest {
string order_id = 1;
string partner_id = 2;
string channel = 3;
repeated ReservationLine lines = 4;
// Vigencia de la reserva. Si falta, se usa la del canal (15 minutos por defecto).
google.protobuf.Duration ttl = 5;
string correlation_id = 6;
}
message LineShortage {
string sku = 1;
string location_id = 2;
int32 requested = 3;
int32 available = 4;
}
message ReserveResponse {
ReserveOutcome outcome = 1;
Reservation reservation = 2;
// Lineas que impidieron reservar, cuando outcome no es HELD.
repeated LineShortage shortages = 3;
}
message ConfirmRequest {
string order_id = 1;
string correlation_id = 2;
}
message ReleaseRequest {
string order_id = 1;
// PAYMENT_REJECTED, PAYMENT_TIMEOUT, ORDER_CANCELLED.
string reason = 2;
string correlation_id = 3;
}
message GetReservationRequest {
string order_id = 1;
}
message Reservation {
string reservation_id = 1;
string order_id = 2;
ReservationStatus status = 3;
google.protobuf.Timestamp expires_at = 4;
repeated ReservationLine lines = 5;
}
// Una respuesta por RPC (ADR-014): cada una puede crecer sin tocar a las otras.
message ConfirmResponse {
Reservation reservation = 1;
}
message ReleaseResponse {
Reservation reservation = 1;
}
message GetReservationResponse {
Reservation reservation = 1;
}