import FluentKit import Foundation import HummingbirdFluent /// A `Sendable` snapshot of an ``ExampleRecord``, safe to return across concurrency boundaries. /// /// Repositories return these value-type snapshots rather than FluentKit models, which are mutable reference /// types that must not escape the database's execution context. public struct Example: Sendable, Equatable { // MARK: Properties /// The record's primary key, or `nil` if it has never been saved. public let id: UUID? /// The record's name. public let name: String } /// Reads and writes ``ExampleRecord`` rows through the default database. /// /// This is the shape every real repository takes: it holds the `Sendable` `Fluent` service, resolves the /// default database per call, and maps FluentKit models to `Sendable` snapshots before returning — so no /// model ever escapes across an async boundary. It is reference scaffolding paired with ``ExampleRecord``; /// replace it with the first real repository once a domain model is defined. public struct ExampleRepository: Sendable { // MARK: Properties /// The service providing the default database the repository reads and writes through. private let fluent: Fluent // MARK: Initializers /// Creates a repository backed by the given `Fluent` service. /// - Parameter fluent: the service whose default database the repository operates on. public init(fluent: Fluent) { self.fluent = fluent } // MARK: Methods /// Inserts a record with the given name. /// - Parameter name: the name of the record to insert. /// - Returns: a `Sendable` snapshot of the inserted record, including its assigned identifier. public func create(name: String) async throws -> Example { let record = ExampleRecord(name: name) try await record.save(on: fluent.db()) return Example(id: record.id, name: record.name) } /// Fetches every record, ordered by name. /// - Returns: a `Sendable` snapshot of each record, sorted by name. public func all() async throws -> [Example] { try await ExampleRecord.query(on: fluent.db()) .sort(\.$name) .all() .map { Example(id: $0.id, name: $0.name) } } }