Wire intent→coordinator DocResolver confirm cards→action_executor kinds for comment, reopen, pending-supplements query, and real submit-review execution.
116 lines
4.4 KiB
Go
116 lines
4.4 KiB
Go
package supplementimpact
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"time"
|
||
)
|
||
|
||
// HTTPBatchView is the JSON shape expected by server supplement-impact handlers.
|
||
type HTTPBatchView struct {
|
||
BatchID string `json:"batch_id"`
|
||
ProjectID int64 `json:"project_id"`
|
||
SessionID string `json:"session_id,omitempty"`
|
||
InitiatorUserID int64 `json:"initiator_user_id"`
|
||
SourceKind string `json:"source_kind,omitempty"`
|
||
SourceSummary string `json:"source_summary,omitempty"`
|
||
CoverageStatus string `json:"coverage_status,omitempty"`
|
||
Status string `json:"status"`
|
||
DecisionNonce string `json:"decision_nonce"`
|
||
DecisionDigest string `json:"decision_digest,omitempty"`
|
||
Revision int64 `json:"revision"`
|
||
ExpiresAt time.Time `json:"expires_at"`
|
||
Items []HTTPItemView `json:"items,omitempty"`
|
||
}
|
||
|
||
type HTTPItemView struct {
|
||
DocID string `json:"doc_id"`
|
||
Title string `json:"title,omitempty"`
|
||
ItemKey string `json:"item_key,omitempty"`
|
||
ImpactType string `json:"impact_type,omitempty"`
|
||
Depth int `json:"depth,omitempty"`
|
||
Reason string `json:"reason,omitempty"`
|
||
AuthorClaimedSnapshot bool `json:"author_claimed_snapshot"`
|
||
BusySnapshot bool `json:"busy_snapshot"`
|
||
LockedSnapshot bool `json:"locked_snapshot"`
|
||
ChangeSummary string `json:"change_summary,omitempty"`
|
||
Selected bool `json:"selected"`
|
||
Outcome string `json:"outcome,omitempty"`
|
||
ProposalID string `json:"proposal_id,omitempty"`
|
||
}
|
||
|
||
// HTTPDecision is the CAS decision envelope from HTTP.
|
||
type HTTPDecision struct {
|
||
Kind string
|
||
SelectedDocIDs []string
|
||
DecisionNonce string
|
||
DecisionDigest string
|
||
ExpectedRevision int64
|
||
}
|
||
|
||
// HTTPPort adapts *Service to the server SupplementImpactService port.
|
||
type HTTPPort struct{ Svc *Service }
|
||
|
||
func (p HTTPPort) GetBatch(ctx context.Context, batchID string) (*HTTPBatchView, error) {
|
||
if p.Svc == nil || p.Svc.Store == nil {
|
||
return nil, fmt.Errorf("supplementimpact: not configured")
|
||
}
|
||
b, err := p.Svc.Store.GetBatch(ctx, batchID)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return toHTTPView(b), nil
|
||
}
|
||
|
||
func (p HTTPPort) Decide(ctx context.Context, batchID string, actorUserID int64, in HTTPDecision) (*HTTPBatchView, error) {
|
||
if p.Svc == nil {
|
||
return nil, fmt.Errorf("supplementimpact: not configured")
|
||
}
|
||
b, err := p.Svc.Decide(ctx, DecisionCommand{
|
||
BatchID: batchID, ActorUserID: actorUserID, Kind: in.Kind,
|
||
SelectedDocIDs: in.SelectedDocIDs, DecisionNonce: in.DecisionNonce,
|
||
DecisionDigest: in.DecisionDigest, ExpectedRevision: in.ExpectedRevision,
|
||
})
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return toHTTPView(b), nil
|
||
}
|
||
|
||
func toHTTPView(b *Batch) *HTTPBatchView {
|
||
if b == nil {
|
||
return nil
|
||
}
|
||
v := &HTTPBatchView{
|
||
BatchID: b.BatchID, ProjectID: b.ProjectID, SessionID: b.SessionID,
|
||
InitiatorUserID: b.InitiatorUserID, SourceKind: b.SourceKind, SourceSummary: b.SourceSummary,
|
||
CoverageStatus: b.CoverageStatus, Status: b.Status, DecisionNonce: b.DecisionNonce,
|
||
DecisionDigest: b.DecisionDigest, Revision: b.Revision, ExpiresAt: b.ExpiresAt,
|
||
}
|
||
for _, it := range b.Items {
|
||
v.Items = append(v.Items, HTTPItemView{
|
||
DocID: it.DocID, Title: it.Title, ItemKey: it.ItemKey, ImpactType: it.ImpactType,
|
||
Depth: it.Depth, Reason: it.Reason, AuthorClaimedSnapshot: it.AuthorClaimedSnapshot,
|
||
BusySnapshot: it.BusySnapshot, LockedSnapshot: it.LockedSnapshot, ChangeSummary: it.ChangeSummary,
|
||
Selected: it.Selected, Outcome: it.Outcome, ProposalID: it.ProposalID,
|
||
})
|
||
}
|
||
return v
|
||
}
|
||
|
||
// BuildConfirmCardJSON returns a lightweight map for coordinator InteractiveCardPayload.ProposedContent.
|
||
func BuildConfirmCardMeta(b *Batch) (title, summary string) {
|
||
if b == nil {
|
||
return "补充影响确认", ""
|
||
}
|
||
n := len(b.Items)
|
||
switch b.CoverageStatus {
|
||
case "index_pending", "partial", "failed":
|
||
return "补充影响分析未完成", fmt.Sprintf("覆盖状态:%s(不得视为无影响)。批次 %s", b.CoverageStatus, b.BatchID)
|
||
}
|
||
if n == 0 {
|
||
return "补充已记录", fmt.Sprintf("暂无文档受影响。批次 %s", b.BatchID)
|
||
}
|
||
return fmt.Sprintf("本次补充可能影响 %d 份文档", n), fmt.Sprintf("请勾选要更新的文档。批次 %s;nonce=%s;rev=%d", b.BatchID, b.DecisionNonce, b.Revision)
|
||
}
|