Skip to content

Commit

Permalink
Simplify notifications API
Browse files Browse the repository at this point in the history
  • Loading branch information
fpseverino committed Nov 5, 2024
1 parent 92a02f3 commit a8f2827
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 58 deletions.
10 changes: 0 additions & 10 deletions Sources/Orders/OrdersService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,6 @@ public final class OrdersService: Sendable {
migrations.add(OrdersErrorLog())
}

/// Sends push notifications for a given order.
///
/// - Parameters:
/// - id: The `UUID` of the order to send the notifications for.
/// - typeIdentifier: The type identifier of the order.
/// - db: The `Database` to use.
public func sendPushNotificationsForOrder(id: UUID, of typeIdentifier: String, on db: any Database) async throws {
try await service.sendPushNotificationsForOrder(id: id, of: typeIdentifier, on: db)
}

/// Sends push notifications for a given order.
///
/// - Parameters:
Expand Down
44 changes: 26 additions & 18 deletions Sources/Orders/OrdersServiceCustom.swift
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,16 @@ extension OrdersServiceCustom {
}
let orderTypeIdentifier = req.parameters.get("orderTypeIdentifier")!

try await sendPushNotificationsForOrder(id: id, of: orderTypeIdentifier, on: req.db)
guard
let order = try await O.query(on: req.db)
.filter(\._$id == id)
.filter(\._$typeIdentifier == orderTypeIdentifier)
.first()
else {
throw Abort(.notFound)
}

try await sendPushNotifications(for: order, on: req.db)
return .noContent
}

Expand All @@ -318,7 +327,16 @@ extension OrdersServiceCustom {
}
let orderTypeIdentifier = req.parameters.get("orderTypeIdentifier")!

return try await Self.registrationsForOrder(id: id, of: orderTypeIdentifier, on: req.db).map { $0.device.pushToken }
guard
let order = try await O.query(on: req.db)
.filter(\._$id == id)
.filter(\._$typeIdentifier == orderTypeIdentifier)
.first()
else {
throw Abort(.notFound)
}

return try await Self.registrations(for: order, on: req.db).map { $0.device.pushToken }
}
}

