glp-companion/lib/features/medication/data/repositories/medication_repository.dart

77 lines
2.8 KiB
Dart

import 'package:drift/drift.dart';
import '../../../../core/database/app_database.dart';
import '../../domain/entities/dose_entry.dart';
import '../../domain/entities/injection_site.dart';
import '../../domain/repositories/medication_repository.dart';
/// Drift-backed implementation of [IMedicationRepository].
///
/// Owns the translation between persistence records
/// ([MedicationDoseRecord]) and the pure-Dart [DoseEntry] domain entity. The
/// rotation quadrant is persisted as its stable enum name string so the
/// database schema stays decoupled from domain types.
class MedicationRepository implements IMedicationRepository {
MedicationRepository(this._database);
final AppDatabase _database;
@override
Stream<List<DoseEntry>> watchDoseEntries({int limit = 500}) => _database
.watchDoseEntries(limit: limit)
.map((records) => records.map(_mapRecord).toList(growable: false));
@override
Future<List<DoseEntry>> getDoseEntries({int limit = 500}) async =>
(await _database.getDoseEntries(limit: limit))
.map(_mapRecord)
.toList(growable: false);
@override
Future<DoseEntry> saveDoseEntry(DoseEntry entry) async {
final companion = _toCompanion(entry);
final MedicationDoseRecord record;
if (entry.id == null) {
record = await _database.insertDoseEntry(companion);
} else {
await _database.updateDoseEntry(entry.id!, companion);
record = await (_database.select(_database.medicationDosesTable)
..where((t) => t.id.equals(entry.id!)))
.getSingle();
}
return _mapRecord(record);
}
@override
Future<void> deleteDoseEntry(int id) => _database.deleteDoseEntry(id);
@override
Future<DoseEntry?> getLatestAdministeredDose() async {
final record = await _database.latestAdministeredDose();
return record == null ? null : _mapRecord(record);
}
/// Converts a persistence record into the domain entity.
DoseEntry _mapRecord(MedicationDoseRecord record) => DoseEntry(
id: record.id,
compoundName: record.compoundName,
doseMg: record.doseMg,
administeredAt: record.administeredTime ?? record.scheduledTime,
scheduledAt: record.scheduledTime,
injectionSite: InjectionSite.tryParse(record.injectionSite),
notes: record.notes,
);
/// Converts a domain entity into an insert/update companion.
MedicationDosesTableCompanion _toCompanion(DoseEntry entry) =>
MedicationDosesTableCompanion(
id: entry.id == null ? const Value.absent() : Value(entry.id!),
compoundName: Value(entry.compoundName),
doseMg: Value(entry.doseMg),
scheduledTime: Value(entry.scheduledAt),
administeredTime: Value(entry.administeredAt),
injectionSite: Value(entry.injectionSite?.persistenceKey),
notes: Value(entry.notes),
);
}