import Foundation // DTOs for the pre-login public store locator (pedifoods.com.br BFF). // See docs/plans/app-migrate-atomenta-calls-to-pedifoods-bff.md for the // exact contract these mirror. struct GuestSessionResult: Decodable, Sendable { let guestToken: String let expiresIn: Int } /// `GET /api/public/locations` returns states+cities in one call, keyed by /// state UF with an array of city names — e.g. `{"SP": ["Aguaí", "Campinas"]}`. typealias PublicLocationsResult = [String: [String]] struct PublicStoreListItem: Decodable, Sendable, Identifiable { let id: String let storeId: String? let name: String? let logo: String? let cover: String? let category: String? let isOpen: Bool? let statusLabel: String? let nextOpenLabel: String? let rating: Double? let totalReviews: Int? let deliveryTime: String? let deliveryFee: Double? let minOrder: Double? } struct PublicStoreDetail: Decodable, Sendable { let id: String let storeId: String? let slug: String? let fantasyName: String? let razaoSocial: String? let logo: String? let cover: String? let specialty: String? let phone: String? let responsiblePhone: String? let address: String? let neighborhood: String? let city: String? let state: String? let zipcode: String? let isOpen: Bool? let statusLabel: String? let nextOpenLabel: String? let averageRate: Double? let totalReviews: Int? let deliveryTime: String? let deliveryFee: Double? let deliveryPrice: Double? let minOrder: Double? let acceptPix: Bool? } // Maps the public (anonymous) store-detail projection onto the same models // StoreDetailView already renders for authenticated users, so the view // itself doesn't need to know which source the data came from. extension StoreInfoResult { init(publicDetail: PublicStoreDetail) { isOpen = publicDetail.isOpen statusLabel = publicDetail.statusLabel fantasyName = publicDetail.fantasyName phone = publicDetail.phone whatsapp = nil logo = publicDetail.logo cover = publicDetail.cover deliveryTime = publicDetail.deliveryTime minOrder = publicDetail.minOrder address = StoreAddressInfo(publicDetail: publicDetail) paymentMethods = StorePaymentMethodsInfo(acceptPix: publicDetail.acceptPix) } } extension StoreAddressInfo { init(publicDetail: PublicStoreDetail) { street = publicDetail.address number = nil neighborhood = publicDetail.neighborhood city = publicDetail.city state = publicDetail.state zipCode = publicDetail.zipcode latitude = nil longitude = nil } } extension StorePaymentMethodsInfo { /// The public projection only exposes whether Pix is accepted — every /// other payment flag is unknown until the user is authenticated and can /// see it via the real store-info call. init(acceptPix: Bool?) { paymentOnDelivery = nil paymentOnPickup = nil self.acceptPix = acceptPix acceptCash = nil acceptCreditCard = nil acceptDebitCard = nil acceptCreditVisa = nil acceptCreditMaster = nil acceptCreditElo = nil acceptCreditAmex = nil acceptCreditHipercard = nil acceptDebitVisa = nil acceptDebitMaster = nil acceptDebitElo = nil acceptVoucherAlelo = nil acceptVoucherSodexo = nil acceptVoucherTicket = nil acceptVoucherVR = nil } }