Milestone 5. One BackupManager entry point so export, import and auto-backup share the same serializer and crypto by construction. Explicit DTOs decouple the backup contract from the Room schema. JCE baseline (PBKDF2-HMAC-SHA256 600k → AES-256-GCM) behind the BackupCrypto interface with format auto-detection on decrypt; age lands behind the same interface in milestone 6. SigV4 signer verified against AWS's published documentation example signature. Settings in SharedPreferences encrypted under a non-exportable AndroidKeyStore key — replaces the now fully deprecated androidx security-crypto with the same construction (~70 lines, zero deps); threat-model comments state plainly that the stored auto-backup passphrase only protects against bucket compromise. WorkManager daily periodic job, inexact by design. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
51 lines
1.3 KiB
Kotlin
51 lines
1.3 KiB
Kotlin
package no.naiv.meddetsamme.data
|
|
|
|
import androidx.room.Dao
|
|
import androidx.room.Insert
|
|
import androidx.room.Query
|
|
import androidx.room.Transaction
|
|
|
|
/**
|
|
* Bulk read/replace for backup. Inserts preserve original ids (autoGenerate
|
|
* only kicks in for id = 0), which keeps FK references in the file intact.
|
|
*/
|
|
@Dao
|
|
interface BackupDao {
|
|
|
|
@Query("SELECT * FROM medication")
|
|
suspend fun allMedications(): List<Medication>
|
|
|
|
@Query("SELECT * FROM dose_time")
|
|
suspend fun allDoseTimes(): List<DoseTime>
|
|
|
|
@Query("SELECT * FROM dose_log")
|
|
suspend fun allDoseLogs(): List<DoseLog>
|
|
|
|
@Query("DELETE FROM medication")
|
|
suspend fun clearMedications()
|
|
|
|
@Insert
|
|
suspend fun insertMedications(meds: List<Medication>)
|
|
|
|
@Insert
|
|
suspend fun insertDoseTimes(doseTimes: List<DoseTime>)
|
|
|
|
@Insert
|
|
suspend fun insertDoseLogs(logs: List<DoseLog>)
|
|
|
|
/**
|
|
* Replace-all restore. Deleting medication CASCADEs to dose_time and
|
|
* dose_log, so one delete clears everything; insertion order respects FKs.
|
|
*/
|
|
@Transaction
|
|
suspend fun replaceAll(
|
|
meds: List<Medication>,
|
|
doseTimes: List<DoseTime>,
|
|
logs: List<DoseLog>,
|
|
) {
|
|
clearMedications()
|
|
insertMedications(meds)
|
|
insertDoseTimes(doseTimes)
|
|
insertDoseLogs(logs)
|
|
}
|
|
}
|