feat: Rename items in database client for consistency.
All checks were successful
CI / Linux Tests (push) Successful in 5m24s

This commit is contained in:
2026-01-29 15:47:24 -05:00
parent 6723f7a410
commit 18a5ef06d3
17 changed files with 144 additions and 341 deletions

View File

@@ -104,14 +104,14 @@ extension SiteRoute.Api.ComponentLossRoute {
switch self {
case .create(let request):
return try await database.componentLoss.create(request)
return try await database.componentLosses.create(request)
case .delete(let id):
try await database.componentLoss.delete(id)
try await database.componentLosses.delete(id)
return nil
case .fetch(let projectID):
return try await database.componentLoss.fetch(projectID)
return try await database.componentLosses.fetch(projectID)
case .get(let id):
guard let room = try await database.componentLoss.get(id) else {
guard let room = try await database.componentLosses.get(id) else {
logger.error("Component loss not found for id: \(id)")
throw ApiError("Component loss not found.")
}

View File

@@ -16,11 +16,108 @@ public struct DatabaseClient: Sendable {
public var projects: Projects
public var rooms: Rooms
public var equipment: Equipment
public var componentLoss: ComponentLoss
public var effectiveLength: EffectiveLengthClient
public var componentLosses: ComponentLosses
public var equivalentLengths: EquivalentLengths
public var users: Users
public var userProfile: UserProfile
public var userProfiles: UserProfiles
public var trunkSizes: TrunkSizes
@DependencyClient
public struct ComponentLosses: Sendable {
public var create:
@Sendable (ComponentPressureLoss.Create) async throws -> ComponentPressureLoss
public var delete: @Sendable (ComponentPressureLoss.ID) async throws -> Void
public var fetch: @Sendable (Project.ID) async throws -> [ComponentPressureLoss]
public var get: @Sendable (ComponentPressureLoss.ID) async throws -> ComponentPressureLoss?
public var update:
@Sendable (ComponentPressureLoss.ID, ComponentPressureLoss.Update) async throws ->
ComponentPressureLoss
}
@DependencyClient
public struct EquivalentLengths: Sendable {
public var create: @Sendable (EquivalentLength.Create) async throws -> EquivalentLength
public var delete: @Sendable (EquivalentLength.ID) async throws -> Void
public var fetch: @Sendable (Project.ID) async throws -> [EquivalentLength]
public var fetchMax: @Sendable (Project.ID) async throws -> EquivalentLength.MaxContainer
public var get: @Sendable (EquivalentLength.ID) async throws -> EquivalentLength?
public var update:
@Sendable (EquivalentLength.ID, EquivalentLength.Update) async throws -> EquivalentLength
}
@DependencyClient
public struct Equipment: Sendable {
public var create: @Sendable (EquipmentInfo.Create) async throws -> EquipmentInfo
public var delete: @Sendable (EquipmentInfo.ID) async throws -> Void
public var fetch: @Sendable (Project.ID) async throws -> EquipmentInfo?
public var get: @Sendable (EquipmentInfo.ID) async throws -> EquipmentInfo?
public var update:
@Sendable (EquipmentInfo.ID, EquipmentInfo.Update) async throws -> EquipmentInfo
}
@DependencyClient
public struct Migrations: Sendable {
public var all: @Sendable () async throws -> [any AsyncMigration]
public func callAsFunction() async throws -> [any AsyncMigration] {
try await self.all()
}
}
@DependencyClient
public struct Projects: Sendable {
public var create: @Sendable (User.ID, Project.Create) async throws -> Project
public var delete: @Sendable (Project.ID) async throws -> Void
public var detail: @Sendable (Project.ID) async throws -> Project.Detail?
public var get: @Sendable (Project.ID) async throws -> Project?
public var getCompletedSteps: @Sendable (Project.ID) async throws -> Project.CompletedSteps
public var getSensibleHeatRatio: @Sendable (Project.ID) async throws -> Double?
public var fetch: @Sendable (User.ID, PageRequest) async throws -> Page<Project>
public var update: @Sendable (Project.ID, Project.Update) async throws -> Project
}
@DependencyClient
public struct Rooms: Sendable {
public var create: @Sendable (Room.Create) async throws -> Room
public var delete: @Sendable (Room.ID) async throws -> Void
public var deleteRectangularSize:
@Sendable (Room.ID, Room.RectangularSize.ID) async throws -> Room
public var get: @Sendable (Room.ID) async throws -> Room?
public var fetch: @Sendable (Project.ID) async throws -> [Room]
public var update: @Sendable (Room.ID, Room.Update) async throws -> Room
public var updateRectangularSize: @Sendable (Room.ID, Room.RectangularSize) async throws -> Room
}
@DependencyClient
public struct TrunkSizes: Sendable {
public var create: @Sendable (TrunkSize.Create) async throws -> TrunkSize
public var delete: @Sendable (TrunkSize.ID) async throws -> Void
public var fetch: @Sendable (Project.ID) async throws -> [TrunkSize]
public var get: @Sendable (TrunkSize.ID) async throws -> TrunkSize?
public var update:
@Sendable (TrunkSize.ID, TrunkSize.Update) async throws ->
TrunkSize
}
@DependencyClient
public struct UserProfiles: Sendable {
public var create: @Sendable (User.Profile.Create) async throws -> User.Profile
public var delete: @Sendable (User.Profile.ID) async throws -> Void
public var fetch: @Sendable (User.ID) async throws -> User.Profile?
public var get: @Sendable (User.Profile.ID) async throws -> User.Profile?
public var update: @Sendable (User.Profile.ID, User.Profile.Update) async throws -> User.Profile
}
@DependencyClient
public struct Users: Sendable {
public var create: @Sendable (User.Create) async throws -> User
public var delete: @Sendable (User.ID) async throws -> Void
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
// public var token: @Sendable (User.ID) async throws -> User.Token
}
}
extension DatabaseClient: TestDependencyKey {
@@ -29,10 +126,10 @@ extension DatabaseClient: TestDependencyKey {
projects: .testValue,
rooms: .testValue,
equipment: .testValue,
componentLoss: .testValue,
effectiveLength: .testValue,
componentLosses: .testValue,
equivalentLengths: .testValue,
users: .testValue,
userProfile: .testValue,
userProfiles: .testValue,
trunkSizes: .testValue
)
@@ -42,33 +139,20 @@ extension DatabaseClient: TestDependencyKey {
projects: .live(database: database),
rooms: .live(database: database),
equipment: .live(database: database),
componentLoss: .live(database: database),
effectiveLength: .live(database: database),
componentLosses: .live(database: database),
equivalentLengths: .live(database: database),
users: .live(database: database),
userProfile: .live(database: database),
userProfiles: .live(database: database),
trunkSizes: .live(database: database)
)
}
}
extension DatabaseClient {
@DependencyClient
public struct Migrations: Sendable {
public var run: @Sendable () async throws -> [any AsyncMigration]
public func callAsFunction() async throws -> [any AsyncMigration] {
try await self.run()
}
}
}
extension DatabaseClient.Migrations: TestDependencyKey {
public static let testValue = Self()
}
extension DatabaseClient.Migrations: DependencyKey {
public static let testValue = Self()
public static let liveValue = Self(
run: {
all: {
[
Project.Migrate(),
User.Migrate(),

View File

@@ -4,25 +4,11 @@ import Fluent
import Foundation
import ManualDCore
extension DatabaseClient {
@DependencyClient
public struct ComponentLoss: Sendable {
public var create:
@Sendable (ComponentPressureLoss.Create) async throws -> ComponentPressureLoss
public var delete: @Sendable (ComponentPressureLoss.ID) async throws -> Void
public var fetch: @Sendable (Project.ID) async throws -> [ComponentPressureLoss]
public var get: @Sendable (ComponentPressureLoss.ID) async throws -> ComponentPressureLoss?
public var update:
@Sendable (ComponentPressureLoss.ID, ComponentPressureLoss.Update) async throws ->
ComponentPressureLoss
}
}
extension DatabaseClient.ComponentLoss: TestDependencyKey {
extension DatabaseClient.ComponentLosses: TestDependencyKey {
public static let testValue = Self()
}
extension DatabaseClient.ComponentLoss {
extension DatabaseClient.ComponentLosses {
public static func live(database: any Database) -> Self {
.init(
create: { request in

View File

@@ -4,20 +4,7 @@ import Fluent
import Foundation
import ManualDCore
extension DatabaseClient {
@DependencyClient
public struct EffectiveLengthClient: Sendable {
public var create: @Sendable (EquivalentLength.Create) async throws -> EquivalentLength
public var delete: @Sendable (EquivalentLength.ID) async throws -> Void
public var fetch: @Sendable (Project.ID) async throws -> [EquivalentLength]
public var fetchMax: @Sendable (Project.ID) async throws -> EquivalentLength.MaxContainer
public var get: @Sendable (EquivalentLength.ID) async throws -> EquivalentLength?
public var update:
@Sendable (EquivalentLength.ID, EquivalentLength.Update) async throws -> EquivalentLength
}
}
extension DatabaseClient.EffectiveLengthClient: TestDependencyKey {
extension DatabaseClient.EquivalentLengths: TestDependencyKey {
public static let testValue = Self()
public static func live(database: any Database) -> Self {

View File

@@ -4,23 +4,9 @@ import Fluent
import Foundation
import ManualDCore
extension DatabaseClient {
@DependencyClient
public struct Equipment: Sendable {
public var create: @Sendable (EquipmentInfo.Create) async throws -> EquipmentInfo
public var delete: @Sendable (EquipmentInfo.ID) async throws -> Void
public var fetch: @Sendable (Project.ID) async throws -> EquipmentInfo?
public var get: @Sendable (EquipmentInfo.ID) async throws -> EquipmentInfo?
public var update:
@Sendable (EquipmentInfo.ID, EquipmentInfo.Update) async throws -> EquipmentInfo
}
}
extension DatabaseClient.Equipment: TestDependencyKey {
public static let testValue = Self()
}
extension DatabaseClient.Equipment {
public static func live(database: any Database) -> Self {
.init(
create: { request in

View File

@@ -4,20 +4,6 @@ import Fluent
import Foundation
import ManualDCore
extension DatabaseClient {
@DependencyClient
public struct Projects: Sendable {
public var create: @Sendable (User.ID, Project.Create) async throws -> Project
public var delete: @Sendable (Project.ID) async throws -> Void
public var detail: @Sendable (Project.ID) async throws -> Project.Detail?
public var get: @Sendable (Project.ID) async throws -> Project?
public var getCompletedSteps: @Sendable (Project.ID) async throws -> Project.CompletedSteps
public var getSensibleHeatRatio: @Sendable (Project.ID) async throws -> Double?
public var fetch: @Sendable (User.ID, PageRequest) async throws -> Page<Project>
public var update: @Sendable (Project.ID, Project.Update) async throws -> Project
}
}
extension DatabaseClient.Projects: TestDependencyKey {
public static let testValue = Self()

View File

@@ -4,20 +4,6 @@ import Fluent
import Foundation
import ManualDCore
extension DatabaseClient {
@DependencyClient
public struct Rooms: Sendable {
public var create: @Sendable (Room.Create) async throws -> Room
public var delete: @Sendable (Room.ID) async throws -> Void
public var deleteRectangularSize:
@Sendable (Room.ID, Room.RectangularSize.ID) async throws -> Room
public var get: @Sendable (Room.ID) async throws -> Room?
public var fetch: @Sendable (Project.ID) async throws -> [Room]
public var update: @Sendable (Room.ID, Room.Update) async throws -> Room
public var updateRectangularSize: @Sendable (Room.ID, Room.RectangularSize) async throws -> Room
}
}
extension DatabaseClient.Rooms: TestDependencyKey {
public static let testValue = Self()

View File

@@ -4,19 +4,6 @@ import Fluent
import Foundation
import ManualDCore
extension DatabaseClient {
@DependencyClient
public struct TrunkSizes: Sendable {
public var create: @Sendable (TrunkSize.Create) async throws -> TrunkSize
public var delete: @Sendable (TrunkSize.ID) async throws -> Void
public var fetch: @Sendable (Project.ID) async throws -> [TrunkSize]
public var get: @Sendable (TrunkSize.ID) async throws -> TrunkSize?
public var update:
@Sendable (TrunkSize.ID, TrunkSize.Update) async throws ->
TrunkSize
}
}
extension DatabaseClient.TrunkSizes: TestDependencyKey {
public static let testValue = Self()

View File

@@ -4,18 +4,7 @@ import Fluent
import ManualDCore
import Vapor
extension DatabaseClient {
@DependencyClient
public struct UserProfile: Sendable {
public var create: @Sendable (User.Profile.Create) async throws -> User.Profile
public var delete: @Sendable (User.Profile.ID) async throws -> Void
public var fetch: @Sendable (User.ID) async throws -> User.Profile?
public var get: @Sendable (User.Profile.ID) async throws -> User.Profile?
public var update: @Sendable (User.Profile.ID, User.Profile.Update) async throws -> User.Profile
}
}
extension DatabaseClient.UserProfile: TestDependencyKey {
extension DatabaseClient.UserProfiles: TestDependencyKey {
public static let testValue = Self()

View File

@@ -4,19 +4,6 @@ import Fluent
import ManualDCore
import Vapor
extension DatabaseClient {
@DependencyClient
public struct Users: Sendable {
public var create: @Sendable (User.Create) async throws -> User
public var delete: @Sendable (User.ID) async throws -> Void
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
// public var token: @Sendable (User.ID) async throws -> User.Token
}
}
extension DatabaseClient.Users: TestDependencyKey {
public static let testValue = Self()

View File

@@ -1,175 +0,0 @@
// import Dependencies
// import DependenciesMacros
// import Fluent
// import Foundation
// import ManualDCore
//
// extension DatabaseClient {
// @DependencyClient
// public struct RectangularDuct: Sendable {
// public var create:
// @Sendable (DuctSizing.RectangularDuct.Create) async throws -> DuctSizing.RectangularDuct
// public var delete: @Sendable (DuctSizing.RectangularDuct.ID) async throws -> Void
// public var fetch: @Sendable (Room.ID) async throws -> [DuctSizing.RectangularDuct]
// public var get:
// @Sendable (DuctSizing.RectangularDuct.ID) async throws -> DuctSizing.RectangularDuct?
// public var update:
// @Sendable (DuctSizing.RectangularDuct.ID, DuctSizing.RectangularDuct.Update) async throws ->
// DuctSizing.RectangularDuct
// }
// }
//
// extension DatabaseClient.RectangularDuct: TestDependencyKey {
// public static let testValue = Self()
//
// public static func live(database: any Database) -> Self {
// .init(
// create: { request in
// try request.validate()
// let model = request.toModel()
// try await model.save(on: database)
// return try model.toDTO()
// },
// delete: { id in
// guard let model = try await RectangularDuctModel.find(id, on: database) else {
// throw NotFoundError()
// }
// try await model.delete(on: database)
// },
// fetch: { roomID in
// try await RectangularDuctModel.query(on: database)
// .with(\.$room)
// .filter(\.$room.$id == roomID)
// .all()
// .map { try $0.toDTO() }
// },
// get: { id in
// try await RectangularDuctModel.find(id, on: database)
// .map { try $0.toDTO() }
// },
// update: { id, updates in
// guard let model = try await RectangularDuctModel.find(id, on: database) else {
// throw NotFoundError()
// }
// try updates.validate()
// model.applyUpdates(updates)
// if model.hasChanges {
// try await model.save(on: database)
// }
// return try model.toDTO()
// }
// )
// }
// }
//
// extension DuctSizing.RectangularDuct.Create {
//
// func validate() throws(ValidationError) {
// guard height > 0 else {
// throw ValidationError("Rectangular duct size height should be greater than 0.")
// }
// if let register {
// guard register > 0 else {
// throw ValidationError("Rectangular duct size register should be greater than 0.")
// }
// }
// }
//
// func toModel() -> RectangularDuctModel {
// .init(roomID: roomID, height: height)
// }
// }
//
// extension DuctSizing.RectangularDuct.Update {
//
// func validate() throws(ValidationError) {
// if let height {
// guard height > 0 else {
// throw ValidationError("Rectangular duct size height should be greater than 0.")
// }
// }
// if let register {
// guard register > 0 else {
// throw ValidationError("Rectangular duct size register should be greater than 0.")
// }
// }
// }
// }
//
// extension DuctSizing.RectangularDuct {
// struct Migrate: AsyncMigration {
// let name = "CreateRectangularDuct"
//
// func prepare(on database: any Database) async throws {
// try await database.schema(RectangularDuctModel.schema)
// .id()
// .field("register", .int8)
// .field("height", .int8, .required)
// .field("roomID", .uuid, .required, .references(RoomModel.schema, "id", onDelete: .cascade))
// .field("createdAt", .datetime)
// .field("updatedAt", .datetime)
// .create()
// }
//
// func revert(on database: any Database) async throws {
// try await database.schema(RectangularDuctModel.schema).delete()
// }
// }
// }
//
// final class RectangularDuctModel: Model, @unchecked Sendable {
//
// static let schema = "rectangularDuct"
//
// @ID(key: .id)
// var id: UUID?
//
// @Parent(key: "roomID")
// var room: RoomModel
//
// @Field(key: "height")
// var height: Int
//
// @Field(key: "register")
// var register: Int?
//
// @Timestamp(key: "createdAt", on: .create, format: .iso8601)
// var createdAt: Date?
//
// @Timestamp(key: "updatedAt", on: .update, format: .iso8601)
// var updatedAt: Date?
//
// init() {}
//
// init(
// id: UUID? = nil,
// roomID: Room.ID,
// register: Int? = nil,
// height: Int
// ) {
// self.id = id
// $room.id = roomID
// self.register = register
// self.height = height
// }
//
// func toDTO() throws -> DuctSizing.RectangularDuct {
// return try .init(
// id: requireID(),
// roomID: $room.id,
// register: register,
// height: height,
// createdAt: createdAt!,
// updatedAt: updatedAt!
// )
// }
//
// func applyUpdates(_ updates: DuctSizing.RectangularDuct.Update) {
// if let height = updates.height, height != self.height {
// self.height = height
// }
// if let register = updates.register, register != self.register {
// self.register = register
// }
// }
// }

View File

@@ -1,7 +1,7 @@
import DatabaseClient
import ManualDCore
extension DatabaseClient.ComponentLoss {
extension DatabaseClient.ComponentLosses {
func createDefaults(projectID: Project.ID) async throws {
let defaults = ComponentPressureLoss.Create.default(projectID: projectID)

View File

@@ -192,9 +192,9 @@ extension DatabaseClient {
}
return try await designFrictionRate(
componentLosses: componentLoss.fetch(projectID),
componentLosses: componentLosses.fetch(projectID),
equipmentInfo: equipmentInfo,
equivalentLengths: effectiveLength.fetchMax(projectID)
equivalentLengths: equivalentLengths.fetchMax(projectID)
)
}
}

View File

@@ -28,8 +28,8 @@ extension ManualDClient {
func frictionRate(projectID: Project.ID) async throws -> ProjectClient.FrictionRateResponse {
@Dependency(\.database) var database
let componentLosses = try await database.componentLoss.fetch(projectID)
let lengths = try await database.effectiveLength.fetchMax(projectID)
let componentLosses = try await database.componentLosses.fetch(projectID)
let lengths = try await database.equivalentLengths.fetchMax(projectID)
let equipmentInfo = try await database.equipment.fetch(projectID)
guard let staticPressure = equipmentInfo?.staticPressure else {
@@ -46,7 +46,7 @@ extension ManualDClient {
frictionRate: frictionRate(
.init(
externalStaticPressure: staticPressure,
componentPressureLosses: database.componentLoss.fetch(projectID),
componentPressureLosses: componentLosses,
totalEffectiveLength: Int(totalEquivalentLength)
)
)

View File

@@ -26,7 +26,7 @@ extension ProjectClient: DependencyKey {
},
createProject: { userID, request in
let project = try await database.projects.create(userID, request)
try await database.componentLoss.createDefaults(projectID: project.id)
try await database.componentLosses.createDefaults(projectID: project.id)
return try await .init(
projectID: project.id,
rooms: database.rooms.fetch(project.id),

View File

@@ -70,7 +70,7 @@ extension ViewController.Request {
case .submitProfile(let profile):
return await view {
await ResultView {
_ = try await database.userProfile.create(profile)
_ = try await database.userProfiles.create(profile)
let userID = profile.userID
// let user = try currentUser()
return (
@@ -108,7 +108,7 @@ extension ViewController.Request {
get async {
@Dependency(\.database) var database
guard let user = try? currentUser() else { return nil }
return try? await database.userProfile.fetch(user.id)?.theme
return try? await database.userProfiles.fetch(user.id)?.theme
}
}
@@ -366,8 +366,8 @@ extension SiteRoute.View.ProjectRoute.FrictionRateRoute {
return await request.view {
await ResultView {
let equipment = try await database.equipment.fetch(projectID)
let componentLosses = try await database.componentLoss.fetch(projectID)
let lengths = try await database.effectiveLength.fetchMax(projectID)
let componentLosses = try await database.componentLosses.fetch(projectID)
let lengths = try await database.equivalentLengths.fetchMax(projectID)
return (
try await database.projects.getCompletedSteps(projectID),
@@ -407,16 +407,16 @@ extension SiteRoute.View.ProjectRoute.ComponentLossRoute {
return EmptyHTML()
case .delete(let id):
return await view(on: request, projectID: projectID) {
_ = try await database.componentLoss.delete(id)
_ = try await database.componentLosses.delete(id)
}
case .submit(let form):
return await view(on: request, projectID: projectID) {
_ = try await database.componentLoss.create(form)
_ = try await database.componentLosses.create(form)
}
case .update(let id, let form):
return await view(on: request, projectID: projectID) {
_ = try await database.componentLoss.update(id, form)
_ = try await database.componentLosses.update(id, form)
}
}
}
@@ -464,7 +464,7 @@ extension SiteRoute.View.ProjectRoute.EquivalentLengthRoute {
case .delete(let id):
return await ResultView {
try await database.effectiveLength.delete(id)
try await database.equivalentLengths.delete(id)
}
case .index:
@@ -481,7 +481,7 @@ extension SiteRoute.View.ProjectRoute.EquivalentLengthRoute {
case .update(let id, let form):
return await view(on: request, projectID: projectID) {
_ = try await database.effectiveLength.update(id, .init(form: form, projectID: projectID))
_ = try await database.equivalentLengths.update(id, .init(form: form, projectID: projectID))
}
case .submit(let step):
@@ -490,7 +490,7 @@ extension SiteRoute.View.ProjectRoute.EquivalentLengthRoute {
return await ResultView {
var effectiveLength: EquivalentLength? = nil
if let id = stepOne.id {
effectiveLength = try await database.effectiveLength.get(id)
effectiveLength = try await database.equivalentLengths.get(id)
}
return effectiveLength
} onSuccess: { effectiveLength in
@@ -505,7 +505,7 @@ extension SiteRoute.View.ProjectRoute.EquivalentLengthRoute {
request.logger.debug("ViewController: Got step two...")
var effectiveLength: EquivalentLength? = nil
if let id = stepTwo.id {
effectiveLength = try await database.effectiveLength.get(id)
effectiveLength = try await database.equivalentLengths.get(id)
}
return effectiveLength
} onSuccess: { effectiveLength in
@@ -515,7 +515,7 @@ extension SiteRoute.View.ProjectRoute.EquivalentLengthRoute {
}
case .three(let stepThree):
return await view(on: request, projectID: projectID) {
_ = try await database.effectiveLength.create(
_ = try await database.equivalentLengths.create(
.init(form: stepThree, projectID: projectID)
)
}
@@ -536,7 +536,7 @@ extension SiteRoute.View.ProjectRoute.EquivalentLengthRoute {
try await catching()
return (
try await database.projects.getCompletedSteps(projectID),
try await database.effectiveLength.fetch(projectID)
try await database.equivalentLengths.fetch(projectID)
)
} onSuccess: { (steps, equivalentLengths) in
ProjectView(projectID: projectID, activeTab: .equivalentLength, completedSteps: steps) {
@@ -652,11 +652,11 @@ extension SiteRoute.View.UserRoute.Profile {
return await view(on: request)
case .submit(let form):
return await view(on: request) {
_ = try await database.userProfile.create(form)
_ = try await database.userProfiles.create(form)
}
case .update(let id, let updates):
return await view(on: request) {
_ = try await database.userProfile.update(id, updates)
_ = try await database.userProfiles.update(id, updates)
}
}
}
@@ -673,7 +673,7 @@ extension SiteRoute.View.UserRoute.Profile {
let user = try request.currentUser()
return (
user,
try await database.userProfile.fetch(user.id)
try await database.userProfiles.fetch(user.id)
)
} onSuccess: { (user, profile) in
UserView(user: user, profile: profile)