feat: Moves TrunkSize to be it's own namespace rather than being under DuctSizing, as it's got it's own database model, etc.
This commit is contained in:
@@ -74,7 +74,7 @@ extension DatabaseClient.Migrations: DependencyKey {
|
||||
EquipmentInfo.Migrate(),
|
||||
Room.Migrate(),
|
||||
EffectiveLength.Migrate(),
|
||||
DuctSizing.TrunkSize.Migrate(),
|
||||
TrunkSize.Migrate(),
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
@@ -7,13 +7,13 @@ import ManualDCore
|
||||
extension DatabaseClient {
|
||||
@DependencyClient
|
||||
public struct TrunkSizes: Sendable {
|
||||
public var create: @Sendable (DuctSizing.TrunkSize.Create) async throws -> DuctSizing.TrunkSize
|
||||
public var delete: @Sendable (DuctSizing.TrunkSize.ID) async throws -> Void
|
||||
public var fetch: @Sendable (Project.ID) async throws -> [DuctSizing.TrunkSize]
|
||||
public var get: @Sendable (DuctSizing.TrunkSize.ID) async throws -> DuctSizing.TrunkSize?
|
||||
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 (DuctSizing.TrunkSize.ID, DuctSizing.TrunkSize.Update) async throws ->
|
||||
DuctSizing.TrunkSize
|
||||
@Sendable (TrunkSize.ID, TrunkSize.Update) async throws ->
|
||||
TrunkSize
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ extension DatabaseClient.TrunkSizes: TestDependencyKey {
|
||||
try request.validate()
|
||||
|
||||
let trunk = request.toModel()
|
||||
var roomProxies = [DuctSizing.TrunkSize.RoomProxy]()
|
||||
var roomProxies = [TrunkSize.RoomProxy]()
|
||||
|
||||
try await trunk.save(on: database)
|
||||
|
||||
@@ -90,7 +90,7 @@ extension DatabaseClient.TrunkSizes: TestDependencyKey {
|
||||
}
|
||||
}
|
||||
|
||||
extension DuctSizing.TrunkSize.Create {
|
||||
extension TrunkSize.Create {
|
||||
|
||||
func validate() throws(ValidationError) {
|
||||
guard rooms.count > 0 else {
|
||||
@@ -113,7 +113,7 @@ extension DuctSizing.TrunkSize.Create {
|
||||
}
|
||||
}
|
||||
|
||||
extension DuctSizing.TrunkSize.Update {
|
||||
extension TrunkSize.Update {
|
||||
func validate() throws(ValidationError) {
|
||||
if let rooms {
|
||||
guard rooms.count > 0 else {
|
||||
@@ -128,7 +128,7 @@ extension DuctSizing.TrunkSize.Update {
|
||||
}
|
||||
}
|
||||
|
||||
extension DuctSizing.TrunkSize {
|
||||
extension TrunkSize {
|
||||
|
||||
struct Migrate: AsyncMigration {
|
||||
let name = "CreateTrunkSize"
|
||||
@@ -192,7 +192,7 @@ final class TrunkRoomModel: Model, @unchecked Sendable {
|
||||
trunkID: TrunkModel.IDValue,
|
||||
roomID: RoomModel.IDValue,
|
||||
registers: [Int],
|
||||
type: DuctSizing.TrunkSize.TrunkType
|
||||
type: TrunkSize.TrunkType
|
||||
) {
|
||||
self.id = id
|
||||
$trunk.id = trunkID
|
||||
@@ -201,7 +201,7 @@ final class TrunkRoomModel: Model, @unchecked Sendable {
|
||||
self.type = type.rawValue
|
||||
}
|
||||
|
||||
func toDTO(on database: any Database) async throws -> DuctSizing.TrunkSize.RoomProxy {
|
||||
func toDTO(on database: any Database) async throws -> TrunkSize.RoomProxy {
|
||||
guard let room = try await RoomModel.find($room.id, on: database) else {
|
||||
throw NotFoundError()
|
||||
}
|
||||
@@ -240,7 +240,7 @@ final class TrunkModel: Model, @unchecked Sendable {
|
||||
init(
|
||||
id: UUID? = nil,
|
||||
projectID: Project.ID,
|
||||
type: DuctSizing.TrunkSize.TrunkType,
|
||||
type: TrunkSize.TrunkType,
|
||||
height: Int? = nil,
|
||||
name: String? = nil
|
||||
) {
|
||||
@@ -251,15 +251,15 @@ final class TrunkModel: Model, @unchecked Sendable {
|
||||
self.name = name
|
||||
}
|
||||
|
||||
func toDTO(on database: any Database) async throws -> DuctSizing.TrunkSize {
|
||||
let rooms = try await withThrowingTaskGroup(of: DuctSizing.TrunkSize.RoomProxy.self) { group in
|
||||
func toDTO(on database: any Database) async throws -> TrunkSize {
|
||||
let rooms = try await withThrowingTaskGroup(of: TrunkSize.RoomProxy.self) { group in
|
||||
for room in self.rooms {
|
||||
group.addTask {
|
||||
try await room.toDTO(on: database)
|
||||
}
|
||||
}
|
||||
|
||||
return try await group.reduce(into: [DuctSizing.TrunkSize.RoomProxy]()) {
|
||||
return try await group.reduce(into: [TrunkSize.RoomProxy]()) {
|
||||
$0.append($1)
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ final class TrunkModel: Model, @unchecked Sendable {
|
||||
}
|
||||
|
||||
func applyUpdates(
|
||||
_ updates: DuctSizing.TrunkSize.Update,
|
||||
_ updates: TrunkSize.Update,
|
||||
on database: any Database
|
||||
) async throws {
|
||||
if let type = updates.type, type.rawValue != self.type {
|
||||
@@ -340,15 +340,15 @@ final class TrunkModel: Model, @unchecked Sendable {
|
||||
|
||||
extension Array where Element == TrunkModel {
|
||||
|
||||
func toDTO(on database: any Database) async throws -> [DuctSizing.TrunkSize] {
|
||||
try await withThrowingTaskGroup(of: DuctSizing.TrunkSize.self) { group in
|
||||
func toDTO(on database: any Database) async throws -> [TrunkSize] {
|
||||
try await withThrowingTaskGroup(of: TrunkSize.self) { group in
|
||||
for model in self {
|
||||
group.addTask {
|
||||
try await model.toDTO(on: database)
|
||||
}
|
||||
}
|
||||
|
||||
return try await group.reduce(into: [DuctSizing.TrunkSize]()) {
|
||||
return try await group.reduce(into: [TrunkSize]()) {
|
||||
$0.append($1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ extension Room {
|
||||
}
|
||||
}
|
||||
|
||||
extension DuctSizing.TrunkSize.RoomProxy {
|
||||
extension TrunkSize.RoomProxy {
|
||||
|
||||
// We need to make sure if registers got removed after a trunk
|
||||
// was already made / saved that we do not include registers that
|
||||
@@ -35,7 +35,7 @@ extension DuctSizing.TrunkSize.RoomProxy {
|
||||
}
|
||||
}
|
||||
|
||||
extension DuctSizing.TrunkSize {
|
||||
extension TrunkSize {
|
||||
|
||||
var totalHeatingLoad: Double {
|
||||
rooms.reduce(into: 0) { $0 += $1.totalHeatingLoad }
|
||||
|
||||
@@ -114,7 +114,7 @@ extension DuctSizing {
|
||||
self.ductSize = ductSize
|
||||
}
|
||||
|
||||
public subscript<T>(dynamicMember keyPath: KeyPath<DuctSizing.TrunkSize, T>) -> T {
|
||||
public subscript<T>(dynamicMember keyPath: KeyPath<TrunkSize, T>) -> T {
|
||||
trunk[keyPath: keyPath]
|
||||
}
|
||||
|
||||
@@ -122,99 +122,4 @@ extension DuctSizing {
|
||||
ductSize[keyPath: keyPath]
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add an optional label that the user can set.
|
||||
|
||||
// Represents the database model.
|
||||
public struct TrunkSize: Codable, Equatable, Identifiable, Sendable {
|
||||
|
||||
public let id: UUID
|
||||
public let projectID: Project.ID
|
||||
public let type: TrunkType
|
||||
public let rooms: [RoomProxy]
|
||||
public let height: Int?
|
||||
public let name: String?
|
||||
|
||||
public init(
|
||||
id: UUID,
|
||||
projectID: Project.ID,
|
||||
type: DuctSizing.TrunkSize.TrunkType,
|
||||
rooms: [DuctSizing.TrunkSize.RoomProxy],
|
||||
height: Int? = nil,
|
||||
name: String? = nil
|
||||
) {
|
||||
self.id = id
|
||||
self.projectID = projectID
|
||||
self.type = type
|
||||
self.rooms = rooms
|
||||
self.height = height
|
||||
self.name = name
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension DuctSizing.TrunkSize {
|
||||
public struct Create: Codable, Equatable, Sendable {
|
||||
|
||||
public let projectID: Project.ID
|
||||
public let type: TrunkType
|
||||
public let rooms: [Room.ID: [Int]]
|
||||
public let height: Int?
|
||||
public let name: String?
|
||||
|
||||
public init(
|
||||
projectID: Project.ID,
|
||||
type: DuctSizing.TrunkSize.TrunkType,
|
||||
rooms: [Room.ID: [Int]],
|
||||
height: Int? = nil,
|
||||
name: String? = nil
|
||||
) {
|
||||
self.projectID = projectID
|
||||
self.type = type
|
||||
self.rooms = rooms
|
||||
self.height = height
|
||||
self.name = name
|
||||
}
|
||||
}
|
||||
|
||||
public struct Update: Codable, Equatable, Sendable {
|
||||
|
||||
public let type: TrunkType?
|
||||
public let rooms: [Room.ID: [Int]]?
|
||||
public let height: Int?
|
||||
public let name: String?
|
||||
|
||||
public init(
|
||||
type: DuctSizing.TrunkSize.TrunkType? = nil,
|
||||
rooms: [Room.ID: [Int]]? = nil,
|
||||
height: Int? = nil,
|
||||
name: String? = nil
|
||||
) {
|
||||
self.type = type
|
||||
self.rooms = rooms
|
||||
self.height = height
|
||||
self.name = name
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Make registers non-optional
|
||||
public struct RoomProxy: Codable, Equatable, Identifiable, Sendable {
|
||||
|
||||
public var id: Room.ID { room.id }
|
||||
public let room: Room
|
||||
public let registers: [Int]
|
||||
|
||||
public init(room: Room, registers: [Int]) {
|
||||
self.room = room
|
||||
self.registers = registers
|
||||
}
|
||||
}
|
||||
|
||||
public enum TrunkType: String, CaseIterable, Codable, Equatable, Sendable {
|
||||
case `return`
|
||||
case supply
|
||||
|
||||
public static let allCases = [Self.supply, .return]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -668,9 +668,9 @@ extension SiteRoute.View.ProjectRoute {
|
||||
}
|
||||
|
||||
public enum TrunkRoute: Equatable, Sendable {
|
||||
case delete(DuctSizing.TrunkSize.ID)
|
||||
case delete(TrunkSize.ID)
|
||||
case submit(TrunkSizeForm)
|
||||
case update(DuctSizing.TrunkSize.ID, TrunkSizeForm)
|
||||
case update(TrunkSize.ID, TrunkSizeForm)
|
||||
|
||||
public static let rootPath = "trunk"
|
||||
|
||||
@@ -678,7 +678,7 @@ extension SiteRoute.View.ProjectRoute {
|
||||
Route(.case(Self.delete)) {
|
||||
Path {
|
||||
rootPath
|
||||
DuctSizing.TrunkSize.ID.parser()
|
||||
TrunkSize.ID.parser()
|
||||
}
|
||||
Method.delete
|
||||
}
|
||||
@@ -690,7 +690,7 @@ extension SiteRoute.View.ProjectRoute {
|
||||
Body {
|
||||
FormData {
|
||||
Field("projectID") { Project.ID.parser() }
|
||||
Field("type") { DuctSizing.TrunkSize.TrunkType.parser() }
|
||||
Field("type") { TrunkSize.TrunkType.parser() }
|
||||
Optionally {
|
||||
Field("height") { Int.parser() }
|
||||
|
||||
@@ -708,13 +708,13 @@ extension SiteRoute.View.ProjectRoute {
|
||||
Route(.case(Self.update)) {
|
||||
Path {
|
||||
rootPath
|
||||
DuctSizing.TrunkSize.ID.parser()
|
||||
TrunkSize.ID.parser()
|
||||
}
|
||||
Method.patch
|
||||
Body {
|
||||
FormData {
|
||||
Field("projectID") { Project.ID.parser() }
|
||||
Field("type") { DuctSizing.TrunkSize.TrunkType.parser() }
|
||||
Field("type") { TrunkSize.TrunkType.parser() }
|
||||
Optionally {
|
||||
Field("height") { Int.parser() }
|
||||
}
|
||||
@@ -732,17 +732,43 @@ extension SiteRoute.View.ProjectRoute {
|
||||
}
|
||||
|
||||
public struct RoomRectangularForm: Equatable, Sendable {
|
||||
|
||||
public let id: Room.RectangularSize.ID?
|
||||
public let register: Int
|
||||
public let height: Int
|
||||
|
||||
public init(
|
||||
id: Room.RectangularSize.ID? = nil,
|
||||
register: Int,
|
||||
height: Int
|
||||
) {
|
||||
self.id = id
|
||||
self.register = register
|
||||
self.height = height
|
||||
}
|
||||
}
|
||||
|
||||
public struct TrunkSizeForm: Equatable, Sendable {
|
||||
|
||||
public let projectID: Project.ID
|
||||
public let type: DuctSizing.TrunkSize.TrunkType
|
||||
public let type: TrunkSize.TrunkType
|
||||
public let height: Int?
|
||||
public let name: String?
|
||||
public let rooms: [String]
|
||||
|
||||
public init(
|
||||
projectID: Project.ID,
|
||||
type: TrunkSize.TrunkType,
|
||||
height: Int? = nil,
|
||||
name: String? = nil,
|
||||
rooms: [String]
|
||||
) {
|
||||
self.projectID = projectID
|
||||
self.type = type
|
||||
self.height = height
|
||||
self.name = name
|
||||
self.rooms = rooms
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
93
Sources/ManualDCore/TrunkSize.swift
Normal file
93
Sources/ManualDCore/TrunkSize.swift
Normal file
@@ -0,0 +1,93 @@
|
||||
import Foundation
|
||||
|
||||
// Represents the database model.
|
||||
public struct TrunkSize: Codable, Equatable, Identifiable, Sendable {
|
||||
|
||||
public let id: UUID
|
||||
public let projectID: Project.ID
|
||||
public let type: TrunkType
|
||||
public let rooms: [RoomProxy]
|
||||
public let height: Int?
|
||||
public let name: String?
|
||||
|
||||
public init(
|
||||
id: UUID,
|
||||
projectID: Project.ID,
|
||||
type: TrunkType,
|
||||
rooms: [RoomProxy],
|
||||
height: Int? = nil,
|
||||
name: String? = nil
|
||||
) {
|
||||
self.id = id
|
||||
self.projectID = projectID
|
||||
self.type = type
|
||||
self.rooms = rooms
|
||||
self.height = height
|
||||
self.name = name
|
||||
}
|
||||
}
|
||||
|
||||
extension TrunkSize {
|
||||
public struct Create: Codable, Equatable, Sendable {
|
||||
|
||||
public let projectID: Project.ID
|
||||
public let type: TrunkType
|
||||
public let rooms: [Room.ID: [Int]]
|
||||
public let height: Int?
|
||||
public let name: String?
|
||||
|
||||
public init(
|
||||
projectID: Project.ID,
|
||||
type: TrunkType,
|
||||
rooms: [Room.ID: [Int]],
|
||||
height: Int? = nil,
|
||||
name: String? = nil
|
||||
) {
|
||||
self.projectID = projectID
|
||||
self.type = type
|
||||
self.rooms = rooms
|
||||
self.height = height
|
||||
self.name = name
|
||||
}
|
||||
}
|
||||
|
||||
public struct Update: Codable, Equatable, Sendable {
|
||||
|
||||
public let type: TrunkType?
|
||||
public let rooms: [Room.ID: [Int]]?
|
||||
public let height: Int?
|
||||
public let name: String?
|
||||
|
||||
public init(
|
||||
type: TrunkType? = nil,
|
||||
rooms: [Room.ID: [Int]]? = nil,
|
||||
height: Int? = nil,
|
||||
name: String? = nil
|
||||
) {
|
||||
self.type = type
|
||||
self.rooms = rooms
|
||||
self.height = height
|
||||
self.name = name
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Make registers non-optional
|
||||
public struct RoomProxy: Codable, Equatable, Identifiable, Sendable {
|
||||
|
||||
public var id: Room.ID { room.id }
|
||||
public let room: Room
|
||||
public let registers: [Int]
|
||||
|
||||
public init(room: Room, registers: [Int]) {
|
||||
self.room = room
|
||||
self.registers = registers
|
||||
}
|
||||
}
|
||||
|
||||
public enum TrunkType: String, CaseIterable, Codable, Equatable, Sendable {
|
||||
case `return`
|
||||
case supply
|
||||
|
||||
public static let allCases = [Self.supply, .return]
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ extension ManualDClient {
|
||||
|
||||
func calculateDuctSizes(
|
||||
rooms: [Room],
|
||||
trunks: [DuctSizing.TrunkSize],
|
||||
trunks: [TrunkSize],
|
||||
sharedRequest: DuctSizeSharedRequest,
|
||||
logger: Logger? = nil
|
||||
) async throws -> ProjectClient.DuctSizeResponse {
|
||||
@@ -93,7 +93,7 @@ extension ManualDClient {
|
||||
|
||||
func calculateTrunkSizes(
|
||||
rooms: [Room],
|
||||
trunks: [DuctSizing.TrunkSize],
|
||||
trunks: [TrunkSize],
|
||||
sharedRequest: DuctSizeSharedRequest,
|
||||
logger: Logger? = nil
|
||||
) async throws -> [DuctSizing.TrunkContainer] {
|
||||
@@ -190,7 +190,7 @@ extension Room {
|
||||
}
|
||||
}
|
||||
|
||||
extension DuctSizing.TrunkSize.RoomProxy {
|
||||
extension TrunkSize.RoomProxy {
|
||||
|
||||
// We need to make sure if registers got removed after a trunk
|
||||
// was already made / saved that we do not include registers that
|
||||
@@ -211,7 +211,7 @@ extension DuctSizing.TrunkSize.RoomProxy {
|
||||
}
|
||||
}
|
||||
|
||||
extension DuctSizing.TrunkSize {
|
||||
extension TrunkSize {
|
||||
|
||||
var totalHeatingLoad: Double {
|
||||
rooms.reduce(into: 0) { $0 += $1.totalHeatingLoad }
|
||||
|
||||
@@ -4,7 +4,7 @@ import ManualDCore
|
||||
|
||||
extension SiteRoute.View.ProjectRoute.DuctSizingRoute.TrunkSizeForm {
|
||||
|
||||
func toCreate(logger: Logger? = nil) throws -> DuctSizing.TrunkSize.Create {
|
||||
func toCreate(logger: Logger? = nil) throws -> TrunkSize.Create {
|
||||
try .init(
|
||||
projectID: projectID,
|
||||
type: type,
|
||||
@@ -14,7 +14,7 @@ extension SiteRoute.View.ProjectRoute.DuctSizingRoute.TrunkSizeForm {
|
||||
)
|
||||
}
|
||||
|
||||
func toUpdate(logger: Logger? = nil) throws -> DuctSizing.TrunkSize.Update {
|
||||
func toUpdate(logger: Logger? = nil) throws -> TrunkSize.Update {
|
||||
try .init(
|
||||
type: type,
|
||||
rooms: makeRooms(logger: logger),
|
||||
|
||||
@@ -17,7 +17,7 @@ struct TrunkSizeForm: HTML, Sendable {
|
||||
let rooms: [DuctSizing.RoomContainer]
|
||||
let dismiss: Bool
|
||||
|
||||
var trunk: DuctSizing.TrunkSize? {
|
||||
var trunk: TrunkSize? {
|
||||
container?.trunk
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ struct TrunkSizeForm: HTML, Sendable {
|
||||
label(.class("select w-full")) {
|
||||
span(.class("label")) { "Type" }
|
||||
select(.name("type")) {
|
||||
for type in DuctSizing.TrunkSize.TrunkType.allCases {
|
||||
for type in TrunkSize.TrunkType.allCases {
|
||||
option(.value(type.rawValue)) { type.rawValue.capitalized }
|
||||
.attributes(.selected, when: trunk?.type == type)
|
||||
}
|
||||
@@ -121,7 +121,7 @@ struct TrunkSizeForm: HTML, Sendable {
|
||||
|
||||
}
|
||||
|
||||
extension Array where Element == DuctSizing.TrunkSize.RoomProxy {
|
||||
extension Array where Element == TrunkSize.RoomProxy {
|
||||
func hasRoom(_ room: DuctSizing.RoomContainer) -> Bool {
|
||||
first {
|
||||
$0.id == room.roomID
|
||||
|
||||
Reference in New Issue
Block a user