feat: Begins breaking database out into it's own module, using dependencies

This commit is contained in:
2025-01-13 14:39:37 -05:00
parent 540b3e771a
commit 217dc5fa56
20 changed files with 1372 additions and 16 deletions

View File

@@ -0,0 +1,63 @@
import Dependencies
import DependenciesMacros
import SharedModels
public extension DatabaseClient {
@DependencyClient
struct Employees: Sendable {
public var create: @Sendable (Employee.Create) async throws -> Employee
public var delete: @Sendable (Employee.ID) async throws -> Void
public var fetchAll: @Sendable (FetchRequest) async throws -> [Employee]
public var get: @Sendable (Employee.ID) async throws -> Employee?
public var update: @Sendable (Employee.ID, Employee.Update) async throws -> Employee
public func fetchAll() async throws -> [Employee] {
try await fetchAll(.all)
}
public enum FetchRequest {
case active
case all
case inactive
}
}
}
extension DatabaseClient.Employees: TestDependencyKey {
public static let testValue = Self()
}
public extension Employee {
struct Create: Codable, Sendable {
public let firstName: String
public let lastName: String
public let active: Bool?
public init(
firstName: String,
lastName: String,
active: Bool? = nil
) {
self.firstName = firstName
self.lastName = lastName
self.active = active
}
}
struct Update: Codable, Sendable {
public let firstName: String?
public let lastName: String?
public let active: Bool?
public init(
firstName: String? = nil,
lastName: String? = nil,
active: Bool? = nil
) {
self.firstName = firstName
self.lastName = lastName
self.active = active
}
}
}

View File

@@ -0,0 +1,30 @@
import Dependencies
import DependenciesMacros
import FluentKit
public extension DependencyValues {
var database: DatabaseClient {
get { self[DatabaseClient.self] }
set { self[DatabaseClient.self] = newValue }
}
}
@DependencyClient
public struct DatabaseClient: Sendable {
public var employees: Employees
public var migrations: @Sendable () async throws -> [any AsyncMigration]
public var purchaseOrders: PurchaseOrders
public var users: Users
public var vendorBranches: VendorBranches
public var vendors: Vendors
}
extension DatabaseClient: TestDependencyKey {
public static let testValue: DatabaseClient = Self(
employees: .testValue,
purchaseOrders: .testValue,
users: .testValue,
vendorBranches: .testValue,
vendors: .testValue
)
}

View File

@@ -0,0 +1,52 @@
import Dependencies
import DependenciesMacros
import Fluent
import SharedModels
public extension DatabaseClient {
@DependencyClient
struct PurchaseOrders: Sendable {
public var create: @Sendable (PurchaseOrder.Create, User.ID) async throws -> PurchaseOrder
public var fetchAll: @Sendable () async throws -> [PurchaseOrder]
public var fetchPage: @Sendable (PageRequest) async throws -> Page<PurchaseOrder>
public var get: @Sendable (PurchaseOrder.ID) async throws -> PurchaseOrder?
// var update: @Sendable (PurchaseOrder.ID, PurchaseOrder.Update) async throws -> PurchaseOrder
public var delete: @Sendable (PurchaseOrder.ID) async throws -> Void
}
}
extension DatabaseClient.PurchaseOrders: TestDependencyKey {
public static let testValue: DatabaseClient.PurchaseOrders = Self()
}
public extension PurchaseOrder {
struct Create: Codable, Sendable {
public let id: Int?
public let workOrder: Int?
public let materials: String
public let customer: String
public let truckStock: Bool?
public let createdForID: Employee.ID
public let vendorBranchID: VendorBranch.ID
public init(
id: Int? = nil,
workOrder: Int? = nil,
materials: String,
customer: String,
truckStock: Bool? = nil,
createdForID: Employee.ID,
vendorBranchID: VendorBranch.ID
) {
self.id = id
self.workOrder = workOrder
self.materials = materials
self.customer = customer
self.truckStock = truckStock
self.createdForID = createdForID
self.vendorBranchID = vendorBranchID
}
}
}

View File

