TeraPublicationStage.swift (2782B)
1 import Foundation 2 3 enum TeraOutboxState: String, CaseIterable, Sendable, Equatable, Hashable { 4 case draft 5 case mediaPreparing 6 case mediaUploading 7 case readyToSign 8 case signing 9 case signed 10 case queued 11 case delivering 12 case partiallyDelivered 13 case retryable 14 case terminal 15 case cancelled 16 case complete 17 18 var isEditable: Bool { 19 self == .draft || self == .mediaPreparing 20 } 21 22 var canAdvance: Bool { 23 self == .queued || self == .retryable || self == .partiallyDelivered 24 } 25 26 var canCancel: Bool { 27 ![.cancelled, .complete, .terminal].contains(self) 28 } 29 30 var label: String { 31 switch self { 32 case .draft: "Saved on this device." 33 case .mediaPreparing: "Preparing photo." 34 case .mediaUploading: "Photo upload awaiting verification." 35 case .readyToSign, .signing: "Awaiting signing." 36 case .signed: "Signed; local admission is pending." 37 case .queued: "Queued for the saved relays." 38 case .delivering: "Sending to the saved relays." 39 case .partiallyDelivered: "Partially delivered; review the saved relay outcomes." 40 case .retryable: "Saved for retry." 41 case .terminal: "Publication needs attention." 42 case .cancelled: "Local work stopped. Recorded remote effects are retained." 43 case .complete: "Delivery completed for the saved relay policy." 44 } 45 } 46 47 func summary(settlement: TeraOperationSettlement?) -> String { 48 guard let settlement, !settlement.summary.isEmpty else { return label } 49 return "\(label) \(settlement.summary)" 50 } 51 } 52 53 extension TeraOperationSettlement { 54 /// Counts are retained facts, not a global publication or erasure receipt. 55 /// A satisfied plan must never hide other pending or uncertain work. 56 var summary: String { 57 var facts: [String] = [] 58 if deliverySatisfied > 0 { 59 facts.append("Saved relay requirements met for \(deliverySatisfied) of \(deliveryPlans) delivery plans.") 60 } 61 if indeterminate > 0 { 62 facts.append("\(indeterminate) artifact outcomes remain unknown.") 63 } 64 if deliveryPending > 0 || pending > 0 { 65 facts.append("Work remains pending.") 66 } 67 if deliveryRetryable > 0 || retryable > 0 { 68 facts.append("Work is saved for retry; current permissions must be checked.") 69 } 70 if deliveryExhausted > 0 { 71 facts.append("A saved delivery limit was reached; review is needed.") 72 } 73 if failedTerminal > 0 || deliveryFailedTerminal > 0 { 74 facts.append("Some work needs attention after failure.") 75 } 76 if cancelled > 0 || deliveryCancelled > 0 { 77 facts.append("Some local work was stopped; recorded effects are retained.") 78 } 79 if signed > 0 { 80 facts.append("\(signed) signed artifacts retained; \(admitted) admitted locally.") 81 } 82 return facts.joined(separator: " ") 83 } 84 }