Skip to content

Repository layer: update() breaks when destructured, create() returns data the database does not hold #134

Description

@Jberma23

Description

Two related defects in mobile/src/lib/db/repository.ts, the repeatable-entry data layer that #118 and #49 are both built on. Neither is caught by the existing tests, and neither is caught by TypeScript.

1. update() throws when detached from the repository object

update reaches its sibling method through this (repository.ts:146 and :164):

const current = await this.find(id);

this is only bound when the method is called as repo.update(...). Ordinary React usage breaks it:

const { update } = contactsRepository;   // or  onPress={repo.update}
await update(id, { name: 'Alexis' });
// → TypeError: _this2.find is not a function

Verified against the in-memory SQLite harness. Every existing update test calls contacts.update(...) on the object, so the suite stays green.

2. create() returns an object the database does not contain

create builds its return value from the caller's input rather than from what it wrote (repository.ts:136):

return { ...values, id, createdAt: now, updatedAt: now };

Two consequences, both verified:

  • A field the caller omits is stored as NULL (repository.ts:129) but returned as absent. create({ name: 'Sam' }) returns no phone key, while find() on the same id returns phone: null — so created and find(created.id) are not equal.
  • Keys not declared in config.fields are silently dropped on insert but echoed back. create({ name, phone, notAColumn }) returns ["name","phone","notAColumn","id","createdAt","updatedAt"].

The existing test at repository.test.ts:94 asserts the stored value is null, which passes while the returned value is undefined.

Nothing consumes createRepository yet, so nothing is broken in the field. But #118 and #49 build directly on it, and the cost of fixing rises with every screen written against the current behaviour.

Acceptance Criteria

  • update works when detached: const { update } = repo; await update(id, {...}) resolves
  • create()'s return value deep-equals find() on the same id, including fields the caller omitted
  • create() never returns keys outside config.fields plus the entry metadata
  • Regression tests for all three cases: the destructured call, the omitted-field round trip, the undeclared key
  • The feature/s being implemented are covered by unit tests - If not, create tests for them on this ticket

Additional Info and Resources

  • Likely fix for (1): hoist find to a plain function above the returned object and call it directly, so no method depends on this
  • Likely fix for (2): build the returned entry from fields (values[field] ?? null) rather than spreading values
  • Found in review of Add encrypted storage and biometric unlock foundation #128. Both are latent, neither is a regression
  • ENTRY_COLUMNS_SQL and the reserved-column guard are unaffected

QA

  • cd mobile && npm test — full suite green, with the new tests present
  • cd mobile && npx tsc --noEmit && npm run lint — clean

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingseverity:significantShould be fixed before shipping

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions