Files
ccn/Packages/Persistence/Sources/Internal/Models/OfferRecord.swift
T

83 lines
1.9 KiB
Swift

import FluentKit
import Foundation
/// A FluentKit model of a single `offers` row.
final class OfferRecord: Model, @unchecked Sendable {
// MARK: Properties
static let schema = "offers"
@ID(key: .id)
var id: UUID?
@Parent(key: "conversation_id")
var conversation: ConversationRecord
@Parent(key: "listing_id")
var listing: ListingRecord
@Parent(key: "buyer_id")
var buyer: UserRecord
@Field(key: "amount_cents")
var amountCents: Int
@Field(key: "status")
var status: String
@Field(key: "created_at")
var createdAt: Date
@Field(key: "expires_at")
var expiresAt: Date
// MARK: Initializers
init() {}
init(
conversationID: UUID,
listingID: UUID,
buyerID: UUID,
amountCents: Int,
at date: Date
) {
self.$conversation.id = conversationID
self.$listing.id = listingID
self.$buyer.id = buyerID
self.amountCents = amountCents
self.status = Offer.Status.open.rawValue
self.createdAt = date
self.expiresAt = date.addingTimeInterval(Offer.lifetime)
}
}
// MARK: - Extensions
extension OfferRecord {
// MARK: Methods
/// The `Sendable` snapshot of the saved record; its buyer, and its listing with its shop, must be eager-loaded.
/// - Parameter now: the moment an open offer's expiry is judged at.
func snapshot(
at now: Date
) throws -> Offer {
let stored = Offer.Status(rawValue: status) ?? .declined
return .init(
id: try requireID(),
conversationID: $conversation.id,
listing: listing.snapshot,
buyer: try buyer.snapshot,
amountCents: amountCents,
status: stored == .open && expiresAt <= now ? .expired : stored,
createdAt: createdAt,
expiresAt: expiresAt
)
}
}