Skip to content

[EDIFIKANA] EventLogRecordMappers.toDomainModel crashes via TODO() on null unit/timeRecorded #581

Description

@CRamsan

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions