Version: 0.9.78.dev.260506
This commit is contained in:
72
backend/services/tokenstore/rpc/errors.go
Normal file
72
backend/services/tokenstore/rpc/errors.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/LoveLosita/smartflow/backend/shared/respond"
|
||||
tokenstoresv "github.com/LoveLosita/smartflow/backend/services/tokenstore/sv"
|
||||
"google.golang.org/genproto/googleapis/rpc/errdetails"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
const tokenStoreErrorDomain = "smartflow.tokenstore"
|
||||
|
||||
// grpcErrorFromServiceError 负责把 token-store 内部错误收口成 gRPC status。
|
||||
//
|
||||
// 职责边界:
|
||||
// 1. 只处理服务内部错误到跨进程错误的转换;
|
||||
// 2. 不决定 HTTP 状态码,也不直接写前端响应;
|
||||
// 3. 未识别错误统一按 Internal 处理,避免泄露数据库或支付细节。
|
||||
func grpcErrorFromServiceError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var resp respond.Response
|
||||
if errors.As(err, &resp) {
|
||||
return grpcErrorFromResponse(resp)
|
||||
}
|
||||
if errors.Is(err, tokenstoresv.ErrNotImplemented) {
|
||||
return status.Error(codes.Unimplemented, err.Error())
|
||||
}
|
||||
log.Printf("tokenstore rpc internal error: %v", err)
|
||||
return status.Error(codes.Internal, "tokenstore service internal error")
|
||||
}
|
||||
|
||||
func grpcErrorFromResponse(resp respond.Response) error {
|
||||
code := grpcCodeFromRespondStatus(resp.Status)
|
||||
message := strings.TrimSpace(resp.Info)
|
||||
if message == "" {
|
||||
message = strings.TrimSpace(resp.Status)
|
||||
}
|
||||
|
||||
st := status.New(code, message)
|
||||
detail := &errdetails.ErrorInfo{
|
||||
Domain: tokenStoreErrorDomain,
|
||||
Reason: resp.Status,
|
||||
Metadata: map[string]string{
|
||||
"info": resp.Info,
|
||||
},
|
||||
}
|
||||
withDetails, err := st.WithDetails(detail)
|
||||
if err != nil {
|
||||
return st.Err()
|
||||
}
|
||||
return withDetails.Err()
|
||||
}
|
||||
|
||||
func grpcCodeFromRespondStatus(statusValue string) codes.Code {
|
||||
switch strings.TrimSpace(statusValue) {
|
||||
case respond.MissingToken.Status, respond.InvalidToken.Status, respond.InvalidClaims.Status, respond.ErrUnauthorized.Status:
|
||||
return codes.Unauthenticated
|
||||
case respond.MissingParam.Status, respond.WrongParamType.Status, respond.ParamTooLong.Status, respond.WrongUserID.Status:
|
||||
return codes.InvalidArgument
|
||||
}
|
||||
if strings.HasPrefix(strings.TrimSpace(statusValue), "5") {
|
||||
return codes.Internal
|
||||
}
|
||||
return codes.InvalidArgument
|
||||
}
|
||||
313
backend/services/tokenstore/rpc/handler.go
Normal file
313
backend/services/tokenstore/rpc/handler.go
Normal file
@@ -0,0 +1,313 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/LoveLosita/smartflow/backend/shared/respond"
|
||||
"github.com/LoveLosita/smartflow/backend/services/tokenstore/rpc/pb"
|
||||
tokenstoresv "github.com/LoveLosita/smartflow/backend/services/tokenstore/sv"
|
||||
tokencontracts "github.com/LoveLosita/smartflow/backend/shared/contracts/tokenstore"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
pb.UnimplementedTokenStoreServiceServer
|
||||
svc *tokenstoresv.Service
|
||||
}
|
||||
|
||||
func NewHandler(svc *tokenstoresv.Service) *Handler {
|
||||
return &Handler{svc: svc}
|
||||
}
|
||||
|
||||
// service 负责统一校验 RPC 层依赖是否已经注入。
|
||||
//
|
||||
// 职责边界:
|
||||
// 1. 只判断 handler 自身和业务 service 是否可用;
|
||||
// 2. 不负责支付状态流转、订单幂等和 grant 账本写入;
|
||||
// 3. 失败时返回可直接转成 gRPC status 的业务错误。
|
||||
func (h *Handler) service() (*tokenstoresv.Service, error) {
|
||||
if h == nil || h.svc == nil {
|
||||
return nil, errors.New("tokenstore service dependency not initialized")
|
||||
}
|
||||
return h.svc, nil
|
||||
}
|
||||
|
||||
// GetSummary 负责把 Token 概览请求从 gRPC 协议转成内部服务调用。
|
||||
func (h *Handler) GetSummary(ctx context.Context, req *pb.GetTokenSummaryRequest) (*pb.GetTokenSummaryResponse, error) {
|
||||
svc, err := h.service()
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
if req == nil {
|
||||
return nil, grpcErrorFromServiceError(respond.MissingParam)
|
||||
}
|
||||
|
||||
summary, err := svc.GetSummary(ctx, req.ActorUserId)
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
return &pb.GetTokenSummaryResponse{Summary: tokenSummaryToPB(summary)}, nil
|
||||
}
|
||||
|
||||
func (h *Handler) ListProducts(ctx context.Context, req *pb.ListTokenProductsRequest) (*pb.ListTokenProductsResponse, error) {
|
||||
svc, err := h.service()
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
if req == nil {
|
||||
return nil, grpcErrorFromServiceError(respond.MissingParam)
|
||||
}
|
||||
|
||||
items, err := svc.ListProducts(ctx, req.ActorUserId)
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
return &pb.ListTokenProductsResponse{Items: tokenProductsToPB(items)}, nil
|
||||
}
|
||||
|
||||
func (h *Handler) CreateOrder(ctx context.Context, req *pb.CreateTokenOrderRequest) (*pb.CreateTokenOrderResponse, error) {
|
||||
svc, err := h.service()
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
if req == nil {
|
||||
return nil, grpcErrorFromServiceError(respond.MissingParam)
|
||||
}
|
||||
|
||||
order, err := svc.CreateOrder(ctx, tokencontracts.CreateTokenOrderRequest{
|
||||
ActorUserID: req.ActorUserId,
|
||||
ProductID: req.ProductId,
|
||||
Quantity: int(req.Quantity),
|
||||
IdempotencyKey: req.IdempotencyKey,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
return &pb.CreateTokenOrderResponse{Order: tokenOrderToPB(order)}, nil
|
||||
}
|
||||
|
||||
func (h *Handler) ListOrders(ctx context.Context, req *pb.ListTokenOrdersRequest) (*pb.ListTokenOrdersResponse, error) {
|
||||
svc, err := h.service()
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
if req == nil {
|
||||
return nil, grpcErrorFromServiceError(respond.MissingParam)
|
||||
}
|
||||
|
||||
items, page, err := svc.ListOrders(ctx, tokencontracts.ListTokenOrdersRequest{
|
||||
ActorUserID: req.ActorUserId,
|
||||
Page: int(req.Page),
|
||||
PageSize: int(req.PageSize),
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
return &pb.ListTokenOrdersResponse{
|
||||
Items: tokenOrdersToPB(items),
|
||||
Page: tokenPageToPB(page),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (h *Handler) GetOrder(ctx context.Context, req *pb.GetTokenOrderRequest) (*pb.GetTokenOrderResponse, error) {
|
||||
svc, err := h.service()
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
if req == nil {
|
||||
return nil, grpcErrorFromServiceError(respond.MissingParam)
|
||||
}
|
||||
|
||||
order, err := svc.GetOrder(ctx, req.ActorUserId, req.OrderId)
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
return &pb.GetTokenOrderResponse{Order: tokenOrderToPB(order)}, nil
|
||||
}
|
||||
|
||||
func (h *Handler) MockPaidOrder(ctx context.Context, req *pb.MockPaidOrderRequest) (*pb.MockPaidOrderResponse, error) {
|
||||
svc, err := h.service()
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
if req == nil {
|
||||
return nil, grpcErrorFromServiceError(respond.MissingParam)
|
||||
}
|
||||
|
||||
order, err := svc.MockPaidOrder(ctx, tokencontracts.MockPaidOrderRequest{
|
||||
ActorUserID: req.ActorUserId,
|
||||
OrderID: req.OrderId,
|
||||
MockChannel: req.MockChannel,
|
||||
IdempotencyKey: req.IdempotencyKey,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
return &pb.MockPaidOrderResponse{Order: tokenOrderToPB(order)}, nil
|
||||
}
|
||||
|
||||
func (h *Handler) ListGrants(ctx context.Context, req *pb.ListTokenGrantsRequest) (*pb.ListTokenGrantsResponse, error) {
|
||||
svc, err := h.service()
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
if req == nil {
|
||||
return nil, grpcErrorFromServiceError(respond.MissingParam)
|
||||
}
|
||||
|
||||
items, page, err := svc.ListGrants(ctx, tokencontracts.ListTokenGrantsRequest{
|
||||
ActorUserID: req.ActorUserId,
|
||||
Page: int(req.Page),
|
||||
PageSize: int(req.PageSize),
|
||||
Source: req.Source,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
return &pb.ListTokenGrantsResponse{
|
||||
Items: tokenGrantsToPB(items),
|
||||
Page: tokenPageToPB(page),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RecordForumRewardGrant 负责把论坛 outbox 奖励事件转成 token-store 内部账本写入调用。
|
||||
func (h *Handler) RecordForumRewardGrant(ctx context.Context, req *pb.RecordForumRewardGrantRequest) (*pb.RecordForumRewardGrantResponse, error) {
|
||||
svc, err := h.service()
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
if req == nil {
|
||||
return nil, grpcErrorFromServiceError(respond.MissingParam)
|
||||
}
|
||||
|
||||
grant, err := svc.RecordForumRewardGrant(ctx, tokencontracts.RecordForumRewardGrantRequest{
|
||||
EventID: req.EventId,
|
||||
ReceiverUserID: req.ReceiverUserId,
|
||||
Source: req.Source,
|
||||
SourceRefID: req.SourceRefId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, grpcErrorFromServiceError(err)
|
||||
}
|
||||
return &pb.RecordForumRewardGrantResponse{Grant: tokenGrantToPB(grant)}, nil
|
||||
}
|
||||
|
||||
func tokenPageToPB(page tokencontracts.PageResult) *pb.PageResponse {
|
||||
return &pb.PageResponse{
|
||||
Page: int32(page.Page),
|
||||
PageSize: int32(page.PageSize),
|
||||
Total: int32(page.Total),
|
||||
HasMore: page.HasMore,
|
||||
}
|
||||
}
|
||||
|
||||
func tokenSummaryToPB(summary *tokencontracts.TokenSummary) *pb.TokenSummary {
|
||||
if summary == nil {
|
||||
return nil
|
||||
}
|
||||
return &pb.TokenSummary{
|
||||
RecordedTokenTotal: summary.RecordedTokenTotal,
|
||||
AppliedTokenTotal: summary.AppliedTokenTotal,
|
||||
PendingApplyTokenTotal: summary.PendingApplyTokenTotal,
|
||||
QuotaSyncStatus: summary.QuotaSyncStatus,
|
||||
Tip: summary.Tip,
|
||||
}
|
||||
}
|
||||
|
||||
func tokenProductToPB(product tokencontracts.TokenProductView) *pb.TokenProductView {
|
||||
return &pb.TokenProductView{
|
||||
ProductId: product.ProductID,
|
||||
Name: product.Name,
|
||||
Description: product.Description,
|
||||
TokenAmount: product.TokenAmount,
|
||||
PriceCent: product.PriceCent,
|
||||
PriceText: product.PriceText,
|
||||
Currency: product.Currency,
|
||||
Badge: product.Badge,
|
||||
Status: product.Status,
|
||||
SortOrder: int32(product.SortOrder),
|
||||
}
|
||||
}
|
||||
|
||||
func tokenProductsToPB(items []tokencontracts.TokenProductView) []*pb.TokenProductView {
|
||||
if len(items) == 0 {
|
||||
return nil
|
||||
}
|
||||
result := make([]*pb.TokenProductView, 0, len(items))
|
||||
for i := range items {
|
||||
result = append(result, tokenProductToPB(items[i]))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func tokenGrantToPB(grant *tokencontracts.TokenGrantView) *pb.TokenGrantView {
|
||||
if grant == nil {
|
||||
return nil
|
||||
}
|
||||
return &pb.TokenGrantView{
|
||||
GrantId: grant.GrantID,
|
||||
EventId: grant.EventID,
|
||||
Source: grant.Source,
|
||||
SourceLabel: grant.SourceLabel,
|
||||
Amount: grant.Amount,
|
||||
Status: grant.Status,
|
||||
QuotaApplied: grant.QuotaApplied,
|
||||
Description: grant.Description,
|
||||
CreatedAt: grant.CreatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func tokenGrantsToPB(items []tokencontracts.TokenGrantView) []*pb.TokenGrantView {
|
||||
if len(items) == 0 {
|
||||
return nil
|
||||
}
|
||||
result := make([]*pb.TokenGrantView, 0, len(items))
|
||||
for i := range items {
|
||||
item := items[i]
|
||||
result = append(result, tokenGrantToPB(&item))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func tokenOrderToPB(order *tokencontracts.TokenOrderView) *pb.TokenOrderView {
|
||||
if order == nil {
|
||||
return nil
|
||||
}
|
||||
return &pb.TokenOrderView{
|
||||
OrderId: order.OrderID,
|
||||
OrderNo: order.OrderNo,
|
||||
Status: order.Status,
|
||||
TokenAmount: order.TokenAmount,
|
||||
AmountCent: order.AmountCent,
|
||||
PriceText: order.PriceText,
|
||||
Currency: order.Currency,
|
||||
PaymentMode: order.PaymentMode,
|
||||
Grant: tokenGrantToPB(order.Grant),
|
||||
CreatedAt: order.CreatedAt,
|
||||
PaidAt: tokenStringFromPtr(order.PaidAt),
|
||||
GrantedAt: tokenStringFromPtr(order.GrantedAt),
|
||||
ProductSnapshot: order.ProductSnapshot,
|
||||
ProductName: order.ProductName,
|
||||
Quantity: int32(order.Quantity),
|
||||
}
|
||||
}
|
||||
|
||||
func tokenOrdersToPB(items []tokencontracts.TokenOrderView) []*pb.TokenOrderView {
|
||||
if len(items) == 0 {
|
||||
return nil
|
||||
}
|
||||
result := make([]*pb.TokenOrderView, 0, len(items))
|
||||
for i := range items {
|
||||
item := items[i]
|
||||
result = append(result, tokenOrderToPB(&item))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func tokenStringFromPtr(value *string) string {
|
||||
if value == nil {
|
||||
return ""
|
||||
}
|
||||
return *value
|
||||
}
|
||||
231
backend/services/tokenstore/rpc/pb/tokenstore.pb.go
Normal file
231
backend/services/tokenstore/rpc/pb/tokenstore.pb.go
Normal file
@@ -0,0 +1,231 @@
|
||||
package pb
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
|
||||
var _ = proto.Marshal
|
||||
|
||||
const _ = proto.ProtoPackageIsVersion3
|
||||
|
||||
type PageResponse struct {
|
||||
Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"`
|
||||
PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
|
||||
Total int32 `protobuf:"varint,3,opt,name=total,proto3" json:"total,omitempty"`
|
||||
HasMore bool `protobuf:"varint,4,opt,name=has_more,json=hasMore,proto3" json:"has_more,omitempty"`
|
||||
}
|
||||
|
||||
func (m *PageResponse) Reset() { *m = PageResponse{} }
|
||||
func (m *PageResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*PageResponse) ProtoMessage() {}
|
||||
|
||||
type TokenSummary struct {
|
||||
RecordedTokenTotal int64 `protobuf:"varint,1,opt,name=recorded_token_total,json=recordedTokenTotal,proto3" json:"recorded_token_total,omitempty"`
|
||||
AppliedTokenTotal int64 `protobuf:"varint,2,opt,name=applied_token_total,json=appliedTokenTotal,proto3" json:"applied_token_total,omitempty"`
|
||||
PendingApplyTokenTotal int64 `protobuf:"varint,3,opt,name=pending_apply_token_total,json=pendingApplyTokenTotal,proto3" json:"pending_apply_token_total,omitempty"`
|
||||
QuotaSyncStatus string `protobuf:"bytes,4,opt,name=quota_sync_status,json=quotaSyncStatus,proto3" json:"quota_sync_status,omitempty"`
|
||||
Tip string `protobuf:"bytes,5,opt,name=tip,proto3" json:"tip,omitempty"`
|
||||
}
|
||||
|
||||
func (m *TokenSummary) Reset() { *m = TokenSummary{} }
|
||||
func (m *TokenSummary) String() string { return proto.CompactTextString(m) }
|
||||
func (*TokenSummary) ProtoMessage() {}
|
||||
|
||||
type TokenProductView struct {
|
||||
ProductId uint64 `protobuf:"varint,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
|
||||
TokenAmount int64 `protobuf:"varint,4,opt,name=token_amount,json=tokenAmount,proto3" json:"token_amount,omitempty"`
|
||||
PriceCent int64 `protobuf:"varint,5,opt,name=price_cent,json=priceCent,proto3" json:"price_cent,omitempty"`
|
||||
PriceText string `protobuf:"bytes,6,opt,name=price_text,json=priceText,proto3" json:"price_text,omitempty"`
|
||||
Currency string `protobuf:"bytes,7,opt,name=currency,proto3" json:"currency,omitempty"`
|
||||
Badge string `protobuf:"bytes,8,opt,name=badge,proto3" json:"badge,omitempty"`
|
||||
Status string `protobuf:"bytes,9,opt,name=status,proto3" json:"status,omitempty"`
|
||||
SortOrder int32 `protobuf:"varint,10,opt,name=sort_order,json=sortOrder,proto3" json:"sort_order,omitempty"`
|
||||
}
|
||||
|
||||
func (m *TokenProductView) Reset() { *m = TokenProductView{} }
|
||||
func (m *TokenProductView) String() string { return proto.CompactTextString(m) }
|
||||
func (*TokenProductView) ProtoMessage() {}
|
||||
|
||||
type TokenGrantView struct {
|
||||
GrantId uint64 `protobuf:"varint,1,opt,name=grant_id,json=grantId,proto3" json:"grant_id,omitempty"`
|
||||
EventId string `protobuf:"bytes,2,opt,name=event_id,json=eventId,proto3" json:"event_id,omitempty"`
|
||||
Source string `protobuf:"bytes,3,opt,name=source,proto3" json:"source,omitempty"`
|
||||
SourceLabel string `protobuf:"bytes,4,opt,name=source_label,json=sourceLabel,proto3" json:"source_label,omitempty"`
|
||||
Amount int64 `protobuf:"varint,5,opt,name=amount,proto3" json:"amount,omitempty"`
|
||||
Status string `protobuf:"bytes,6,opt,name=status,proto3" json:"status,omitempty"`
|
||||
QuotaApplied bool `protobuf:"varint,7,opt,name=quota_applied,json=quotaApplied,proto3" json:"quota_applied,omitempty"`
|
||||
Description string `protobuf:"bytes,8,opt,name=description,proto3" json:"description,omitempty"`
|
||||
CreatedAt string `protobuf:"bytes,9,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
}
|
||||
|
||||
func (m *TokenGrantView) Reset() { *m = TokenGrantView{} }
|
||||
func (m *TokenGrantView) String() string { return proto.CompactTextString(m) }
|
||||
func (*TokenGrantView) ProtoMessage() {}
|
||||
|
||||
type TokenOrderView struct {
|
||||
OrderId uint64 `protobuf:"varint,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"`
|
||||
OrderNo string `protobuf:"bytes,2,opt,name=order_no,json=orderNo,proto3" json:"order_no,omitempty"`
|
||||
Status string `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
|
||||
TokenAmount int64 `protobuf:"varint,4,opt,name=token_amount,json=tokenAmount,proto3" json:"token_amount,omitempty"`
|
||||
AmountCent int64 `protobuf:"varint,5,opt,name=amount_cent,json=amountCent,proto3" json:"amount_cent,omitempty"`
|
||||
PriceText string `protobuf:"bytes,6,opt,name=price_text,json=priceText,proto3" json:"price_text,omitempty"`
|
||||
Currency string `protobuf:"bytes,7,opt,name=currency,proto3" json:"currency,omitempty"`
|
||||
PaymentMode string `protobuf:"bytes,8,opt,name=payment_mode,json=paymentMode,proto3" json:"payment_mode,omitempty"`
|
||||
Grant *TokenGrantView `protobuf:"bytes,9,opt,name=grant,proto3" json:"grant,omitempty"`
|
||||
CreatedAt string `protobuf:"bytes,10,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
PaidAt string `protobuf:"bytes,11,opt,name=paid_at,json=paidAt,proto3" json:"paid_at,omitempty"`
|
||||
GrantedAt string `protobuf:"bytes,12,opt,name=granted_at,json=grantedAt,proto3" json:"granted_at,omitempty"`
|
||||
ProductSnapshot string `protobuf:"bytes,13,opt,name=product_snapshot,json=productSnapshot,proto3" json:"product_snapshot,omitempty"`
|
||||
ProductName string `protobuf:"bytes,14,opt,name=product_name,json=productName,proto3" json:"product_name,omitempty"`
|
||||
Quantity int32 `protobuf:"varint,15,opt,name=quantity,proto3" json:"quantity,omitempty"`
|
||||
}
|
||||
|
||||
func (m *TokenOrderView) Reset() { *m = TokenOrderView{} }
|
||||
func (m *TokenOrderView) String() string { return proto.CompactTextString(m) }
|
||||
func (*TokenOrderView) ProtoMessage() {}
|
||||
|
||||
type GetTokenSummaryRequest struct {
|
||||
ActorUserId uint64 `protobuf:"varint,1,opt,name=actor_user_id,json=actorUserId,proto3" json:"actor_user_id,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetTokenSummaryRequest) Reset() { *m = GetTokenSummaryRequest{} }
|
||||
func (m *GetTokenSummaryRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetTokenSummaryRequest) ProtoMessage() {}
|
||||
|
||||
type GetTokenSummaryResponse struct {
|
||||
Summary *TokenSummary `protobuf:"bytes,1,opt,name=summary,proto3" json:"summary,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetTokenSummaryResponse) Reset() { *m = GetTokenSummaryResponse{} }
|
||||
func (m *GetTokenSummaryResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetTokenSummaryResponse) ProtoMessage() {}
|
||||
|
||||
type ListTokenProductsRequest struct {
|
||||
ActorUserId uint64 `protobuf:"varint,1,opt,name=actor_user_id,json=actorUserId,proto3" json:"actor_user_id,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ListTokenProductsRequest) Reset() { *m = ListTokenProductsRequest{} }
|
||||
func (m *ListTokenProductsRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListTokenProductsRequest) ProtoMessage() {}
|
||||
|
||||
type ListTokenProductsResponse struct {
|
||||
Items []*TokenProductView `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ListTokenProductsResponse) Reset() { *m = ListTokenProductsResponse{} }
|
||||
func (m *ListTokenProductsResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListTokenProductsResponse) ProtoMessage() {}
|
||||
|
||||
type CreateTokenOrderRequest struct {
|
||||
ActorUserId uint64 `protobuf:"varint,1,opt,name=actor_user_id,json=actorUserId,proto3" json:"actor_user_id,omitempty"`
|
||||
ProductId uint64 `protobuf:"varint,2,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"`
|
||||
Quantity int32 `protobuf:"varint,3,opt,name=quantity,proto3" json:"quantity,omitempty"`
|
||||
IdempotencyKey string `protobuf:"bytes,4,opt,name=idempotency_key,json=idempotencyKey,proto3" json:"idempotency_key,omitempty"`
|
||||
}
|
||||
|
||||
func (m *CreateTokenOrderRequest) Reset() { *m = CreateTokenOrderRequest{} }
|
||||
func (m *CreateTokenOrderRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*CreateTokenOrderRequest) ProtoMessage() {}
|
||||
|
||||
type CreateTokenOrderResponse struct {
|
||||
Order *TokenOrderView `protobuf:"bytes,1,opt,name=order,proto3" json:"order,omitempty"`
|
||||
}
|
||||
|
||||
func (m *CreateTokenOrderResponse) Reset() { *m = CreateTokenOrderResponse{} }
|
||||
func (m *CreateTokenOrderResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*CreateTokenOrderResponse) ProtoMessage() {}
|
||||
|
||||
type ListTokenOrdersRequest struct {
|
||||
ActorUserId uint64 `protobuf:"varint,1,opt,name=actor_user_id,json=actorUserId,proto3" json:"actor_user_id,omitempty"`
|
||||
Page int32 `protobuf:"varint,2,opt,name=page,proto3" json:"page,omitempty"`
|
||||
PageSize int32 `protobuf:"varint,3,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
|
||||
Status string `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ListTokenOrdersRequest) Reset() { *m = ListTokenOrdersRequest{} }
|
||||
func (m *ListTokenOrdersRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListTokenOrdersRequest) ProtoMessage() {}
|
||||
|
||||
type ListTokenOrdersResponse struct {
|
||||
Items []*TokenOrderView `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
|
||||
Page *PageResponse `protobuf:"bytes,2,opt,name=page,proto3" json:"page,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ListTokenOrdersResponse) Reset() { *m = ListTokenOrdersResponse{} }
|
||||
func (m *ListTokenOrdersResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListTokenOrdersResponse) ProtoMessage() {}
|
||||
|
||||
type GetTokenOrderRequest struct {
|
||||
ActorUserId uint64 `protobuf:"varint,1,opt,name=actor_user_id,json=actorUserId,proto3" json:"actor_user_id,omitempty"`
|
||||
OrderId uint64 `protobuf:"varint,2,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetTokenOrderRequest) Reset() { *m = GetTokenOrderRequest{} }
|
||||
func (m *GetTokenOrderRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetTokenOrderRequest) ProtoMessage() {}
|
||||
|
||||
type GetTokenOrderResponse struct {
|
||||
Order *TokenOrderView `protobuf:"bytes,1,opt,name=order,proto3" json:"order,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetTokenOrderResponse) Reset() { *m = GetTokenOrderResponse{} }
|
||||
func (m *GetTokenOrderResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetTokenOrderResponse) ProtoMessage() {}
|
||||
|
||||
type MockPaidOrderRequest struct {
|
||||
ActorUserId uint64 `protobuf:"varint,1,opt,name=actor_user_id,json=actorUserId,proto3" json:"actor_user_id,omitempty"`
|
||||
OrderId uint64 `protobuf:"varint,2,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"`
|
||||
MockChannel string `protobuf:"bytes,3,opt,name=mock_channel,json=mockChannel,proto3" json:"mock_channel,omitempty"`
|
||||
IdempotencyKey string `protobuf:"bytes,4,opt,name=idempotency_key,json=idempotencyKey,proto3" json:"idempotency_key,omitempty"`
|
||||
}
|
||||
|
||||
func (m *MockPaidOrderRequest) Reset() { *m = MockPaidOrderRequest{} }
|
||||
func (m *MockPaidOrderRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*MockPaidOrderRequest) ProtoMessage() {}
|
||||
|
||||
type MockPaidOrderResponse struct {
|
||||
Order *TokenOrderView `protobuf:"bytes,1,opt,name=order,proto3" json:"order,omitempty"`
|
||||
}
|
||||
|
||||
func (m *MockPaidOrderResponse) Reset() { *m = MockPaidOrderResponse{} }
|
||||
func (m *MockPaidOrderResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*MockPaidOrderResponse) ProtoMessage() {}
|
||||
|
||||
type ListTokenGrantsRequest struct {
|
||||
ActorUserId uint64 `protobuf:"varint,1,opt,name=actor_user_id,json=actorUserId,proto3" json:"actor_user_id,omitempty"`
|
||||
Page int32 `protobuf:"varint,2,opt,name=page,proto3" json:"page,omitempty"`
|
||||
PageSize int32 `protobuf:"varint,3,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
|
||||
Source string `protobuf:"bytes,4,opt,name=source,proto3" json:"source,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ListTokenGrantsRequest) Reset() { *m = ListTokenGrantsRequest{} }
|
||||
func (m *ListTokenGrantsRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListTokenGrantsRequest) ProtoMessage() {}
|
||||
|
||||
type ListTokenGrantsResponse struct {
|
||||
Items []*TokenGrantView `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
|
||||
Page *PageResponse `protobuf:"bytes,2,opt,name=page,proto3" json:"page,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ListTokenGrantsResponse) Reset() { *m = ListTokenGrantsResponse{} }
|
||||
func (m *ListTokenGrantsResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListTokenGrantsResponse) ProtoMessage() {}
|
||||
|
||||
type RecordForumRewardGrantRequest struct {
|
||||
EventId string `protobuf:"bytes,1,opt,name=event_id,json=eventId,proto3" json:"event_id,omitempty"`
|
||||
ReceiverUserId uint64 `protobuf:"varint,2,opt,name=receiver_user_id,json=receiverUserId,proto3" json:"receiver_user_id,omitempty"`
|
||||
Source string `protobuf:"bytes,3,opt,name=source,proto3" json:"source,omitempty"`
|
||||
SourceRefId string `protobuf:"bytes,4,opt,name=source_ref_id,json=sourceRefId,proto3" json:"source_ref_id,omitempty"`
|
||||
}
|
||||
|
||||
func (m *RecordForumRewardGrantRequest) Reset() { *m = RecordForumRewardGrantRequest{} }
|
||||
func (m *RecordForumRewardGrantRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*RecordForumRewardGrantRequest) ProtoMessage() {}
|
||||
|
||||
type RecordForumRewardGrantResponse struct {
|
||||
Grant *TokenGrantView `protobuf:"bytes,1,opt,name=grant,proto3" json:"grant,omitempty"`
|
||||
}
|
||||
|
||||
func (m *RecordForumRewardGrantResponse) Reset() { *m = RecordForumRewardGrantResponse{} }
|
||||
func (m *RecordForumRewardGrantResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*RecordForumRewardGrantResponse) ProtoMessage() {}
|
||||
185
backend/services/tokenstore/rpc/pb/tokenstore_grpc.pb.go
Normal file
185
backend/services/tokenstore/rpc/pb/tokenstore_grpc.pb.go
Normal file
@@ -0,0 +1,185 @@
|
||||
package pb
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
const (
|
||||
TokenStoreService_GetSummary_FullMethodName = "/smartflow.tokenstore.TokenStoreService/GetSummary"
|
||||
TokenStoreService_ListProducts_FullMethodName = "/smartflow.tokenstore.TokenStoreService/ListProducts"
|
||||
TokenStoreService_CreateOrder_FullMethodName = "/smartflow.tokenstore.TokenStoreService/CreateOrder"
|
||||
TokenStoreService_ListOrders_FullMethodName = "/smartflow.tokenstore.TokenStoreService/ListOrders"
|
||||
TokenStoreService_GetOrder_FullMethodName = "/smartflow.tokenstore.TokenStoreService/GetOrder"
|
||||
TokenStoreService_MockPaidOrder_FullMethodName = "/smartflow.tokenstore.TokenStoreService/MockPaidOrder"
|
||||
TokenStoreService_ListGrants_FullMethodName = "/smartflow.tokenstore.TokenStoreService/ListGrants"
|
||||
TokenStoreService_RecordForumRewardGrant_FullMethodName = "/smartflow.tokenstore.TokenStoreService/RecordForumRewardGrant"
|
||||
)
|
||||
|
||||
type TokenStoreServiceClient interface {
|
||||
GetSummary(ctx context.Context, in *GetTokenSummaryRequest, opts ...grpc.CallOption) (*GetTokenSummaryResponse, error)
|
||||
ListProducts(ctx context.Context, in *ListTokenProductsRequest, opts ...grpc.CallOption) (*ListTokenProductsResponse, error)
|
||||
CreateOrder(ctx context.Context, in *CreateTokenOrderRequest, opts ...grpc.CallOption) (*CreateTokenOrderResponse, error)
|
||||
ListOrders(ctx context.Context, in *ListTokenOrdersRequest, opts ...grpc.CallOption) (*ListTokenOrdersResponse, error)
|
||||
GetOrder(ctx context.Context, in *GetTokenOrderRequest, opts ...grpc.CallOption) (*GetTokenOrderResponse, error)
|
||||
MockPaidOrder(ctx context.Context, in *MockPaidOrderRequest, opts ...grpc.CallOption) (*MockPaidOrderResponse, error)
|
||||
ListGrants(ctx context.Context, in *ListTokenGrantsRequest, opts ...grpc.CallOption) (*ListTokenGrantsResponse, error)
|
||||
RecordForumRewardGrant(ctx context.Context, in *RecordForumRewardGrantRequest, opts ...grpc.CallOption) (*RecordForumRewardGrantResponse, error)
|
||||
}
|
||||
|
||||
type tokenStoreServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewTokenStoreServiceClient(cc grpc.ClientConnInterface) TokenStoreServiceClient {
|
||||
return &tokenStoreServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *tokenStoreServiceClient) GetSummary(ctx context.Context, in *GetTokenSummaryRequest, opts ...grpc.CallOption) (*GetTokenSummaryResponse, error) {
|
||||
return invokeTokenStore[GetTokenSummaryResponse](ctx, c.cc, TokenStoreService_GetSummary_FullMethodName, in, opts...)
|
||||
}
|
||||
|
||||
func (c *tokenStoreServiceClient) ListProducts(ctx context.Context, in *ListTokenProductsRequest, opts ...grpc.CallOption) (*ListTokenProductsResponse, error) {
|
||||
return invokeTokenStore[ListTokenProductsResponse](ctx, c.cc, TokenStoreService_ListProducts_FullMethodName, in, opts...)
|
||||
}
|
||||
|
||||
func (c *tokenStoreServiceClient) CreateOrder(ctx context.Context, in *CreateTokenOrderRequest, opts ...grpc.CallOption) (*CreateTokenOrderResponse, error) {
|
||||
return invokeTokenStore[CreateTokenOrderResponse](ctx, c.cc, TokenStoreService_CreateOrder_FullMethodName, in, opts...)
|
||||
}
|
||||
|
||||
func (c *tokenStoreServiceClient) ListOrders(ctx context.Context, in *ListTokenOrdersRequest, opts ...grpc.CallOption) (*ListTokenOrdersResponse, error) {
|
||||
return invokeTokenStore[ListTokenOrdersResponse](ctx, c.cc, TokenStoreService_ListOrders_FullMethodName, in, opts...)
|
||||
}
|
||||
|
||||
func (c *tokenStoreServiceClient) GetOrder(ctx context.Context, in *GetTokenOrderRequest, opts ...grpc.CallOption) (*GetTokenOrderResponse, error) {
|
||||
return invokeTokenStore[GetTokenOrderResponse](ctx, c.cc, TokenStoreService_GetOrder_FullMethodName, in, opts...)
|
||||
}
|
||||
|
||||
func (c *tokenStoreServiceClient) MockPaidOrder(ctx context.Context, in *MockPaidOrderRequest, opts ...grpc.CallOption) (*MockPaidOrderResponse, error) {
|
||||
return invokeTokenStore[MockPaidOrderResponse](ctx, c.cc, TokenStoreService_MockPaidOrder_FullMethodName, in, opts...)
|
||||
}
|
||||
|
||||
func (c *tokenStoreServiceClient) ListGrants(ctx context.Context, in *ListTokenGrantsRequest, opts ...grpc.CallOption) (*ListTokenGrantsResponse, error) {
|
||||
return invokeTokenStore[ListTokenGrantsResponse](ctx, c.cc, TokenStoreService_ListGrants_FullMethodName, in, opts...)
|
||||
}
|
||||
|
||||
func (c *tokenStoreServiceClient) RecordForumRewardGrant(ctx context.Context, in *RecordForumRewardGrantRequest, opts ...grpc.CallOption) (*RecordForumRewardGrantResponse, error) {
|
||||
return invokeTokenStore[RecordForumRewardGrantResponse](ctx, c.cc, TokenStoreService_RecordForumRewardGrant_FullMethodName, in, opts...)
|
||||
}
|
||||
|
||||
func invokeTokenStore[Resp any](ctx context.Context, cc grpc.ClientConnInterface, fullMethod string, in interface{}, opts ...grpc.CallOption) (*Resp, error) {
|
||||
out := new(Resp)
|
||||
err := cc.Invoke(ctx, fullMethod, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type TokenStoreServiceServer interface {
|
||||
GetSummary(context.Context, *GetTokenSummaryRequest) (*GetTokenSummaryResponse, error)
|
||||
ListProducts(context.Context, *ListTokenProductsRequest) (*ListTokenProductsResponse, error)
|
||||
CreateOrder(context.Context, *CreateTokenOrderRequest) (*CreateTokenOrderResponse, error)
|
||||
ListOrders(context.Context, *ListTokenOrdersRequest) (*ListTokenOrdersResponse, error)
|
||||
GetOrder(context.Context, *GetTokenOrderRequest) (*GetTokenOrderResponse, error)
|
||||
MockPaidOrder(context.Context, *MockPaidOrderRequest) (*MockPaidOrderResponse, error)
|
||||
ListGrants(context.Context, *ListTokenGrantsRequest) (*ListTokenGrantsResponse, error)
|
||||
RecordForumRewardGrant(context.Context, *RecordForumRewardGrantRequest) (*RecordForumRewardGrantResponse, error)
|
||||
}
|
||||
|
||||
type UnimplementedTokenStoreServiceServer struct{}
|
||||
|
||||
func (UnimplementedTokenStoreServiceServer) GetSummary(context.Context, *GetTokenSummaryRequest) (*GetTokenSummaryResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetSummary not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedTokenStoreServiceServer) ListProducts(context.Context, *ListTokenProductsRequest) (*ListTokenProductsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListProducts not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedTokenStoreServiceServer) CreateOrder(context.Context, *CreateTokenOrderRequest) (*CreateTokenOrderResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateOrder not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedTokenStoreServiceServer) ListOrders(context.Context, *ListTokenOrdersRequest) (*ListTokenOrdersResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListOrders not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedTokenStoreServiceServer) GetOrder(context.Context, *GetTokenOrderRequest) (*GetTokenOrderResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetOrder not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedTokenStoreServiceServer) MockPaidOrder(context.Context, *MockPaidOrderRequest) (*MockPaidOrderResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method MockPaidOrder not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedTokenStoreServiceServer) ListGrants(context.Context, *ListTokenGrantsRequest) (*ListTokenGrantsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListGrants not implemented")
|
||||
}
|
||||
|
||||
func (UnimplementedTokenStoreServiceServer) RecordForumRewardGrant(context.Context, *RecordForumRewardGrantRequest) (*RecordForumRewardGrantResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RecordForumRewardGrant not implemented")
|
||||
}
|
||||
|
||||
func RegisterTokenStoreServiceServer(s grpc.ServiceRegistrar, srv TokenStoreServiceServer) {
|
||||
s.RegisterService(&TokenStoreService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func tokenStoreUnaryHandler[Req any](methodName string, fullMethod string, invoke func(TokenStoreServiceServer, context.Context, *Req) (interface{}, error)) grpc.MethodDesc {
|
||||
return grpc.MethodDesc{
|
||||
MethodName: methodName,
|
||||
Handler: func(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Req)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return invoke(srv.(TokenStoreServiceServer), ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: fullMethod,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return invoke(srv.(TokenStoreServiceServer), ctx, req.(*Req))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
var TokenStoreService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "smartflow.tokenstore.TokenStoreService",
|
||||
HandlerType: (*TokenStoreServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
tokenStoreUnaryHandler[GetTokenSummaryRequest]("GetSummary", TokenStoreService_GetSummary_FullMethodName, func(s TokenStoreServiceServer, ctx context.Context, req *GetTokenSummaryRequest) (interface{}, error) {
|
||||
return s.GetSummary(ctx, req)
|
||||
}),
|
||||
tokenStoreUnaryHandler[ListTokenProductsRequest]("ListProducts", TokenStoreService_ListProducts_FullMethodName, func(s TokenStoreServiceServer, ctx context.Context, req *ListTokenProductsRequest) (interface{}, error) {
|
||||
return s.ListProducts(ctx, req)
|
||||
}),
|
||||
tokenStoreUnaryHandler[CreateTokenOrderRequest]("CreateOrder", TokenStoreService_CreateOrder_FullMethodName, func(s TokenStoreServiceServer, ctx context.Context, req *CreateTokenOrderRequest) (interface{}, error) {
|
||||
return s.CreateOrder(ctx, req)
|
||||
}),
|
||||
tokenStoreUnaryHandler[ListTokenOrdersRequest]("ListOrders", TokenStoreService_ListOrders_FullMethodName, func(s TokenStoreServiceServer, ctx context.Context, req *ListTokenOrdersRequest) (interface{}, error) {
|
||||
return s.ListOrders(ctx, req)
|
||||
}),
|
||||
tokenStoreUnaryHandler[GetTokenOrderRequest]("GetOrder", TokenStoreService_GetOrder_FullMethodName, func(s TokenStoreServiceServer, ctx context.Context, req *GetTokenOrderRequest) (interface{}, error) {
|
||||
return s.GetOrder(ctx, req)
|
||||
}),
|
||||
tokenStoreUnaryHandler[MockPaidOrderRequest]("MockPaidOrder", TokenStoreService_MockPaidOrder_FullMethodName, func(s TokenStoreServiceServer, ctx context.Context, req *MockPaidOrderRequest) (interface{}, error) {
|
||||
return s.MockPaidOrder(ctx, req)
|
||||
}),
|
||||
tokenStoreUnaryHandler[ListTokenGrantsRequest]("ListGrants", TokenStoreService_ListGrants_FullMethodName, func(s TokenStoreServiceServer, ctx context.Context, req *ListTokenGrantsRequest) (interface{}, error) {
|
||||
return s.ListGrants(ctx, req)
|
||||
}),
|
||||
tokenStoreUnaryHandler[RecordForumRewardGrantRequest]("RecordForumRewardGrant", TokenStoreService_RecordForumRewardGrant_FullMethodName, func(s TokenStoreServiceServer, ctx context.Context, req *RecordForumRewardGrantRequest) (interface{}, error) {
|
||||
return s.RecordForumRewardGrant(ctx, req)
|
||||
}),
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "tokenstore.proto",
|
||||
}
|
||||
73
backend/services/tokenstore/rpc/server.go
Normal file
73
backend/services/tokenstore/rpc/server.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/LoveLosita/smartflow/backend/services/tokenstore/rpc/pb"
|
||||
tokenstoresv "github.com/LoveLosita/smartflow/backend/services/tokenstore/sv"
|
||||
"github.com/zeromicro/go-zero/core/service"
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultListenOn = "0.0.0.0:9095"
|
||||
defaultTimeout = 2 * time.Second
|
||||
)
|
||||
|
||||
type ServerOptions struct {
|
||||
ListenOn string
|
||||
Timeout time.Duration
|
||||
Service *tokenstoresv.Service
|
||||
}
|
||||
|
||||
// Start 启动 token-store zrpc 服务。
|
||||
//
|
||||
// 职责边界:
|
||||
// 1. 只负责装配 go-zero zrpc server 和注册 protobuf service;
|
||||
// 2. 不创建 DB 连接,也不接入 user/auth 授额出口,这些依赖由 cmd 入口注入;
|
||||
// 3. 启动后阻塞当前进程,保持后续“一服务一进程”的迁移方向。
|
||||
func Start(opts ServerOptions) {
|
||||
server, listenOn, err := NewServer(opts)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to build tokenstore zrpc server: %v", err)
|
||||
}
|
||||
defer server.Stop()
|
||||
|
||||
log.Printf("tokenstore zrpc service starting on %s", listenOn)
|
||||
server.Start()
|
||||
}
|
||||
|
||||
// NewServer 负责创建 token-store RPC server,供 cmd 启动和测试复用。
|
||||
func NewServer(opts ServerOptions) (*zrpc.RpcServer, string, error) {
|
||||
if opts.Service == nil {
|
||||
return nil, "", errors.New("tokenstore service dependency not initialized")
|
||||
}
|
||||
|
||||
listenOn := strings.TrimSpace(opts.ListenOn)
|
||||
if listenOn == "" {
|
||||
listenOn = defaultListenOn
|
||||
}
|
||||
timeout := opts.Timeout
|
||||
if timeout <= 0 {
|
||||
timeout = defaultTimeout
|
||||
}
|
||||
|
||||
server, err := zrpc.NewServer(zrpc.RpcServerConf{
|
||||
ServiceConf: service.ServiceConf{
|
||||
Name: "tokenstore.rpc",
|
||||
Mode: service.DevMode,
|
||||
},
|
||||
ListenOn: listenOn,
|
||||
Timeout: int64(timeout / time.Millisecond),
|
||||
}, func(grpcServer *grpc.Server) {
|
||||
pb.RegisterTokenStoreServiceServer(grpcServer, NewHandler(opts.Service))
|
||||
})
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return server, listenOn, nil
|
||||
}
|
||||
156
backend/services/tokenstore/rpc/tokenstore.proto
Normal file
156
backend/services/tokenstore/rpc/tokenstore.proto
Normal file
@@ -0,0 +1,156 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package smartflow.tokenstore;
|
||||
|
||||
option go_package = "github.com/LoveLosita/smartflow/backend/services/tokenstore/rpc/pb";
|
||||
|
||||
service TokenStoreService {
|
||||
rpc GetSummary(GetTokenSummaryRequest) returns (GetTokenSummaryResponse);
|
||||
rpc ListProducts(ListTokenProductsRequest) returns (ListTokenProductsResponse);
|
||||
rpc CreateOrder(CreateTokenOrderRequest) returns (CreateTokenOrderResponse);
|
||||
rpc ListOrders(ListTokenOrdersRequest) returns (ListTokenOrdersResponse);
|
||||
rpc GetOrder(GetTokenOrderRequest) returns (GetTokenOrderResponse);
|
||||
rpc MockPaidOrder(MockPaidOrderRequest) returns (MockPaidOrderResponse);
|
||||
rpc ListGrants(ListTokenGrantsRequest) returns (ListTokenGrantsResponse);
|
||||
rpc RecordForumRewardGrant(RecordForumRewardGrantRequest) returns (RecordForumRewardGrantResponse);
|
||||
}
|
||||
|
||||
message PageResponse {
|
||||
int32 page = 1;
|
||||
int32 page_size = 2;
|
||||
int32 total = 3;
|
||||
bool has_more = 4;
|
||||
}
|
||||
|
||||
message TokenSummary {
|
||||
int64 recorded_token_total = 1;
|
||||
int64 applied_token_total = 2;
|
||||
int64 pending_apply_token_total = 3;
|
||||
string quota_sync_status = 4;
|
||||
string tip = 5;
|
||||
}
|
||||
|
||||
message TokenProductView {
|
||||
uint64 product_id = 1;
|
||||
string name = 2;
|
||||
string description = 3;
|
||||
int64 token_amount = 4;
|
||||
int64 price_cent = 5;
|
||||
string price_text = 6;
|
||||
string currency = 7;
|
||||
string badge = 8;
|
||||
string status = 9;
|
||||
int32 sort_order = 10;
|
||||
}
|
||||
|
||||
message TokenGrantView {
|
||||
uint64 grant_id = 1;
|
||||
string event_id = 2;
|
||||
string source = 3;
|
||||
string source_label = 4;
|
||||
int64 amount = 5;
|
||||
string status = 6;
|
||||
bool quota_applied = 7;
|
||||
string description = 8;
|
||||
string created_at = 9;
|
||||
}
|
||||
|
||||
message TokenOrderView {
|
||||
uint64 order_id = 1;
|
||||
string order_no = 2;
|
||||
string status = 3;
|
||||
int64 token_amount = 4;
|
||||
int64 amount_cent = 5;
|
||||
string price_text = 6;
|
||||
string currency = 7;
|
||||
string payment_mode = 8;
|
||||
TokenGrantView grant = 9;
|
||||
string created_at = 10;
|
||||
string paid_at = 11;
|
||||
string granted_at = 12;
|
||||
string product_snapshot = 13;
|
||||
string product_name = 14;
|
||||
int32 quantity = 15;
|
||||
}
|
||||
|
||||
message GetTokenSummaryRequest {
|
||||
uint64 actor_user_id = 1;
|
||||
}
|
||||
|
||||
message GetTokenSummaryResponse {
|
||||
TokenSummary summary = 1;
|
||||
}
|
||||
|
||||
message ListTokenProductsRequest {
|
||||
uint64 actor_user_id = 1;
|
||||
}
|
||||
|
||||
message ListTokenProductsResponse {
|
||||
repeated TokenProductView items = 1;
|
||||
}
|
||||
|
||||
message CreateTokenOrderRequest {
|
||||
uint64 actor_user_id = 1;
|
||||
uint64 product_id = 2;
|
||||
int32 quantity = 3;
|
||||
string idempotency_key = 4;
|
||||
}
|
||||
|
||||
message CreateTokenOrderResponse {
|
||||
TokenOrderView order = 1;
|
||||
}
|
||||
|
||||
message ListTokenOrdersRequest {
|
||||
uint64 actor_user_id = 1;
|
||||
int32 page = 2;
|
||||
int32 page_size = 3;
|
||||
string status = 4;
|
||||
}
|
||||
|
||||
message ListTokenOrdersResponse {
|
||||
repeated TokenOrderView items = 1;
|
||||
PageResponse page = 2;
|
||||
}
|
||||
|
||||
message GetTokenOrderRequest {
|
||||
uint64 actor_user_id = 1;
|
||||
uint64 order_id = 2;
|
||||
}
|
||||
|
||||
message GetTokenOrderResponse {
|
||||
TokenOrderView order = 1;
|
||||
}
|
||||
|
||||
message MockPaidOrderRequest {
|
||||
uint64 actor_user_id = 1;
|
||||
uint64 order_id = 2;
|
||||
string mock_channel = 3;
|
||||
string idempotency_key = 4;
|
||||
}
|
||||
|
||||
message MockPaidOrderResponse {
|
||||
TokenOrderView order = 1;
|
||||
}
|
||||
|
||||
message ListTokenGrantsRequest {
|
||||
uint64 actor_user_id = 1;
|
||||
int32 page = 2;
|
||||
int32 page_size = 3;
|
||||
string source = 4;
|
||||
}
|
||||
|
||||
message ListTokenGrantsResponse {
|
||||
repeated TokenGrantView items = 1;
|
||||
PageResponse page = 2;
|
||||
}
|
||||
|
||||
message RecordForumRewardGrantRequest {
|
||||
string event_id = 1;
|
||||
uint64 receiver_user_id = 2;
|
||||
string source = 3;
|
||||
string source_ref_id = 4;
|
||||
}
|
||||
|
||||
message RecordForumRewardGrantResponse {
|
||||
TokenGrantView grant = 1;
|
||||
}
|
||||
Reference in New Issue
Block a user