Prechádzať zdrojové kódy

Merge pull request #980 from ryceg/fix/delete-glucose-ns

Fix: Delete Glucose entries in Nightscout API
Deniz Cengiz 2 týždňov pred
rodič
commit
c174051bb5

+ 0 - 10
Model/Helper/GlucoseStored+helper.swift

@@ -93,16 +93,6 @@ extension NSPredicate {
         return NSPredicate(format: "date >= %@ AND isUploadedToTidepool == %@", date as NSDate, false as NSNumber)
         return NSPredicate(format: "date >= %@ AND isUploadedToTidepool == %@", date as NSDate, false as NSNumber)
     }
     }
 
 
-    static var manualGlucoseNotYetUploadedToNightscout: NSPredicate {
-        let date = Date.oneDayAgo
-        return NSPredicate(
-            format: "date >= %@ AND isUploadedToNS == %@ AND isManual == %@",
-            date as NSDate,
-            false as NSNumber,
-            true as NSNumber
-        )
-    }
-
     static var manualGlucoseNotYetUploadedToHealth: NSPredicate {
     static var manualGlucoseNotYetUploadedToHealth: NSPredicate {
         let date = Date.oneDayAgo
         let date = Date.oneDayAgo
         return NSPredicate(
         return NSPredicate(

+ 1 - 1
Model/JSONImporter.swift

@@ -355,7 +355,7 @@ extension BloodGlucose {
         }
         }
 
 
         let glucoseEntry = GlucoseStored(context: context)
         let glucoseEntry = GlucoseStored(context: context)
-        glucoseEntry.id = _id.flatMap({ UUID(uuidString: $0) }) ?? UUID()
+        glucoseEntry.id = UUID(uuidString: id) ?? UUID()
         glucoseEntry.date = dateString
         glucoseEntry.date = dateString
         glucoseEntry.glucose = Int16(glucoseValue)
         glucoseEntry.glucose = Int16(glucoseValue)
         glucoseEntry.direction = direction?.rawValue
         glucoseEntry.direction = direction?.rawValue

+ 1 - 1
Trio/Sources/APS/CGM/GlucoseSimulatorSource.swift

@@ -217,7 +217,7 @@ class OscillatingGenerator: BloodGlucoseGenerator {
 
 
             // Create BloodGlucose with the correct constructor
             // Create BloodGlucose with the correct constructor
             let bloodGlucose = BloodGlucose(
             let bloodGlucose = BloodGlucose(
-                _id: UUID().uuidString,
+                id: UUID().uuidString,
                 sgv: glucose,
                 sgv: glucose,
                 direction: direction,
                 direction: direction,
                 date: Decimal(Int(currentDate.timeIntervalSince1970) * 1000),
                 date: Decimal(Int(currentDate.timeIntervalSince1970) * 1000),

+ 1 - 1
Trio/Sources/APS/CGM/PluginSource.swift

@@ -236,7 +236,7 @@ extension PluginSource: CGMManagerDelegate {
 
 
                 let value = Int(quantity.doubleValue(for: .milligramsPerDeciliter))
                 let value = Int(quantity.doubleValue(for: .milligramsPerDeciliter))
                 return BloodGlucose(
                 return BloodGlucose(
-                    _id: UUID().uuidString,
+                    id: UUID().uuidString,
                     sgv: value,
                     sgv: value,
                     direction: .init(trendType: newGlucoseSample.trend),
                     direction: .init(trendType: newGlucoseSample.trend),
                     date: Decimal(Int(newGlucoseSample.date.timeIntervalSince1970 * 1000)),
                     date: Decimal(Int(newGlucoseSample.date.timeIntervalSince1970 * 1000)),

+ 1 - 1
Trio/Sources/APS/DeviceDataManager.swift

@@ -357,7 +357,7 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable {
                         let results = glucose.enumerated().map { index, sample -> BloodGlucose in
                         let results = glucose.enumerated().map { index, sample -> BloodGlucose in
                             let value = Int(sample.quantity.doubleValue(for: .milligramsPerDeciliter))
                             let value = Int(sample.quantity.doubleValue(for: .milligramsPerDeciliter))
                             return BloodGlucose(
                             return BloodGlucose(
-                                _id: sample.syncIdentifier,
+                                id: sample.syncIdentifier,
                                 sgv: value,
                                 sgv: value,
                                 direction: directions[index],
                                 direction: directions[index],
                                 date: Decimal(Int(sample.date.timeIntervalSince1970 * 1000)),
                                 date: Decimal(Int(sample.date.timeIntervalSince1970 * 1000)),

+ 26 - 63
Trio/Sources/APS/Storage/GlucoseStorage.swift

@@ -19,7 +19,6 @@ protocol GlucoseStorage {
     func isGlucoseFresh() -> Bool
     func isGlucoseFresh() -> Bool
     func getGlucoseNotYetUploadedToNightscout() async throws -> [BloodGlucose]
     func getGlucoseNotYetUploadedToNightscout() async throws -> [BloodGlucose]
     func getCGMStateNotYetUploadedToNightscout() async throws -> [NightscoutTreatment]
     func getCGMStateNotYetUploadedToNightscout() async throws -> [NightscoutTreatment]
-    func getManualGlucoseNotYetUploadedToNightscout() async throws -> [NightscoutTreatment]
     func getGlucoseNotYetUploadedToHealth() async throws -> [BloodGlucose]
     func getGlucoseNotYetUploadedToHealth() async throws -> [BloodGlucose]
     func getManualGlucoseNotYetUploadedToHealth() async throws -> [BloodGlucose]
     func getManualGlucoseNotYetUploadedToHealth() async throws -> [BloodGlucose]
     func getGlucoseNotYetUploadedToTidepool() async throws -> [StoredGlucoseSample]
     func getGlucoseNotYetUploadedToTidepool() async throws -> [StoredGlucoseSample]
@@ -411,64 +410,28 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
             }
             }
 
 
             return fetchedResults.map { result in
             return fetchedResults.map { result in
-                BloodGlucose(
-                    _id: result.id?.uuidString ?? UUID().uuidString,
-                    sgv: Int(result.glucose),
-                    direction: BloodGlucose.Direction(from: result.direction ?? ""),
-                    date: Decimal(result.date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000,
-                    dateString: result.date ?? Date(),
-                    unfiltered: Decimal(result.glucose),
-                    filtered: Decimal(result.glucose),
-                    noise: nil,
-                    glucose: Int(result.glucose),
-                    type: "sgv"
-                )
-            }
-        }
-    }
-
-    // Fetch manual glucose that is not uploaded to Nightscout yet
-    /// - Returns: Array of NightscoutTreatment to ensure the correct format for the NS Upload
-    func getManualGlucoseNotYetUploadedToNightscout() async throws -> [NightscoutTreatment] {
-        let results = try await CoreDataStack.shared.fetchEntitiesAsync(
-            ofType: GlucoseStored.self,
-            onContext: context,
-            predicate: NSPredicate.manualGlucoseNotYetUploadedToNightscout,
-            key: "date",
-            ascending: false
-        )
-
-        return try await context.perform {
-            guard let fetchedResults = results as? [GlucoseStored] else {
-                throw CoreDataError.fetchError(function: #function, file: #file)
-            }
-
-            return fetchedResults.map { result in
-                NightscoutTreatment(
-                    duration: nil,
-                    rawDuration: nil,
-                    rawRate: nil,
-                    absolute: nil,
-                    rate: nil,
-                    eventType: .capillaryGlucose,
-                    createdAt: result.date,
-                    enteredBy: CarbsEntry.local,
-                    bolus: nil,
-                    insulin: nil,
-                    notes: "Trio User",
-                    carbs: nil,
-                    fat: nil,
-                    protein: nil,
-                    foodType: nil,
-                    targetTop: nil,
-                    targetBottom: nil,
-                    glucoseType: "Manual",
-                    glucose: self.settingsManager.settings
-                        .units == .mgdL ? (self.glucoseFormatter.string(from: Int(result.glucose) as NSNumber) ?? "")
-                        : (self.glucoseFormatter.string(from: Decimal(result.glucose).asMmolL as NSNumber) ?? ""),
-                    units: self.settingsManager.settings.units == .mmolL ? "mmol" : "mg/dl",
-                    id: result.id?.uuidString
-                )
+                if result.isManual {
+                    BloodGlucose(
+                        id: result.id?.uuidString ?? UUID().uuidString,
+                        mbg: Int(result.glucose),
+                        date: Decimal(result.date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000,
+                        dateString: result.date ?? Date(),
+                        type: "mbg"
+                    )
+                } else {
+                    BloodGlucose(
+                        id: result.id?.uuidString ?? UUID().uuidString,
+                        sgv: Int(result.glucose),
+                        direction: BloodGlucose.Direction(from: result.direction ?? ""),
+                        date: Decimal(result.date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000,
+                        dateString: result.date ?? Date(),
+                        unfiltered: Decimal(result.glucose),
+                        filtered: Decimal(result.glucose),
+                        noise: nil,
+                        glucose: Int(result.glucose),
+                        type: "sgv"
+                    )
+                }
             }
             }
         }
         }
     }
     }
@@ -501,7 +464,7 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
 
 
             return fetchedResults.map { result in
             return fetchedResults.map { result in
                 BloodGlucose(
                 BloodGlucose(
-                    _id: result.id?.uuidString ?? UUID().uuidString,
+                    id: result.id?.uuidString ?? UUID().uuidString,
                     sgv: Int(result.glucose),
                     sgv: Int(result.glucose),
                     direction: BloodGlucose.Direction(from: result.direction ?? ""),
                     direction: BloodGlucose.Direction(from: result.direction ?? ""),
                     date: Decimal(result.date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000,
                     date: Decimal(result.date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000,
@@ -533,7 +496,7 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
 
 
             return fetchedResults.map { result in
             return fetchedResults.map { result in
                 BloodGlucose(
                 BloodGlucose(
-                    _id: result.id?.uuidString ?? UUID().uuidString,
+                    id: result.id?.uuidString ?? UUID().uuidString,
                     sgv: Int(result.glucose),
                     sgv: Int(result.glucose),
                     direction: BloodGlucose.Direction(from: result.direction ?? ""),
                     direction: BloodGlucose.Direction(from: result.direction ?? ""),
                     date: Decimal(result.date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000,
                     date: Decimal(result.date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000,
@@ -565,7 +528,7 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
 
 
             return fetchedResults.map { result in
             return fetchedResults.map { result in
                 BloodGlucose(
                 BloodGlucose(
-                    _id: result.id?.uuidString ?? UUID().uuidString,
+                    id: result.id?.uuidString ?? UUID().uuidString,
                     sgv: Int(result.glucose),
                     sgv: Int(result.glucose),
                     direction: BloodGlucose.Direction(from: result.direction ?? ""),
                     direction: BloodGlucose.Direction(from: result.direction ?? ""),
                     date: Decimal(result.date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000,
                     date: Decimal(result.date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000,
@@ -598,7 +561,7 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
 
 
             return fetchedResults.map { result in
             return fetchedResults.map { result in
                 BloodGlucose(
                 BloodGlucose(
-                    _id: result.id?.uuidString ?? UUID().uuidString,
+                    id: result.id?.uuidString ?? UUID().uuidString,
                     sgv: Int(result.glucose),
                     sgv: Int(result.glucose),
                     direction: BloodGlucose.Direction(from: result.direction ?? ""),
                     direction: BloodGlucose.Direction(from: result.direction ?? ""),
                     date: Decimal(result.date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000,
                     date: Decimal(result.date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970) * 1000,

+ 26 - 9
Trio/Sources/Models/BloodGlucose.swift

@@ -60,8 +60,10 @@ struct BloodGlucose: JSON, Identifiable, Hashable, Codable {
     }
     }
 
 
     enum CodingKeys: String, CodingKey {
     enum CodingKeys: String, CodingKey {
-        case _id
+        case legacyId = "_id"
+        case id
         case sgv
         case sgv
+        case mbg
         case direction
         case direction
         case date
         case date
         case dateString
         case dateString
@@ -77,7 +79,12 @@ struct BloodGlucose: JSON, Identifiable, Hashable, Codable {
 
 
     init(from decoder: Decoder) throws {
     init(from decoder: Decoder) throws {
         let container = try decoder.container(keyedBy: CodingKeys.self)
         let container = try decoder.container(keyedBy: CodingKeys.self)
-        _id = try container.decode(String.self, forKey: ._id)
+
+        let legacyId = try container.decodeIfPresent(String.self, forKey: .legacyId)
+        let explicitId = try container.decodeIfPresent(String.self, forKey: .id)
+
+        self.legacyId = legacyId
+        id = explicitId ?? legacyId ?? UUID().uuidString
 
 
         sgv = try? container.decodeIfPresent(Int.self, forKey: .sgv)
         sgv = try? container.decodeIfPresent(Int.self, forKey: .sgv)
         if sgv == nil {
         if sgv == nil {
@@ -87,6 +94,14 @@ struct BloodGlucose: JSON, Identifiable, Hashable, Codable {
             }
             }
             // If both attempts fail, sgv remains nil
             // If both attempts fail, sgv remains nil
         }
         }
+        mbg = try? container.decodeIfPresent(Int.self, forKey: .mbg)
+        if mbg == nil {
+            // The nightscout API might return a double instead of an int, or the key might be missing
+            if let doubleValue = try? container.decodeIfPresent(Double.self, forKey: .mbg) {
+                mbg = Int(doubleValue)
+            }
+            // If both attempts fail, sgv remains nil
+        }
 
 
         direction = try container.decodeIfPresent(Direction.self, forKey: .direction)
         direction = try container.decodeIfPresent(Direction.self, forKey: .direction)
         date = try container.decode(Decimal.self, forKey: .date)
         date = try container.decode(Decimal.self, forKey: .date)
@@ -102,8 +117,10 @@ struct BloodGlucose: JSON, Identifiable, Hashable, Codable {
     }
     }
 
 
     init(
     init(
-        _id: String = UUID().uuidString,
+        id: String = UUID().uuidString,
+        legacyId: String? = nil,
         sgv: Int? = nil,
         sgv: Int? = nil,
+        mbg: Int? = nil,
         direction: Direction? = nil,
         direction: Direction? = nil,
         date: Decimal,
         date: Decimal,
         dateString: Date,
         dateString: Date,
@@ -116,8 +133,10 @@ struct BloodGlucose: JSON, Identifiable, Hashable, Codable {
         sessionStartDate: Date? = nil,
         sessionStartDate: Date? = nil,
         transmitterID: String? = nil
         transmitterID: String? = nil
     ) {
     ) {
-        self._id = _id
+        self.id = id
+        self.legacyId = legacyId
         self.sgv = sgv
         self.sgv = sgv
+        self.mbg = mbg
         self.direction = direction
         self.direction = direction
         self.date = date
         self.date = date
         self.dateString = dateString
         self.dateString = dateString
@@ -131,12 +150,10 @@ struct BloodGlucose: JSON, Identifiable, Hashable, Codable {
         self.transmitterID = transmitterID
         self.transmitterID = transmitterID
     }
     }
 
 
-    var _id: String?
-    var id: String {
-        _id ?? UUID().uuidString
-    }
-
+    let legacyId: String?
+    var id: String
     var sgv: Int?
     var sgv: Int?
+    var mbg: Int?
     var direction: Direction?
     var direction: Direction?
     let date: Decimal
     let date: Decimal
     let dateString: Date
     let dateString: Date

+ 1 - 1
Trio/Sources/Modules/History/HistoryDataFlow.swift

@@ -244,7 +244,7 @@ enum History {
 protocol HistoryProvider: Provider {
 protocol HistoryProvider: Provider {
     func deleteCarbsFromNightscout(withID id: String)
     func deleteCarbsFromNightscout(withID id: String)
     func deleteInsulinFromNightscout(withID id: String)
     func deleteInsulinFromNightscout(withID id: String)
-    func deleteManualGlucoseFromNightscout(withID id: String)
+    func deleteGlucoseFromNightscout(withID id: String, withDate date: Date)
     func deleteGlucoseFromHealth(withSyncID id: String)
     func deleteGlucoseFromHealth(withSyncID id: String)
     func deleteMealDataFromHealth(byID id: String, sampleType: HKSampleType)
     func deleteMealDataFromHealth(byID id: String, sampleType: HKSampleType)
     func deleteInsulinFromHealth(withSyncID id: String)
     func deleteInsulinFromHealth(withSyncID id: String)

+ 2 - 2
Trio/Sources/Modules/History/HistoryProvider.swift

@@ -35,10 +35,10 @@ extension History {
             }
             }
         }
         }
 
 
-        func deleteManualGlucoseFromNightscout(withID id: String) {
+        func deleteGlucoseFromNightscout(withID id: String, withDate date: Date) {
             Task.detached { [weak self] in
             Task.detached { [weak self] in
                 guard let self = self else { return }
                 guard let self = self else { return }
-                await self.nightscoutManager.deleteManualGlucose(withID: id)
+                await self.nightscoutManager.deleteGlucose(withID: id, withDate: date)
             }
             }
         }
         }
 
 

+ 2 - 2
Trio/Sources/Modules/History/HistoryStateModel.swift

@@ -73,8 +73,8 @@ extension History {
                     }
                     }
 
 
                     // Delete from Nightscout
                     // Delete from Nightscout
-                    if let id = glucoseToDelete.id?.uuidString {
-                        self.provider.deleteManualGlucoseFromNightscout(withID: id)
+                    if let id = glucoseToDelete.id?.uuidString, let date = glucoseToDelete.date {
+                        self.provider.deleteGlucoseFromNightscout(withID: id, withDate: date)
                     }
                     }
 
 
                     // Delete from Apple Health
                     // Delete from Apple Health

+ 0 - 1
Trio/Sources/Services/Network/Nightscout/BaseNightscoutManager+Subscribers.swift

@@ -73,7 +73,6 @@ extension BaseNightscoutManager {
             .filteredByEntityName("GlucoseStored")
             .filteredByEntityName("GlucoseStored")
             .sink { [weak self] _ in
             .sink { [weak self] _ in
                 self?.requestUpload(.glucose)
                 self?.requestUpload(.glucose)
-                self?.requestUpload(.manualGlucose)
             }
             }
             .store(in: &subscriptions)
             .store(in: &subscriptions)
     }
     }

+ 10 - 5
Trio/Sources/Services/Network/Nightscout/NightscoutAPI.swift

@@ -188,14 +188,21 @@ extension NightscoutAPI {
         return
         return
     }
     }
 
 
-    func deleteManualGlucose(withId id: String) async throws {
+    func deleteGlucose(withId id: String, withDate date: Date) async throws {
         var components = URLComponents()
         var components = URLComponents()
         components.scheme = url.scheme
         components.scheme = url.scheme
         components.host = url.host
         components.host = url.host
         components.port = url.port
         components.port = url.port
-        components.path = Config.treatmentsPath
+        components.path = Config.uploadEntriesPath
         components.queryItems = [
         components.queryItems = [
-            URLQueryItem(name: "find[id][$eq]", value: id)
+            URLQueryItem(
+                name: "find[$or][0][id][$eq]",
+                value: id
+            ),
+            URLQueryItem(
+                name: "find[$or][1][dateString][$eq]",
+                value: Formatter.iso8601withFractionalSeconds.string(from: date)
+            )
         ]
         ]
 
 
         guard let url = components.url else {
         guard let url = components.url else {
@@ -216,8 +223,6 @@ extension NightscoutAPI {
         guard let httpResponse = response as? HTTPURLResponse, (200 ... 299).contains(httpResponse.statusCode) else {
         guard let httpResponse = response as? HTTPURLResponse, (200 ... 299).contains(httpResponse.statusCode) else {
             throw URLError(.badServerResponse)
             throw URLError(.badServerResponse)
         }
         }
-
-        debugPrint("Delete successful for ID \(id)")
     }
     }
 
 
     func deleteInsulin(withId id: String) async throws {
     func deleteInsulin(withId id: String) async throws {

+ 6 - 59
Trio/Sources/Services/Network/Nightscout/NightscoutManager.swift

@@ -11,14 +11,13 @@ protocol NightscoutManager: GlucoseSource {
     func fetchTempTargets() async -> [TempTarget]
     func fetchTempTargets() async -> [TempTarget]
     func deleteCarbs(withID id: String) async
     func deleteCarbs(withID id: String) async
     func deleteInsulin(withID id: String) async
     func deleteInsulin(withID id: String) async
-    func deleteManualGlucose(withID id: String) async
+    func deleteGlucose(withID id: String, withDate date: Date) async
     func uploadDeviceStatus() async throws
     func uploadDeviceStatus() async throws
     func uploadGlucose() async
     func uploadGlucose() async
     func uploadCarbs() async
     func uploadCarbs() async
     func uploadPumpHistory() async
     func uploadPumpHistory() async
     func uploadOverrides() async
     func uploadOverrides() async
     func uploadTempTargets() async
     func uploadTempTargets() async
-    func uploadManualGlucose() async
     func uploadProfiles() async throws
     func uploadProfiles() async throws
     func uploadNoteTreatment(note: String) async
     func uploadNoteTreatment(note: String) async
     func importSettings() async -> ScheduledNightscoutProfile?
     func importSettings() async -> ScheduledNightscoutProfile?
@@ -54,7 +53,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     /// coalesce into a single upload run for that pipeline.
     /// coalesce into a single upload run for that pipeline.
     let uploadPipelineInterval: [NightscoutUploadPipeline: TimeInterval] = [
     let uploadPipelineInterval: [NightscoutUploadPipeline: TimeInterval] = [
         .carbs: 2, .pumpHistory: 2, .overrides: 2, .tempTargets: 2,
         .carbs: 2, .pumpHistory: 2, .overrides: 2, .tempTargets: 2,
-        .glucose: 2, .manualGlucose: 2, .deviceStatus: 2
+        .glucose: 2, .deviceStatus: 2
     ]
     ]
 
 
     /// Subjects used to request an upload pipeline. The pipeline applies a throttle so
     /// Subjects used to request an upload pipeline. The pipeline applies a throttle so
@@ -95,7 +94,6 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         case .overrides: await uploadOverrides()
         case .overrides: await uploadOverrides()
         case .tempTargets: await uploadTempTargets()
         case .tempTargets: await uploadTempTargets()
         case .glucose: await uploadGlucose()
         case .glucose: await uploadGlucose()
-        case .manualGlucose: await uploadManualGlucose()
         case .deviceStatus:
         case .deviceStatus:
             do { try await uploadDeviceStatus() }
             do { try await uploadDeviceStatus() }
             catch { debug(.nightscout, "deviceStatus upload failed: \(error)") }
             catch { debug(.nightscout, "deviceStatus upload failed: \(error)") }
@@ -339,15 +337,16 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         }
         }
     }
     }
 
 
-    func deleteManualGlucose(withID id: String) async {
+    func deleteGlucose(withID id: String, withDate date: Date) async {
         guard let nightscout = nightscoutAPI, isUploadEnabled else { return }
         guard let nightscout = nightscoutAPI, isUploadEnabled else { return }
 
 
         do {
         do {
-            try await nightscout.deleteManualGlucose(withId: id)
+            try await nightscout.deleteGlucose(withId: id, withDate: date)
+            debug(.nightscout, "Glucose deleted")
         } catch {
         } catch {
             debug(
             debug(
                 .nightscout,
                 .nightscout,
-                "\(DebuggingIdentifiers.failed) Failed to delete Manual Glucose from Nightscout with error: \(error)"
+                "\(DebuggingIdentifiers.failed) Failed to delete Glucose from Nightscout with error: \(error)"
             )
             )
         }
         }
     }
     }
@@ -772,17 +771,6 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         }
         }
     }
     }
 
 
-    func uploadManualGlucose() async {
-        do {
-            try await uploadManualGlucose(glucoseStorage.getManualGlucoseNotYetUploadedToNightscout())
-        } catch {
-            debug(
-                .nightscout,
-                "\(DebuggingIdentifiers.failed) failed to upload manual glucose with error: \(error)"
-            )
-        }
-    }
-
     func uploadPumpHistory() async {
     func uploadPumpHistory() async {
         do {
         do {
             try await uploadPumpHistory(pumpHistoryStorage.getPumpHistoryNotYetUploadedToNightscout())
             try await uploadPumpHistory(pumpHistoryStorage.getPumpHistoryNotYetUploadedToNightscout())
@@ -928,47 +916,6 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         }
         }
     }
     }
 
 
-    private func uploadManualGlucose(_ treatments: [NightscoutTreatment]) async {
-        guard !treatments.isEmpty, let nightscout = nightscoutAPI, isUploadEnabled else {
-            return
-        }
-
-        do {
-            for chunk in treatments.chunks(ofCount: 100) {
-                try await nightscout.uploadTreatments(Array(chunk))
-            }
-
-            // If successful, update the isUploadedToNS property of the GlucoseStored objects
-            await updateManualGlucoseAsUploaded(treatments)
-
-            debug(.nightscout, "Treatments uploaded")
-        } catch {
-            debug(.nightscout, String(describing: error))
-        }
-    }
-
-    private func updateManualGlucoseAsUploaded(_ treatments: [NightscoutTreatment]) async {
-        await backgroundContext.perform {
-            let ids = treatments.map(\.id) as NSArray
-            let fetchRequest: NSFetchRequest<GlucoseStored> = GlucoseStored.fetchRequest()
-            fetchRequest.predicate = NSPredicate(format: "id IN %@", ids)
-
-            do {
-                let results = try self.backgroundContext.fetch(fetchRequest)
-                for result in results {
-                    result.isUploadedToNS = true
-                }
-
-                guard self.backgroundContext.hasChanges else { return }
-                try self.backgroundContext.save()
-            } catch let error as NSError {
-                debugPrint(
-                    "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to update isUploadedToNS: \(error.userInfo)"
-                )
-            }
-        }
-    }
-
     private func uploadCarbs(_ treatments: [NightscoutTreatment]) async {
     private func uploadCarbs(_ treatments: [NightscoutTreatment]) async {
         guard !treatments.isEmpty, let nightscout = nightscoutAPI, isUploadEnabled else {
         guard !treatments.isEmpty, let nightscout = nightscoutAPI, isUploadEnabled else {
             return
             return

+ 0 - 1
Trio/Sources/Services/Network/Nightscout/NightscoutUploadPipeline.swift

@@ -9,7 +9,6 @@ public enum NightscoutUploadPipeline: String, CaseIterable {
     case overrides
     case overrides
     case tempTargets
     case tempTargets
     case glucose
     case glucose
-    case manualGlucose
     case deviceStatus
     case deviceStatus
 }
 }
 
 

+ 0 - 15
TrioTests/CoreDataTests/GlucoseStorageTests.swift

@@ -127,21 +127,6 @@ import Testing
         #expect(notUploadedEntries[0].glucose == 160, "Glucose value should match")
         #expect(notUploadedEntries[0].glucose == 160, "Glucose value should match")
     }
     }
 
 
-    @Test("Get manual glucose not yet uploaded to Nightscout") func testGetManualGlucoseNotYetUploadedToNightscout() async throws {
-        // Given
-        storage.addManualGlucose(glucose: 180)
-
-        // When
-        let notUploadedEntries = try await storage.getManualGlucoseNotYetUploadedToNightscout()
-
-        // Then
-        #expect(!notUploadedEntries.isEmpty, "Should have manual entries not uploaded to NS")
-        let entry = notUploadedEntries[0]
-        #expect(entry.glucose == "180", "Glucose value should match")
-        #expect(entry.glucoseType == "Manual", "Type should be mbg for manual entries")
-        #expect(entry.eventType == .capillaryGlucose, "Type should be capillaryGlucose")
-    }
-
     @Test(
     @Test(
         "Test glucose alarms",
         "Test glucose alarms",
         .enabled(if: false, "Flaky test, disabled while investigating")
         .enabled(if: false, "Flaky test, disabled while investigating")