TeraComposerModels.swift (3635B)
1 import Foundation 2 3 /// Stable account and local context, independent of runtime generation and relay settings. 4 struct TeraComposerScope: Sendable, Equatable, Hashable { 5 let authorPublicKey: String 6 let localNetworkID: String 7 } 8 9 /// Reference metadata only. Loading this value never creates a file or upload-ready handle. 10 struct TeraComposerMedia: Sendable, Equatable, Hashable { 11 var opaqueReference: String 12 var sha256: String 13 var mediaType: String 14 var byteSize: UInt64 15 var width: UInt32 16 var height: UInt32 17 var alt: String 18 var preparedAtUnixSeconds: UInt64 19 } 20 21 struct TeraComposerForm: Sendable, Equatable, Hashable { 22 var commandType: TeraAddCommandType 23 var content: String = "" 24 var identifier: String? 25 var title: String? 26 var summary: String? 27 var location: String? 28 var eventTiming: TeraEventTiming? 29 var eventStartDate: String? 30 var eventEndDate: String? 31 var eventStartUnixSeconds: UInt64? 32 var eventEndUnixSeconds: UInt64? 33 var eventTimezone: String? 34 var priceAmount: String? 35 var currency: String? 36 var unit: String? 37 var quantity: String? 38 var foodPublishedAtUnixSeconds: UInt64? 39 var foodStatus: String? 40 var media: [TeraComposerMedia] = [] 41 42 init(commandType: TeraAddCommandType) { 43 self.commandType = commandType 44 } 45 46 init(editing form: TeraAddForm) { 47 commandType = form.commandType 48 content = form.content 49 identifier = form.identifier 50 title = form.title 51 summary = form.summary 52 location = form.location 53 eventTiming = form.eventTiming 54 eventStartDate = form.eventStartDate 55 eventEndDate = form.eventEndDate 56 eventStartUnixSeconds = form.eventStartUnixSeconds 57 eventEndUnixSeconds = form.eventEndUnixSeconds 58 eventTimezone = form.eventTimezone 59 priceAmount = form.priceAmount 60 currency = form.currency 61 unit = form.unit 62 quantity = form.quantity 63 foodPublishedAtUnixSeconds = form.foodPublishedAtUnixSeconds 64 foodStatus = form.foodStatus 65 media = form.media.map { value in 66 TeraComposerMedia( 67 opaqueReference: value.opaqueReference, 68 sha256: value.sha256, 69 mediaType: value.mediaType, 70 byteSize: value.byteSize, 71 width: value.width, 72 height: value.height, 73 alt: value.alt, 74 preparedAtUnixSeconds: value.preparedAtUnixSeconds 75 ) 76 } 77 } 78 } 79 80 struct TeraComposerSaveRequest: Sendable, Equatable { 81 let scope: TeraComposerScope 82 let id: String 83 let expectedRevision: UInt64? 84 let editSequence: UInt64 85 let form: TeraComposerForm 86 } 87 88 struct TeraComposerDraft: Sendable, Equatable { 89 let scope: TeraComposerScope 90 let id: String 91 let revision: UInt64 92 let editSequence: UInt64 93 let form: TeraComposerForm 94 } 95 96 /// Acknowledges this exact historical revision; newer edits require their own receipt. 97 struct TeraComposerSaveReceipt: Sendable, Equatable { 98 let draft: TeraComposerDraft 99 let replayed: Bool 100 } 101 102 struct TeraComposerSummary: Sendable, Equatable { 103 let id: String 104 let revision: UInt64 105 let editSequence: UInt64 106 let commandType: TeraAddCommandType 107 let createdAtUnixMilliseconds: UInt64 108 let updatedAtUnixMilliseconds: UInt64 109 } 110 111 enum TeraComposerRepairReason: Sendable, Equatable { 112 case unsupportedSchema 113 case corruptRecord 114 } 115 116 enum TeraComposerListEntry: Sendable, Equatable { 117 case draft(TeraComposerSummary) 118 /// This locator may contain invalid ID bytes and must never become an editing ID. 119 case repair(draftKey: String, revision: UInt64, reason: TeraComposerRepairReason) 120 } 121 122 struct TeraComposerPage: Sendable, Equatable { 123 let scope: TeraComposerScope 124 let entries: [TeraComposerListEntry] 125 let nextCursor: String? 126 }