@@ -0,0 +1,76 @@
import Dependencies
import DependenciesMacros
import Foundation
import SharedModels
public extension DatabaseClient {
@DependencyClient
struct Users: Sendable {
public var create: @Sendable (User.Create) async throws -> User
public var delete: @Sendable (User.ID) async throws -> Void
public var fetchAll: @Sendable () async throws -> [User]
public var get: @Sendable (User.ID) async throws -> User?
public var login: @Sendable (User.Login) async throws -> User.Token
public var logout: @Sendable (User.Token.ID) async throws -> Void
}
}
extension DatabaseClient.Users: TestDependencyKey {
public static let testValue: DatabaseClient.Users = Self()
}
public extension User {
struct Create: Codable, Sendable {
public let username: String
public let email: String
public let password: String
public let confirmPassword: String
public init(
username: String,
email: String,
password: String,
confirmPassword: String
) {
self.username = username
self.email = email
self.password = password
self.confirmPassword = confirmPassword
}
}
struct Login: Codable, Sendable {
public let username: String?
public let email: String?
public let password: String
public init(
username: String?,
email: String? = nil,
password: String
) {
self.username = username
self.email = email
self.password = password
}
}
struct Token: Codable, Equatable, Identifiable, Sendable {
public let id: UUID
public let userID: User.ID
public let value: String
public init(
id: UUID,
userID: User.ID,
value: String
) {
self.id = id
self.userID = userID
self.value = value
}
}
}

View File

@@ -0,0 +1,48 @@
import Dependencies
import DependenciesMacros
import SharedModels
public extension DatabaseClient {
@DependencyClient
struct VendorBranches: Sendable {
public var create: @Sendable (VendorBranch.Create) async throws -> VendorBranch
public var delete: @Sendable (VendorBranch.ID) async throws -> Void
public var fetchAll: @Sendable (FetchRequest) async throws -> [VendorBranch]
public var get: @Sendable (VendorBranch.ID) async throws -> VendorBranch?
public var update: @Sendable (VendorBranch.ID, VendorBranch.Update) async throws -> VendorBranch
public enum FetchRequest: Equatable {
case all
case `for`(vendorID: Vendor.ID)
case withVendor
}
public func fetchAll() async throws -> [VendorBranch] {
try await fetchAll(.all)
}
}
}
extension DatabaseClient.VendorBranches: TestDependencyKey {
public static let testValue: DatabaseClient.VendorBranches = Self()
}
public extension VendorBranch {
struct Create: Codable, Sendable {
public let name: String
public let vendorID: Vendor.ID
public init(name: String, vendorID: Vendor.ID) {
self.name = name
self.vendorID = vendorID
}
}
struct Update: Codable, Sendable {
public let name: String?
public init(name: String?) {
self.name = name
}
}
}

View File

@@ -0,0 +1,55 @@
import Dependencies
import DependenciesMacros
import SharedModels
public extension DatabaseClient {
@DependencyClient
struct Vendors: Sendable {
public var create: @Sendable (Vendor.Create) async throws -> Vendor
public var delete: @Sendable (Vendor.ID) async throws -> Void
public var fetchAll: @Sendable (FetchRequest) async throws -> [Vendor]
public var get: @Sendable (Vendor.ID, GetRequest) async throws -> Vendor?
public var update: @Sendable (Vendor.ID, Vendor.Update) async throws -> Vendor
public enum FetchRequest {
case all
case withBranches
}
public enum GetRequest {
case all
case withBranches
}
public func fetchAll() async throws -> [Vendor] {
try await fetchAll(.all)
}
public func get(_ id: Vendor.ID) async throws -> Vendor? {
try await get(id, .all)
}
}
}
extension DatabaseClient.Vendors: TestDependencyKey {
public static let testValue: DatabaseClient.Vendors = Self()
}
public extension Vendor {
struct Create: Codable, Sendable {
public let name: String
public init(name: String) {
self.name = name
}
}
struct Update: Codable, Sendable {
public let name: String?
public init(name: String?) {
self.name = name
}
}
}