Added the catalogue models and seed to support phase 1 of the POC prototype in the Persistence package.
This commit is contained in:
1 parent
717df5208c
commit
6d7ab4bcba
19 files changed
+1381
-151
No files matched your search
@@ -1,45 +0,0 @@
|
||||
import FluentKit
|
||||
import Foundation
|
||||
|
||||
/// A FluentKit model of a single `example_records` row.
|
||||
///
|
||||
/// This is reference scaffolding: it demonstrates the model → migration → repository pattern the rest of
|
||||
/// the package is built around, and is what the tests exercise. Replace it with the first real domain model
|
||||
/// (paired with its own migration and repository) once one is defined.
|
||||
///
|
||||
/// FluentKit models are mutable reference types whose property wrappers are not `Sendable`; the model never
|
||||
/// crosses a concurrency boundary (repositories map it to a `Sendable` snapshot before returning), so the
|
||||
/// conformance is declared `@unchecked Sendable`.
|
||||
final class ExampleRecord: Model, @unchecked Sendable {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The name of the backing table.
|
||||
static let schema = "example_records"
|
||||
|
||||
/// The row's primary key, assigned on first save.
|
||||
@ID(key: .id)
|
||||
var id: UUID?
|
||||
|
||||
/// The row's name column.
|
||||
@Field(key: "name")
|
||||
var name: String
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
/// Creates an empty record, as required by FluentKit to hydrate query results.
|
||||
init() {}
|
||||
|
||||
/// Creates a record with the given values.
|
||||
/// - Parameters:
|
||||
/// - id: the primary key, or `nil` to have one assigned on save.
|
||||
/// - name: the value of the name column.
|
||||
init(
|
||||
id: UUID? = nil,
|
||||
name: String
|
||||
) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
import FluentKit
|
||||
import Foundation
|
||||
|
||||
/// A FluentKit model of a single `listings` row.
|
||||
///
|
||||
/// The catalogue fields (series, issue, publisher) are folded into the listing; they move to tables of their own once the series screen needs them.
|
||||
final class ListingRecord: Model, @unchecked Sendable {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
static let schema = "listings"
|
||||
|
||||
@ID(key: .id)
|
||||
var id: UUID?
|
||||
|
||||
@Parent(key: "shop_id")
|
||||
var shop: ShopRecord
|
||||
|
||||
@Field(key: "slug")
|
||||
var slug: String
|
||||
|
||||
@Field(key: "title")
|
||||
var title: String
|
||||
|
||||
@Field(key: "series_title")
|
||||
var seriesTitle: String
|
||||
|
||||
@Field(key: "issue_label")
|
||||
var issueLabel: String
|
||||
|
||||
@Field(key: "publisher")
|
||||
var publisher: String
|
||||
|
||||
@Field(key: "year")
|
||||
var year: Int
|
||||
|
||||
@Field(key: "format")
|
||||
var format: String
|
||||
|
||||
@Field(key: "printing")
|
||||
var printing: String
|
||||
|
||||
@Field(key: "printing_detail")
|
||||
var printingDetail: String
|
||||
|
||||
@Field(key: "is_first_print")
|
||||
var isFirstPrint: Bool
|
||||
|
||||
@OptionalField(key: "grader")
|
||||
var grader: String?
|
||||
|
||||
@OptionalField(key: "grade")
|
||||
var grade: Double?
|
||||
|
||||
@Field(key: "condition")
|
||||
var condition: String
|
||||
|
||||
@OptionalField(key: "cert_number")
|
||||
var certNumber: String?
|
||||
|
||||
@OptionalField(key: "page_quality")
|
||||
var pageQuality: String?
|
||||
|
||||
@OptionalField(key: "key_notes")
|
||||
var keyNotes: String?
|
||||
|
||||
@Field(key: "seller_notes")
|
||||
var sellerNotes: String
|
||||
|
||||
@Field(key: "price_cents")
|
||||
var priceCents: Int
|
||||
|
||||
@Field(key: "shipping_cents")
|
||||
var shippingCents: Int
|
||||
|
||||
@Field(key: "accepts_offers")
|
||||
var acceptsOffers: Bool
|
||||
|
||||
@Field(key: "cover_tone")
|
||||
var coverTone: String
|
||||
|
||||
@Field(key: "cover_title")
|
||||
var coverTitle: String
|
||||
|
||||
@Field(key: "cover_imprint")
|
||||
var coverImprint: String
|
||||
|
||||
@Field(key: "cover_number")
|
||||
var coverNumber: String
|
||||
|
||||
@Field(key: "listed_at")
|
||||
var listedAt: Date
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
init() {}
|
||||
|
||||
/// Creates a record from a snapshot.
|
||||
/// - Parameters:
|
||||
/// - listing: the snapshot the record takes its values from.
|
||||
/// - shopID: the identifier of the shop the listing belongs to.
|
||||
init(
|
||||
_ listing: Listing,
|
||||
shopID: UUID
|
||||
) {
|
||||
self.$shop.id = shopID
|
||||
self.slug = listing.slug
|
||||
self.title = listing.title
|
||||
self.seriesTitle = listing.seriesTitle
|
||||
self.issueLabel = listing.issueLabel
|
||||
self.publisher = listing.publisher
|
||||
self.year = listing.year
|
||||
self.format = listing.format
|
||||
self.printing = listing.printing
|
||||
self.printingDetail = listing.printingDetail
|
||||
self.isFirstPrint = listing.isFirstPrint
|
||||
self.grader = listing.grader
|
||||
self.grade = listing.grade
|
||||
self.condition = listing.condition
|
||||
self.certNumber = listing.certNumber
|
||||
self.pageQuality = listing.pageQuality
|
||||
self.keyNotes = listing.keyNotes
|
||||
self.sellerNotes = listing.sellerNotes
|
||||
self.priceCents = listing.priceCents
|
||||
self.shippingCents = listing.shippingCents
|
||||
self.acceptsOffers = listing.acceptsOffers
|
||||
self.coverTone = listing.cover.tone
|
||||
self.coverTitle = listing.cover.title
|
||||
self.coverImprint = listing.cover.imprint
|
||||
self.coverNumber = listing.cover.number
|
||||
self.listedAt = listing.listedAt
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Extensions
|
||||
|
||||
extension ListingRecord {
|
||||
|
||||
// MARK: Computed
|
||||
|
||||
/// The `Sendable` snapshot of the record; its shop must be eager-loaded.
|
||||
var snapshot: Listing {
|
||||
.init(
|
||||
slug: slug,
|
||||
shop: shop.snapshot,
|
||||
title: title,
|
||||
seriesTitle: seriesTitle,
|
||||
issueLabel: issueLabel,
|
||||
publisher: publisher,
|
||||
year: year,
|
||||
format: format,
|
||||
printing: printing,
|
||||
printingDetail: printingDetail,
|
||||
isFirstPrint: isFirstPrint,
|
||||
grader: grader,
|
||||
grade: grade,
|
||||
condition: condition,
|
||||
certNumber: certNumber,
|
||||
pageQuality: pageQuality,
|
||||
keyNotes: keyNotes,
|
||||
sellerNotes: sellerNotes,
|
||||
priceCents: priceCents,
|
||||
shippingCents: shippingCents,
|
||||
acceptsOffers: acceptsOffers,
|
||||
cover: .init(
|
||||
tone: coverTone,
|
||||
title: coverTitle,
|
||||
imprint: coverImprint,
|
||||
number: coverNumber
|
||||
),
|
||||
listedAt: listedAt
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
import FluentKit
|
||||
import Foundation
|
||||
|
||||
/// A FluentKit model of a single `shops` row.
|
||||
final class ShopRecord: Model, @unchecked Sendable {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
static let schema = "shops"
|
||||
|
||||
@ID(key: .id)
|
||||
var id: UUID?
|
||||
|
||||
@Field(key: "slug")
|
||||
var slug: String
|
||||
|
||||
@Field(key: "name")
|
||||
var name: String
|
||||
|
||||
@Field(key: "city")
|
||||
var city: String
|
||||
|
||||
@Field(key: "country")
|
||||
var country: String
|
||||
|
||||
@Field(key: "since_year")
|
||||
var sinceYear: Int
|
||||
|
||||
@Field(key: "is_verified")
|
||||
var isVerified: Bool
|
||||
|
||||
@Field(key: "rating")
|
||||
var rating: Double
|
||||
|
||||
@Field(key: "rated_sales")
|
||||
var ratedSales: Int
|
||||
|
||||
@Field(key: "sold_count")
|
||||
var soldCount: Int
|
||||
|
||||
@Field(key: "handling_days")
|
||||
var handlingDays: Int
|
||||
|
||||
@Field(key: "ships_note")
|
||||
var shipsNote: String
|
||||
|
||||
@Field(key: "returns_note")
|
||||
var returnsNote: String
|
||||
|
||||
@Field(key: "about")
|
||||
var about: String
|
||||
|
||||
@Children(for: \.$shop)
|
||||
var listings: [ListingRecord]
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
init() {}
|
||||
|
||||
/// Creates a record from a snapshot.
|
||||
/// - Parameter shop: the snapshot the record takes its values from.
|
||||
init(
|
||||
_ shop: Shop
|
||||
) {
|
||||
self.slug = shop.slug
|
||||
self.name = shop.name
|
||||
self.city = shop.city
|
||||
self.country = shop.country
|
||||
self.sinceYear = shop.sinceYear
|
||||
self.isVerified = shop.isVerified
|
||||
self.rating = shop.rating
|
||||
self.ratedSales = shop.ratedSales
|
||||
self.soldCount = shop.soldCount
|
||||
self.handlingDays = shop.handlingDays
|
||||
self.shipsNote = shop.shipsNote
|
||||
self.returnsNote = shop.returnsNote
|
||||
self.about = shop.about
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Extensions
|
||||
|
||||
extension ShopRecord {
|
||||
|
||||
// MARK: Computed
|
||||
|
||||
/// The `Sendable` snapshot of the record.
|
||||
var snapshot: Shop {
|
||||
.init(
|
||||
slug: slug,
|
||||
name: name,
|
||||
city: city,
|
||||
country: country,
|
||||
sinceYear: sinceYear,
|
||||
isVerified: isVerified,
|
||||
rating: rating,
|
||||
ratedSales: ratedSales,
|
||||
soldCount: soldCount,
|
||||
handlingDays: handlingDays,
|
||||
shipsNote: shipsNote,
|
||||
returnsNote: returnsNote,
|
||||
about: about
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user