Review iOS app code changes for FlyFun EuroAIP architecture compliance...
Review code changes in app/FlyFunEuroAIP/ for compliance with the architecture defined in designs/IOS_APP_DESIGN.md.
RZFlight Model Reuse (CRITICAL):
RZFlight.Airport, RZFlight.Runway, RZFlight.Procedure, RZFlight.AIPEntry directlyKnownAirportsComposed AppState:
AirportDomain, ChatDomain, NavigationDomain, SystemDomain, SettingsDomain@Environment(\.appState)No ViewModels:
*ViewModel.swift filesRepository Pattern:
AirportRepositoryProtocol defines unified APILocalAirportDataSource uses KnownAirportsRZFlight.Airport directlyFilterConfig is Pure Data:
Codable structapply(to:db:) methodAPI Adapters:
APIAirportAdapter.toRZFlight() converts immediatelyAPIAirport outside adaptersRegion-Based Map Loading:
airportsInRegion(boundingBox:filters:limit:)File-Based Caching:
Caches/ directoryModern Swift Only (iOS 18.0+/macOS 15.0+):
@Observable macro (no ObservableObject)@Environment injection (no @EnvironmentObject)async/await everywhere (no Combine)Map { } builderDB is Canonical Source:
Flag these violations immediately:
Airport, Runway in app instead of using RZFlight*ViewModel.swift fileFMDatabase directly instead of KnownAirportsapply(to:db:) methodAPIAirport used outside adapter files@Model or SwiftData imports@Observableapp/FlyFunEuroAIP/import RZFlight, no import CombineRZFlight.Airport vs local AirportAPPROVED:
file:line - Explanation of why it's correctVIOLATION:
file:line - DescriptionApp/State/AppState.swift - Composed domains?App/State/Domains/*.swift - Each domain ~200-400 lines?App/Data/Repositories/AirportRepository.swift - Returns RZFlight types?App/Models/*.swift - Should be minimal (app-specific only)struct Airport - Should NOT exist (use RZFlight.Airport)UserInterface/Views/*.swift - Uses @Environment(\.appState)?UserInterface/Views/Map/*.swift - Region-based loading?RZFlight Model Usage:
// GOOD
import RZFlight
let airport: Airport // This is RZFlight.Airport
// BAD
struct AppAirport { let icao: String; let name: String }
Composed AppState:
// GOOD
@Observable @MainActor
final class AppState {
let airports: AirportDomain
let chat: ChatDomain
let navigation: NavigationDomain
}
Environment Injection:
// GOOD
struct AirportMapView: View {
@Environment(\.appState) private var state
}
// BAD
@StateObject private var viewModel = AirportMapViewModel()
Region-Based Loading:
// GOOD
func onRegionChange(_ region: MKCoordinateRegion) {
regionUpdateTask?.cancel()
regionUpdateTask = Task {
try? await Task.sleep(for: .milliseconds(300))
airports = try await repository.airportsInRegion(
boundingBox: region.paddedBy(factor: 1.3).boundingBox,
filters: filters, limit: 500
)
}
}
// BAD
airports = try await repository.allAirports() // 10K+ airports!
See designs/IOS_APP_DESIGN.md for full design details.