Expand All @@ -327,11 +345,10 @@ extension OrdersServiceCustom {
/// Sends push notifications for a given order.
///
/// - Parameters:
/// - id: The `UUID` of the order to send the notifications for.
/// - typeIdentifier: The type identifier of the order.
/// - order: The order to send the notifications for.
/// - db: The `Database` to use.
public func sendPushNotificationsForOrder(id: UUID, of typeIdentifier: String, on db: any Database) async throws {
let registrations = try await Self.registrationsForOrder(id: id, of: typeIdentifier, on: db)
public func sendPushNotifications(for order: O, on db: any Database) async throws {
let registrations = try await Self.registrations(for: order, on: db)
for reg in registrations {
let backgroundNotification = APNSBackgroundNotification(
expiration: .immediately,
Expand All @@ -350,25 +367,16 @@ extension OrdersServiceCustom {
}
}

/// Sends push notifications for a given order.
///
/// - Parameters:
/// - order: The order to send the notifications for.
/// - db: The `Database` to use.
public func sendPushNotifications(for order: O, on db: any Database) async throws {
try await sendPushNotificationsForOrder(id: order.requireID(), of: order.typeIdentifier, on: db)
}

private static func registrationsForOrder(id: UUID, of typeIdentifier: String, on db: any Database) async throws -> [R] {
private static func registrations(for order: O, on db: any Database) async throws -> [R] {
// This could be done by enforcing the caller to have a Siblings property wrapper,
// but there's not really any value to forcing that on them when we can just do the query ourselves like this.
try await R.query(on: db)
.join(parent: \._$order)
.join(parent: \._$device)
.with(\._$order)
.with(\._$device)
.filter(O.self, \._$typeIdentifier == typeIdentifier)
.filter(O.self, \._$id == id)
.filter(O.self, \._$typeIdentifier == order._$typeIdentifier.value!)
.filter(O.self, \._$id == order.requireID())
.all()
}
}
Expand Down
10 changes: 0 additions & 10 deletions Sources/Passes/PassesService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,6 @@ public final class PassesService: Sendable {
migrations.add(PassesErrorLog())
}

/// Sends push notifications for a given pass.
///
/// - Parameters:
/// - id: The `UUID` of the pass to send the notifications for.
/// - typeIdentifier: The type identifier of the pass.
/// - db: The `Database` to use.
public func sendPushNotificationsForPass(id: UUID, of typeIdentifier: String, on db: any Database) async throws {
try await service.sendPushNotificationsForPass(id: id, of: typeIdentifier, on: db)
}

/// Sends push notifications for a given pass.
///
/// - Parameters:
Expand Down
44 changes: 26 additions & 18 deletions Sources/Passes/PassesServiceCustom.swift
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,16 @@ extension PassesServiceCustom {
}
let passTypeIdentifier = req.parameters.get("passTypeIdentifier")!

try await sendPushNotificationsForPass(id: id, of: passTypeIdentifier, on: req.db)
guard
let pass = try await P.query(on: req.db)
.filter(\._$id == id)
.filter(\._$typeIdentifier == passTypeIdentifier)
.first()
else {
throw Abort(.notFound)
}

try await sendPushNotifications(for: pass, on: req.db)
return .noContent
}

Expand All @@ -363,7 +372,16 @@ extension PassesServiceCustom {
}
let passTypeIdentifier = req.parameters.get("passTypeIdentifier")!

return try await Self.registrationsForPass(id: id, of: passTypeIdentifier, on: req.db).map { $0.device.pushToken }
guard
let pass = try await P.query(on: req.db)
.filter(\._$id == id)
.filter(\._$typeIdentifier == passTypeIdentifier)
.first()
else {
throw Abort(.notFound)
}

return try await Self.registrations(for: pass, on: req.db).map { $0.device.pushToken }
}
}

Expand All @@ -372,11 +390,10 @@ extension PassesServiceCustom {
/// Sends push notifications for a given pass.
///
/// - Parameters:
/// - id: The `UUID` of the pass to send the notifications for.
/// - typeIdentifier: The type identifier of the pass.
/// - pass: The pass to send the notifications for.
/// - db: The `Database` to use.
public func sendPushNotificationsForPass(id: UUID, of typeIdentifier: String, on db: any Database) async throws {
let registrations = try await Self.registrationsForPass(id: id, of: typeIdentifier, on: db)
public func sendPushNotifications(for pass: P, on db: any Database) async throws {
let registrations = try await Self.registrations(for: pass, on: db)
for reg in registrations {
let backgroundNotification = APNSBackgroundNotification(
expiration: .immediately,
Expand All @@ -395,25 +412,16 @@ extension PassesServiceCustom {
}
}

/// Sends push notifications for a given pass.
///
/// - Parameters:
/// - pass: The pass to send the notifications for.
/// - db: The `Database` to use.
public func sendPushNotifications(for pass: P, on db: any Database) async throws {
try await sendPushNotificationsForPass(id: pass.requireID(), of: pass.typeIdentifier, on: db)
}

private static func registrationsForPass(id: UUID, of typeIdentifier: String, on db: any Database) async throws -> [R] {
private static func registrations(for pass: P, on db: any Database) async throws -> [R] {
// This could be done by enforcing the caller to have a Siblings property wrapper,
// but there's not really any value to forcing that on them when we can just do the query ourselves like this.
try await R.query(on: db)
.join(parent: \._$pass)
.join(parent: \._$device)
.with(\._$pass)
.with(\._$device)
.filter(P.self, \._$typeIdentifier == typeIdentifier)
.filter(P.self, \._$id == id)
.filter(P.self, \._$typeIdentifier == pass._$typeIdentifier.value!)
.filter(P.self, \._$id == pass.requireID())
.all()
}
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/OrdersTests/OrdersTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ struct OrdersTests {
try await orderData.create(on: app.db)
let order = try await orderData._$order.get(on: app.db)

try await ordersService.sendPushNotificationsForOrder(id: order.requireID(), of: order.typeIdentifier, on: app.db)
try await ordersService.sendPushNotifications(for: order, on: app.db)

let deviceLibraryIdentifier = "abcdefg"
let pushToken = "1234567890"
Expand Down
2 changes: 1 addition & 1 deletion Tests/PassesTests/PassesTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ struct PassesTests {
try await passData.create(on: app.db)
let pass = try await passData._$pass.get(on: app.db)

try await passesService.sendPushNotificationsForPass(id: pass.requireID(), of: pass.typeIdentifier, on: app.db)
try await passesService.sendPushNotifications(for: pass, on: app.db)

let deviceLibraryIdentifier = "abcdefg"
let pushToken = "1234567890"
Expand Down

0 comments on commit a8f2827

Please sign in to comment.