Summary
EventLogRecordEntity.toDomainModel() (edifikana/front-end/app/src/localDB/kotlin/com/cramsan/edifikana/client/lib/managers/mappers/EventLogRecordMappers.kt:30-45) has two ?: TODO(...) fallbacks:
timeRecorded = timeRecorded?.let { Instant.fromEpochMilliseconds(it) } ?: TODO("Time recorded cannot be null"),
unit = unit ?: TODO("Unit cannot be null"),
TODO(...) throws kotlin.NotImplementedError at runtime — these are not stubs guarded by a compile-time check, they are live, unhandled crash paths.
Why this is reachable, not just theoretical
EventLogRecordEntity.unit (the Room-persisted local DB entity) is declared UnitId? = null — genuinely nullable at the schema level (EventLogRecordEntity.kt:17). Any locally-persisted row created before unit was required (or written by any code path that doesn't set it) will have unit = null in the local SQLite DB.
EventLogRecordEntity.timeRecorded is similarly Long? = null (EventLogRecordEntity.kt:16).
toDomainModel() is called whenever a locally-cached event log record is read back out of Room (e.g. offline queue replay, list rendering from local cache). Any pre-existing row with a null unit or timeRecorded will crash the read path with NotImplementedError instead of failing gracefully or backfilling a sensible default.
This was introduced as part of making EventLogRecordModel.unit non-nullable (datastore-test-catalog.md DS-EVT-010) — the domain model was tightened, but the local DB → domain model mapper was not given a real migration/backfill strategy for existing null rows, just a TODO() placeholder.
Suggested fix (not done here — tracking only)
Decide how to handle legacy null unit/timeRecorded values on read: a Room migration to backfill/reject them, a sentinel value, or an explicit error type surfaced to the caller instead of an unhandled crash.
Tracking
Both call sites are annotated with @Defect(catalogId = "GH-<this-issue-number>") (framework:test's Defect annotation) as a known, currently-unfixed defect, to be removed once resolved.
Summary
EventLogRecordEntity.toDomainModel()(edifikana/front-end/app/src/localDB/kotlin/com/cramsan/edifikana/client/lib/managers/mappers/EventLogRecordMappers.kt:30-45) has two?: TODO(...)fallbacks:TODO(...)throwskotlin.NotImplementedErrorat runtime — these are not stubs guarded by a compile-time check, they are live, unhandled crash paths.Why this is reachable, not just theoretical
EventLogRecordEntity.unit(the Room-persisted local DB entity) is declaredUnitId? = null— genuinely nullable at the schema level (EventLogRecordEntity.kt:17). Any locally-persisted row created beforeunitwas required (or written by any code path that doesn't set it) will haveunit = nullin the local SQLite DB.EventLogRecordEntity.timeRecordedis similarlyLong? = null(EventLogRecordEntity.kt:16).toDomainModel()is called whenever a locally-cached event log record is read back out of Room (e.g. offline queue replay, list rendering from local cache). Any pre-existing row with a nullunitortimeRecordedwill crash the read path withNotImplementedErrorinstead of failing gracefully or backfilling a sensible default.This was introduced as part of making
EventLogRecordModel.unitnon-nullable (datastore-test-catalog.mdDS-EVT-010) — the domain model was tightened, but the local DB → domain model mapper was not given a real migration/backfill strategy for existing null rows, just aTODO()placeholder.Suggested fix (not done here — tracking only)
Decide how to handle legacy null
unit/timeRecordedvalues on read: a Room migration to backfill/reject them, a sentinel value, or an explicit error type surfaced to the caller instead of an unhandled crash.Tracking
Both call sites are annotated with
@Defect(catalogId = "GH-<this-issue-number>")(framework:test'sDefectannotation) as a known, currently-unfixed defect, to be removed once resolved.