Skip to content

Latest commit

 

History

History
399 lines (337 loc) · 11.4 KB

File metadata and controls

399 lines (337 loc) · 11.4 KB

28 — Event Schemas

All events conform to the standard envelope (see 04-event-driven-architecture.md §3). What follows is the per-topic payload schema. Format: Protocol Buffers proto3. Registered in Confluent Schema Registry; compatibility = BACKWARD (FULL_TRANSITIVE for financial topics).

Common Types

syntax = "proto3";
package redbus.common.v1;

import "google/protobuf/timestamp.proto";

message Money {
  // Stored as minor units (e.g. paise for INR) for precision
  int64  amount_minor = 1;
  string currency     = 2;   // ISO 4217
}

message UserRef    { string user_id = 1; }
message OperatorRef{ string operator_id = 1; }
message TripRef    { string trip_id = 1; string journey_date = 2; }   // YYYY-MM-DD
message SeatRef    { string trip_id = 1; string journey_date = 2; string seat_no = 3; }

1. user.signed_up

package redbus.user.v1;
message UserSignedUp {
  string                user_id     = 1;
  string                source      = 2;   // app_android, app_ios, web, partner
  google.protobuf.Timestamp signed_up_at = 3;
  string                country     = 4;
  string                referrer    = 5;
  string                device_id   = 6;
  string                ip_country  = 7;
}

2. user.logged_in

message UserLoggedIn {
  string                user_id      = 1;
  string                method       = 2;  // otp, password, oauth_google, oauth_apple
  string                device_id    = 3;
  google.protobuf.Timestamp at       = 4;
  string                ip_hash      = 5;
  bool                  step_up      = 6;
}

3. booking.created

package redbus.booking.v1;
message BookingCreated {
  string                booking_id   = 1;
  string                pnr          = 2;
  redbus.common.v1.UserRef user      = 3;
  redbus.common.v1.TripRef trip      = 4;
  repeated string       seat_nos     = 5;
  redbus.common.v1.Money total       = 6;
  google.protobuf.Timestamp created_at = 7;
  google.protobuf.Timestamp expires_at = 8;
  string                quote_id     = 9;
  string                source       = 10;
}

4. booking.seats_locked

message BookingSeatsLocked {
  string                booking_id   = 1;
  string                lock_token   = 2;
  repeated redbus.common.v1.SeatRef seats = 3;
  google.protobuf.Timestamp lock_expires_at = 4;
}

5. booking.confirmed

message BookingConfirmed {
  string                booking_id    = 1;
  string                pnr           = 2;
  redbus.common.v1.UserRef user       = 3;
  redbus.common.v1.TripRef trip       = 4;
  repeated string       seat_nos      = 5;
  redbus.common.v1.Money total        = 6;
  string                payment_id    = 7;
  google.protobuf.Timestamp confirmed_at = 8;
  string                operator_id   = 9;
}

6. booking.cancelled

message BookingCancelled {
  string                booking_id    = 1;
  google.protobuf.Timestamp at        = 2;
  string                reason        = 3;   // user_initiated, operator_cancelled, ops_override, fraud
  string                initiated_by  = 4;   // user_id or operator_id or admin id
  redbus.common.v1.Money refund_amount = 5;
  redbus.common.v1.Money penalty_amount = 6;
}

7. booking.expired

message BookingExpired {
  string                booking_id   = 1;
  google.protobuf.Timestamp at       = 2;
  string                reason       = 3;   // payment_timeout, lock_expired
}

8. payment.initiated

package redbus.payment.v1;
message PaymentInitiated {
  string                intent_id    = 1;
  string                booking_id   = 2;
  string                user_id      = 3;
  redbus.common.v1.Money amount      = 4;
  string                method       = 5;   // upi, card, netbanking, wallet
  string                psp          = 6;
  string                idempotency_key = 7;
  google.protobuf.Timestamp at       = 8;
}

9. payment.success

message PaymentSucceeded {
  string                intent_id    = 1;
  string                booking_id   = 2;
  string                user_id      = 3;
  redbus.common.v1.Money amount      = 4;
  string                psp          = 5;
  string                psp_payment_id = 6;
  google.protobuf.Timestamp captured_at = 7;
  string                last4        = 8;       // optional, card-only
  string                bin_country  = 9;
}

10. payment.failed

message PaymentFailed {
  string                intent_id    = 1;
  string                booking_id   = 2;
  string                user_id      = 3;
  string                psp          = 4;
  string                error_code   = 5;       // standardized internal taxonomy
  string                psp_error    = 6;
  google.protobuf.Timestamp at       = 7;
  bool                  retryable    = 8;
}

11. refund.initiated

message RefundInitiated {
  string                refund_id    = 1;
  string                payment_id   = 2;
  string                booking_id   = 3;
  redbus.common.v1.Money amount      = 4;
  string                reason       = 5;       // cancellation, goodwill, dispute
  string                target       = 6;       // source, wallet
  google.protobuf.Timestamp at       = 7;
}

12. refund.completed

message RefundCompleted {
  string                refund_id    = 1;
  string                payment_id   = 2;
  string                booking_id   = 3;
  redbus.common.v1.Money amount      = 4;
  string                psp_refund_id = 5;
  google.protobuf.Timestamp completed_at = 6;
}

13. seat.locked

