med-det-samme/app/src/main/java/no/naiv/meddetsamme/data/BackupDao.kt
Ole-Morten Duesund 8f5b18cf68 Backup: versioned JSON serializer, SigV4 + S3 client, JCE crypto, daily worker
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>
2026-06-10 13:54:13 +02:00

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)
}
}