Stabilize beta release with warning cleanup and edge-case fixes

This commit is contained in:
Trey t
2026-02-22 13:18:14 -06:00
parent fddea81e36
commit ec2bbb4764
55 changed files with 712 additions and 315 deletions

View File

@@ -7,12 +7,13 @@
// - Expected Behavior:
// - itineraryDays() returns one ItineraryDay per calendar day from first arrival to last activity
// - Last activity day includes departure day if there are games on that day
// - tripDuration is max(1, days between first arrival and last departure + 1)
// - tripDuration is 0 when there are no stops, otherwise max(1, days between first arrival and last departure + 1)
// - cities returns deduplicated city list preserving visit order
// - displayName uses " " separator between cities
//
// - Invariants:
// - tripDuration >= 1 (minimum 1 day)
// - tripDuration >= 0
// - tripDuration == 0 iff stops is empty
// - cities has no duplicates
// - itineraryDays() dayNumber starts at 1 and increments
//

View File

@@ -56,7 +56,8 @@ struct TripPoll: Identifiable, Codable, Hashable {
private static let shareCodeCharacters = Array("ABCDEFGHJKMNPQRSTUVWXYZ23456789")
static func generateShareCode() -> String {
String((0..<6).map { _ in shareCodeCharacters.randomElement()! })
let fallback: Character = "A"
return String((0..<6).map { _ in shareCodeCharacters.randomElement() ?? fallback })
}
// MARK: - Trip Hash
@@ -73,7 +74,11 @@ struct TripPoll: Identifiable, Codable, Hashable {
// MARK: - Deep Link URL
var shareURL: URL {
URL(string: "sportstime://poll/\(shareCode)")!
var components = URLComponents()
components.scheme = "sportstime"
components.host = "poll"
components.path = "/\(shareCode)"
return components.url ?? URL(string: "sportstime://poll")!
}
}
@@ -107,9 +112,11 @@ struct PollVote: Identifiable, Codable, Hashable {
/// Returns array where index = trip index, value = score
static func calculateScores(rankings: [Int], tripCount: Int) -> [Int] {
var scores = Array(repeating: 0, count: tripCount)
var seenTripIndices = Set<Int>()
for (rank, tripIndex) in rankings.enumerated() {
guard tripIndex < tripCount else { continue }
let points = tripCount - rank
guard tripIndex >= 0, tripIndex < tripCount else { continue }
guard seenTripIndices.insert(tripIndex).inserted else { continue }
let points = max(tripCount - rank, 0)
scores[tripIndex] = points
}
return scores

View File

@@ -556,15 +556,6 @@ final class CanonicalSport {
}
}
// MARK: - Sendable Conformance
// These SwiftData models are passed across actor boundaries during sync operations.
// Access is still coordinated by SwiftData contexts and higher-level sync orchestration.
extension StadiumAlias: @unchecked Sendable {}
extension TeamAlias: @unchecked Sendable {}
extension LeagueStructureModel: @unchecked Sendable {}
extension CanonicalSport: @unchecked Sendable {}
// MARK: - Bundled Data Timestamps
/// Timestamps for bundled data files.