feat: expose result subscription HTTP and WebSocket APIs

This commit is contained in:
2026-09-17 19:57:55 +08:00
parent 1c3300cc5b
commit 8485a662b2
38 changed files with 3462 additions and 26 deletions

View File

@@ -0,0 +1,88 @@
package events
import (
"context"
"time"
"git.yuntuo.hk/k2safe/orbit/internal/fault"
core "git.yuntuo.hk/k2safe/orbit/model"
"git.yuntuo.hk/k2safe/orbit/platform/auth"
platform "git.yuntuo.hk/k2safe/orbit/platform/model"
)
type PageInput struct {
Limit int
Cursor string
State platform.DeliveryState
}
type SubscriptionPage struct {
Items []Subscription `json:"items"`
NextCursor string `json:"next_cursor,omitempty"`
}
type DeliveryPage struct {
Items []Delivery `json:"items"`
NextCursor string `json:"next_cursor,omitempty"`
}
type DeliveryDetail struct {
Delivery Delivery `json:"delivery"`
Event Event `json:"event"`
}
// ConsumerBinding 由认证关系派生,不接受客户端指定应用、队列或凭据归属。
type ConsumerBinding struct {
ApplicationID core.ID
SubscriptionID core.ID
QueueID core.ID
Enabled bool
ServerTime time.Time
}
func normalizePage(in PageInput) (PageInput, error) {
if in.Limit == 0 {
in.Limit = 20
}
if in.Limit < 1 || in.Limit > 100 || len(in.Cursor) > 2048 {
return in, fault.Invalid("invalid event page")
}
switch in.State {
case "", platform.DeliveryPending, platform.DeliveryLeased, platform.DeliveryAcked, platform.DeliveryExpired:
default:
return in, fault.Invalid("invalid delivery state")
}
return in, nil
}
func (s *Service) List(ctx context.Context, t auth.Token, queue core.ID, in PageInput) (SubscriptionPage, error) {
in, err := normalizePage(in)
if err != nil {
return SubscriptionPage{}, err
}
if queue.Validate() != nil || in.State != "" {
return SubscriptionPage{}, fault.Invalid("invalid subscription query")
}
return s.store.ListSubscriptions(ctx, t, queue, in)
}
func (s *Service) Deliveries(ctx context.Context, t auth.Token, id core.ID, in PageInput) (DeliveryPage, error) {
in, err := normalizePage(in)
if err != nil {
return DeliveryPage{}, err
}
if id.Validate() != nil {
return DeliveryPage{}, fault.Invalid("invalid subscription_id")
}
return s.store.ListDeliveries(ctx, t, id, in)
}
func (s *Service) Detail(ctx context.Context, t auth.Token, sub, id core.ID) (DeliveryDetail, error) {
if sub.Validate() != nil || id.Validate() != nil {
return DeliveryDetail{}, fault.Invalid("invalid subscription_id or delivery_id")
}
return s.store.GetDeliveryDetail(ctx, t, sub, id)
}
func (s *Service) Authorize(ctx context.Context, t auth.Token) error {
return s.store.AuthorizeEvents(ctx, t)
}
func (s *Service) Bind(ctx context.Context, t auth.Token, id core.ID) (ConsumerBinding, error) {
if id.Validate() != nil {
return ConsumerBinding{}, fault.Invalid("invalid subscription_id")
}
return s.store.BindConsumer(ctx, t, id)
}