package redbus.seat.v1;
message SeatLocked {
  redbus.common.v1.SeatRef seat     = 1;
  string                lock_token = 2;
  string                user_id    = 3;
  google.protobuf.Timestamp at     = 4;
  google.protobuf.Timestamp expires_at = 5;
}

14. seat.released

message SeatReleased {
  redbus.common.v1.SeatRef seat     = 1;
  google.protobuf.Timestamp at     = 2;
  string                reason     = 3; // ttl, cancelled, abandoned, ops
}

15. seat.booked

message SeatBooked {
  redbus.common.v1.SeatRef seat     = 1;
  string                booking_id = 2;
  google.protobuf.Timestamp at     = 3;
}

16. seat.inventory.snapshot

message SeatInventorySnapshot {
  redbus.common.v1.TripRef trip     = 1;
  int32                 total       = 2;
  int32                 available   = 3;
  // bitmap of states, 2 bits per seat: 0 avail, 1 lock, 2 booked, 3 blocked
  bytes                 state_bitmap = 4;
  int64                 version     = 5;
  google.protobuf.Timestamp at     = 6;
}

17. notification.send

package redbus.notification.v1;
message NotificationSend {
  string                message_id   = 1;       // ulid
  string                channel      = 2;       // sms, email, push, whatsapp, inapp
  string                template_id  = 3;
  map<string,string>    variables    = 4;
  string                user_id      = 5;       // optional
  string                phone_e164   = 6;       // optional (KMS-encrypted)
  string                email        = 7;       // optional (KMS-encrypted)
  string                topic        = 8;       // booking, marketing, payment...
  string                priority     = 9;       // high, normal, low
  google.protobuf.Timestamp send_after = 10;    // for scheduling
}

18. notification.delivered

message NotificationDelivered {
  string                message_id   = 1;
  string                channel      = 2;
  string                vendor       = 3;
  google.protobuf.Timestamp delivered_at = 4;
}

19. bus.location.updated

package redbus.realtime.v1;
message BusLocationUpdated {
  redbus.common.v1.TripRef trip      = 1;
  double                lat          = 2;
  double                lon          = 3;
  float                 speed_kmph   = 4;
  float                 bearing_deg  = 5;
  google.protobuf.Timestamp at       = 6;
  string                provider     = 7;       // telematics vendor
}

20. eta.updated

message ETAUpdated {
  redbus.common.v1.TripRef trip      = 1;
  string                next_stop_id = 2;
  google.protobuf.Timestamp eta     = 3;
  int32                 delay_min   = 4;
}

21. coupon.applied

package redbus.pricing.v1;
message CouponApplied {
  string                booking_id   = 1;
  string                coupon_code  = 2;
  redbus.common.v1.Money discount    = 3;
  string                user_id      = 4;
  google.protobuf.Timestamp at       = 5;
}

22. wallet.updated

package redbus.wallet.v1;
message WalletUpdated {
  string                user_id      = 1;
  string                txn_id       = 2;
  string                direction    = 3;       // D, C
  redbus.common.v1.Money amount      = 4;
  redbus.common.v1.Money balance_after = 5;
  string                reference    = 6;
  google.protobuf.Timestamp at       = 7;
  string                source       = 8;       // refund, cashback, redemption
}

23. review.created

package redbus.review.v1;
message ReviewCreated {
  string                review_id    = 1;
  string                user_id      = 2;
  string                booking_id   = 3;
  string                operator_id  = 4;
  string                trip_id      = 5;
  int32                 rating       = 6;       // 1-5
  string                text         = 7;
  repeated string       tags         = 8;
  google.protobuf.Timestamp at       = 9;
}

24. price.quote.created

message PriceQuoteCreated {
  string                quote_id     = 1;
  string                user_id      = 2;
  redbus.common.v1.TripRef trip      = 3;
  repeated string       seat_nos     = 4;
  redbus.common.v1.Money base        = 5;
  redbus.common.v1.Money surge       = 6;
  redbus.common.v1.Money discount    = 7;
  redbus.common.v1.Money total       = 8;
  google.protobuf.Timestamp expires_at = 9;
  string                version      = 10;      // pricing-engine version
}

25. audit.events

package redbus.audit.v1;
message AuditEvent {
  string                actor_id     = 1;
  string                actor_role   = 2;
  string                action       = 3;
  string                resource_type = 4;
  string                resource_id  = 5;
  string                before_hash  = 6;       // sha256 of before-state json
  string                after_hash   = 7;
  string                approval_id  = 8;       // checker if any
  string                trace_id     = 9;
  string                ip           = 10;
  string                user_agent   = 11;
  google.protobuf.Timestamp at       = 12;
  string                prev_event_hash = 13;   // tamper-evident chain
}

Schema Evolution Rules

  • New fields → optional with sensible default (forward compat).
  • Never reuse field numbers.
  • Never change field types.
  • Removed fields → mark reserved.
  • For breaking changes: new topic/event type, parallel run, deprecate after one sprint.

Versioning of Topics

For major schema breaks we publish to <topic>.v2. Producers dual-write during migration; consumers migrate first. After migration window, v1 retired.

Consumer Contract

Consumers MUST:

  • Idempotent on event_id.
  • Tolerate unknown fields.
  • Reject malformed events to DLQ, never silently drop.
  • Validate semantic invariants (e.g. amount > 0).