Skip to content

Commit b8cb520

Browse files
committed
feat(release): 发布 v1.2.68 并同步全部工作区更新
账号共享改为直接加入并移除预约队列,更新房间详情与成员操作。 加入个人代理管理,完善图像模型、计费重试和网关会话错误契约。 纳入迁移 280、全部现有工作区功能及回归测试,同步使用指南和版本记录。 修复默认测试编译与全量静态检查问题,通过后端和前端发布检查。
1 parent 1f2b410 commit b8cb520

99 files changed

Lines changed: 15772 additions & 18159 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

backend/cmd/server/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.2.67
1+
1.2.68

backend/internal/config/config.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2162,7 +2162,6 @@ func setDefaults() {
21622162
// Account-share staged rollout. Contract behavior stays disabled until the
21632163
// expand schema has been observed and the dedicated contract release runs.
21642164
viper.SetDefault("account_share_rollout.lifecycle_contract_enabled", false)
2165-
viper.SetDefault("account_share_rollout.deferred_queue_binding_enabled", false)
21662165
viper.SetDefault("account_share_rollout.review_room_subject_writes_enabled", false)
21672166
viper.SetDefault("account_share_rollout.quota_mode", AccountShareQuotaModeShadow)
21682167

backend/internal/handler/account_share_mode_handler.go

Lines changed: 12 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -92,22 +92,15 @@ type accountShareListingUpdateRequest struct {
9292
Anthropic5hLimitPercent *float64 `json:"anthropic_5h_limit_percent"`
9393
Anthropic7dLimitPercent *float64 `json:"anthropic_7d_limit_percent"`
9494
Concurrency *int `json:"concurrency"`
95-
EditSessionID string `json:"edit_session_id"`
9695
ForceActiveEdit bool `json:"force_active_edit"`
9796
ExpectedVersion *int64 `json:"expected_version"`
9897
Reason string `json:"reason"`
9998
Confirmed bool `json:"confirmed"`
10099
}
101100

102-
type accountShareListingEditSessionRequest struct {
103-
SessionID string `json:"session_id"`
104-
Force bool `json:"force"`
105-
}
106-
107101
type accountShareJoinIntentRequest struct {
108102
APIKeyID int64 `json:"api_key_id" binding:"required"`
109103
IdleTimeoutMinutes int `json:"idle_timeout_minutes"`
110-
AcceptQueue bool `json:"accept_queue"`
111104
}
112105

113106
type accountShareJoinRequest struct {
@@ -116,11 +109,6 @@ type accountShareJoinRequest struct {
116109
IntentToken string `json:"intent_token" binding:"required"`
117110
ExpectedVersion int64 `json:"expected_version" binding:"required,min=1"`
118111
ExpectedRevisionID int64 `json:"expected_revision_id" binding:"required,min=1"`
119-
AcceptQueue bool `json:"accept_queue"`
120-
}
121-
122-
type accountShareEndRequest struct {
123-
Token string `json:"token" binding:"required"`
124112
}
125113

126114
type accountShareReviewSubmitRequest struct {
@@ -132,11 +120,6 @@ type accountShareIdleTimeoutUpdateRequest struct {
132120
IdleTimeoutMinutes int `json:"idle_timeout_minutes"`
133121
}
134122

135-
type accountShareQueueReorderRequest struct {
136-
APIKeyID int64 `json:"api_key_id" binding:"required"`
137-
MembershipIDs []int64 `json:"membership_ids" binding:"required"`
138-
}
139-
140123
type accountShareRoomCreateRequest struct {
141124
AccountID int64 `json:"account_id" binding:"required"`
142125
IdempotencyKey string `json:"idempotency_key" binding:"required,max=128"`
@@ -389,7 +372,15 @@ func (h *AccountShareModeHandler) ListListings(c *gin.Context) {
389372
response.ErrorFrom(c, err)
390373
return
391374
}
392-
response.Paginated(c, listings, result.Total, result.Page, result.PageSize)
375+
response.Success(c, gin.H{
376+
"items": listings,
377+
"total": result.Total,
378+
"page": result.Page,
379+
"page_size": result.PageSize,
380+
"pages": result.Pages,
381+
"total_exact": !result.Approximate,
382+
"has_more": result.HasMore,
383+
})
393384
}
394385

395386
func (h *AccountShareModeHandler) ListMembershipHistory(c *gin.Context) {
@@ -458,14 +449,8 @@ func (h *AccountShareModeHandler) GetRecommendationUsageProfile(c *gin.Context)
458449
response.Success(c, profile)
459450
}
460451

461-
// ListAvailableProxies 按用户即将分享的账号平台与等级返回可选的平台代理。
462-
// 用户不再拥有代理,只能选择平台代理;platform / account_level 查询参数决定筛选范围。
463-
//
464-
// 这里必须带上调用者自己的遗留归属豁免:更新前用户可以自行上传代理,迁移 256 明确
465-
// 保留了这些代理的 owner_user_id。不带豁免的话,老用户账号上已经绑定的自有代理不会
466-
// 出现在列表里,选择器只能显示成「请选择」,重新授权时又会被 scope 校验拒绝。
467-
// 创建侧的事务内守卫(account_repo.ensureOwnedProxyCapacityForCreateInTx)本来就允许
468-
// owner_user_id = 调用者,这里放开只是让选择器与它保持一致。
452+
// ListAvailableProxies 返回本人代理,以及符合账号平台和等级要求的平台代理。
453+
// 归属范围与账号创建、改绑及 OAuth 校验保持一致,不包含其他用户的专属代理。
469454
func (h *AccountShareModeHandler) ListAvailableProxies(c *gin.Context) {
470455
subject, ok := middleware2.GetAuthSubjectFromContext(c)
471456
if !ok {
@@ -689,7 +674,6 @@ func (h *AccountShareModeHandler) UpdateListing(c *gin.Context) {
689674
Anthropic5hLimitPercent: req.Anthropic5hLimitPercent,
690675
Anthropic7dLimitPercent: req.Anthropic7dLimitPercent,
691676
Concurrency: req.Concurrency,
692-
EditSessionID: req.EditSessionID,
693677
ForceActiveEdit: req.ForceActiveEdit,
694678
ExpectedVersion: req.ExpectedVersion,
695679
Reason: req.Reason,
@@ -707,64 +691,6 @@ func (h *AccountShareModeHandler) UpdateListing(c *gin.Context) {
707691
)
708692
}
709693

710-
func (h *AccountShareModeHandler) BeginListingEdit(c *gin.Context) {
711-
subject, ok := middleware2.GetAuthSubjectFromContext(c)
712-
if !ok {
713-
response.Unauthorized(c, "User not authenticated")
714-
return
715-
}
716-
role, _ := middleware2.GetUserRoleFromContext(c)
717-
listingID, err := parseInt64Param(c, "id")
718-
if err != nil {
719-
response.BadRequest(c, "Invalid listing ID")
720-
return
721-
}
722-
var req accountShareListingEditSessionRequest
723-
if err := c.ShouldBindJSON(&req); err != nil {
724-
response.BadRequest(c, "Invalid request: "+err.Error())
725-
return
726-
}
727-
executeUserRequiredIdempotentJSON(
728-
c,
729-
"account_share_listing_edit_begin",
730-
map[string]any{"listing_id": listingID, "body": req},
731-
service.DefaultWriteIdempotencyTTL(),
732-
func(ctx context.Context, _ string) (any, error) {
733-
return h.service.BeginListingEdit(ctx, subject.UserID, role == service.RoleAdmin, listingID, req.SessionID, req.Force)
734-
},
735-
nil,
736-
)
737-
}
738-
739-
func (h *AccountShareModeHandler) ReleaseListingEdit(c *gin.Context) {
740-
subject, ok := middleware2.GetAuthSubjectFromContext(c)
741-
if !ok {
742-
response.Unauthorized(c, "User not authenticated")
743-
return
744-
}
745-
role, _ := middleware2.GetUserRoleFromContext(c)
746-
listingID, err := parseInt64Param(c, "id")
747-
if err != nil {
748-
response.BadRequest(c, "Invalid listing ID")
749-
return
750-
}
751-
var req accountShareListingEditSessionRequest
752-
if err := c.ShouldBindJSON(&req); err != nil {
753-
response.BadRequest(c, "Invalid request: "+err.Error())
754-
return
755-
}
756-
executeUserRequiredIdempotentJSON(
757-
c,
758-
"account_share_listing_edit_release",
759-
map[string]any{"listing_id": listingID, "body": req},
760-
service.DefaultWriteIdempotencyTTL(),
761-
func(ctx context.Context, _ string) (any, error) {
762-
return h.service.ReleaseListingEdit(ctx, subject.UserID, role == service.RoleAdmin, listingID, req.SessionID)
763-
},
764-
nil,
765-
)
766-
}
767-
768694
func (h *AccountShareModeHandler) JoinListing(c *gin.Context) {
769695
subject, ok := middleware2.GetAuthSubjectFromContext(c)
770696
if !ok {
@@ -787,7 +713,6 @@ func (h *AccountShareModeHandler) JoinListing(c *gin.Context) {
787713
IntentToken: req.IntentToken,
788714
ExpectedVersion: req.ExpectedVersion,
789715
ExpectedRevisionID: req.ExpectedRevisionID,
790-
AcceptQueue: req.AcceptQueue,
791716
})
792717
if err != nil {
793718
logger.FromContext(c.Request.Context()).Warn("account share join failed",
@@ -824,7 +749,6 @@ func (h *AccountShareModeHandler) CreateJoinIntent(c *gin.Context) {
824749
intent, err := h.service.CreateJoinIntent(c.Request.Context(), subject.UserID, listingID, service.CreateAccountShareJoinIntentInput{
825750
APIKeyID: req.APIKeyID,
826751
IdleTimeoutMinutes: req.IdleTimeoutMinutes,
827-
AcceptQueue: req.AcceptQueue,
828752
})
829753
if err != nil {
830754
response.ErrorFrom(c, err)
@@ -857,25 +781,6 @@ func (h *AccountShareModeHandler) UpdateMembershipIdleTimeout(c *gin.Context) {
857781
response.Success(c, membership)
858782
}
859783

860-
func (h *AccountShareModeHandler) ListMembershipQueue(c *gin.Context) {
861-
subject, ok := middleware2.GetAuthSubjectFromContext(c)
862-
if !ok {
863-
response.Unauthorized(c, "User not authenticated")
864-
return
865-
}
866-
apiKeyID, err := parseInt64Param(c, "apiKeyID")
867-
if err != nil {
868-
response.BadRequest(c, "Invalid API key ID")
869-
return
870-
}
871-
memberships, err := h.service.ListMembershipQueue(c.Request.Context(), subject.UserID, apiKeyID)
872-
if err != nil {
873-
response.ErrorFrom(c, err)
874-
return
875-
}
876-
response.Success(c, memberships)
877-
}
878-
879784
func (h *AccountShareModeHandler) GetAPIKeyBindingStatus(c *gin.Context) {
880785
subject, ok := middleware2.GetAuthSubjectFromContext(c)
881786
if !ok {
@@ -895,52 +800,6 @@ func (h *AccountShareModeHandler) GetAPIKeyBindingStatus(c *gin.Context) {
895800
response.Success(c, status)
896801
}
897802

898-
func (h *AccountShareModeHandler) ReorderMembershipQueue(c *gin.Context) {
899-
subject, ok := middleware2.GetAuthSubjectFromContext(c)
900-
if !ok {
901-
response.Unauthorized(c, "User not authenticated")
902-
return
903-
}
904-
var req accountShareQueueReorderRequest
905-
if err := c.ShouldBindJSON(&req); err != nil {
906-
response.BadRequest(c, "Invalid request: "+err.Error())
907-
return
908-
}
909-
memberships, err := h.service.ReorderMembershipQueue(c.Request.Context(), subject.UserID, req.APIKeyID, req.MembershipIDs)
910-
if err != nil {
911-
response.ErrorFrom(c, err)
912-
return
913-
}
914-
response.Success(c, memberships)
915-
}
916-
917-
func (h *AccountShareModeHandler) CreateEndMembershipIntent(c *gin.Context) {
918-
subject, ok := middleware2.GetAuthSubjectFromContext(c)
919-
if !ok {
920-
response.Unauthorized(c, "User not authenticated")
921-
return
922-
}
923-
membershipID, err := parseInt64Param(c, "id")
924-
if err != nil {
925-
response.BadRequest(c, "Invalid membership ID")
926-
return
927-
}
928-
intent, err := h.service.CreateEndMembershipToken(c.Request.Context(), subject.UserID, membershipID)
929-
if err != nil {
930-
response.ErrorFrom(c, err)
931-
return
932-
}
933-
logger.FromContext(c.Request.Context()).Info("account share end intent created",
934-
zap.String("component", "account_share.audit"),
935-
zap.Int64("user_id", subject.UserID),
936-
zap.Int64("membership_id", membershipID),
937-
zap.String("client_ip", c.ClientIP()),
938-
zap.String("user_agent", c.Request.UserAgent()),
939-
zap.String("referer", c.Request.Referer()),
940-
)
941-
response.Success(c, intent)
942-
}
943-
944803
func (h *AccountShareModeHandler) EndMembership(c *gin.Context) {
945804
subject, ok := middleware2.GetAuthSubjectFromContext(c)
946805
if !ok {
@@ -952,10 +811,7 @@ func (h *AccountShareModeHandler) EndMembership(c *gin.Context) {
952811
response.BadRequest(c, "Invalid membership ID")
953812
return
954813
}
955-
// 单阶段结束:token 仅为旧前端兼容,缺省或无效均可直接结束
956-
var req accountShareEndRequest
957-
_ = c.ShouldBindJSON(&req)
958-
membership, err := h.service.EndMembership(c.Request.Context(), subject.UserID, membershipID, req.Token)
814+
membership, err := h.service.EndMembership(c.Request.Context(), subject.UserID, membershipID)
959815
if err != nil {
960816
logger.FromContext(c.Request.Context()).Warn("account share end failed",
961817
zap.String("component", "account_share.audit"),

0 commit comments

Comments
 (0)