Added the catalogue models and seed to support phase 6 of the POC prototype in the Persistence package.

This commit is contained in:
javier committed 2026-09-21 13:52:52 +02:00
1 parent 31d2d98d49
commit 256d22df40
10 files changed
+473 -4

No files matched your search

@@ -192,3 +192,105 @@ public extension CollectingRepository {
}
}
// MARK: - Collection
public extension CollectingRepository {
/// Adds issues of a series to an account's collection; the ones already in it, or outside the run, are skipped.
func own(
issues: [Int],
ofSeries slug: String,
by user: User
) async throws {
guard let series = try await series(slug: slug) else {
return
}
let owned = try await ownedIssues(of: user)[slug] ?? []
let run = series.issueCount > 0 ? 1...series.issueCount : 1...999
for issue in Set(issues).subtracting(owned) where run.contains(issue) {
try await OwnedIssueRecord(userID: user.id, seriesSlug: slug, issue: issue).save(on: fluent.db())
}
}
/// Fetches the issues an account owns, by series slug.
func ownedIssues(
of user: User
) async throws -> [String: Set<Int>] {
try await OwnedIssueRecord.query(on: fluent.db())
.filter(\.$user.$id == user.id)
.all()
.reduce(into: [:]) { $0[$1.seriesSlug, default: []].insert($1.issue) }
}
/// Takes an issue out of an account's collection.
func disown(
issue: Int,
ofSeries slug: String,
by user: User
) async throws {
try await OwnedIssueRecord.query(on: fluent.db())
.filter(\.$user.$id == user.id)
.filter(\.$seriesSlug == slug)
.filter(\.$issue == issue)
.delete()
}
}
// MARK: - Events
public extension CollectingRepository {
/// Fetches the events still to come or under way, soonest first, each with the shops trading there.
func upcomingEvents() async throws -> [Event] {
try await EventRecord.query(on: fluent.db())
.filter(\.$endsOn >= now().addingTimeInterval(-86_400))
.sort(\.$startsOn)
.with(\.$shops)
.all()
.map { record in
.init(
slug: record.slug,
name: record.name,
venue: record.venue,
startsOn: record.startsOn,
endsOn: record.endsOn,
shops: record.shops.map(\.snapshot)
)
}
}
/// Sets the upcoming events the shop an account owns trades at.
func setEvents(
_ slugs: [String],
forShopOwnedBy user: User
) async throws {
try await fluent.db().transaction { database in
guard let shop = try await ShopRecord.query(on: database)
.filter(\.$owner.$id == user.id)
.first()
else {
return
}
let upcoming = try await EventRecord.query(on: database)
.filter(\.$endsOn >= now().addingTimeInterval(-86_400))
.with(\.$shops)
.all()
for event in upcoming {
let trades = try event.shops.contains { try $0.requireID() == shop.requireID() }
if slugs.contains(event.slug), !trades {
try await event.$shops.attach(shop, on: database)
} else if !slugs.contains(event.slug), trades {
try await event.$shops.detach(shop, on: database)
}
}
}
}
}