Skip to content

[EDIFIKANA] Make createProperty atomic via RPC (DS-PROP-010) - #579

Merged
CRamsan merged 11 commits into
mainfrom
cr/ds-prop-010-atomic-create-property
Jul 27, 2026
Merged

[EDIFIKANA] Make createProperty atomic via RPC (DS-PROP-010)#579
CRamsan merged 11 commits into
mainfrom
cr/ds-prop-010-atomic-create-property

Conversation

@CRamsan

@CRamsan CRamsan commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • createProperty previously issued two separate Postgrest inserts (properties, then
    user_property_mapping) with nothing wrapping them. If the second insert failed for any
    reason, the property from the first insert was already committed — an orphaned, ownerless
    property, permanently invisible via getProperties(userId) for every user.
  • Replaced both inserts with a single atomic create_property_with_owner RPC (new migration),
    mirroring the existing upsert_rent_config/transfer_ownership atomicity pattern — Postgres
    executes one RPC call as one transaction, so a failure on either insert rolls back both.
  • Removed the now-dead PropertyEntity.CreatePropertyEntity model and its SupabaseMappers.kt
    factory function, since nothing constructs the old two-step insert payload anymore.
  • Updated datastore-test-catalog.md (Finding Build Tech Doc #3 / DS-PROP-010) to record the fix.

Demo

N/A — no UI changes.

References

Test plan

  • ./gradlew :edifikana:back-end:release --quiet — clean build
  • New test DS-PROP-010b createProperty should not leave an orphaned property row when the owner mapping insert fails — fabricates a nonexistent creatorUserId (FK violation), confirms Result.isFailure, and confirms via a raw untyped select that no orphaned properties row survives
  • Existing DS-PROP-010 createProperty should create both the property and its owning user_property_mapping (happy path) still passes unmodified against the new RPC-backed implementation
  • ./gradlew :edifikana:back-end:integTest --tests "*SupabasePropertyDatastoreIntegrationTest*" — all pass
  • ./gradlew :edifikana:back-end:integTest (full suite) — 264/264 pass, no regressions

Cramsan added 11 commits July 27, 2026 00:22
…og (NONE)

DS-X-009 (property-side RESTRICT-vs-CASCADE sweep) already existed and
passes live -- discovered during implementation, not written as part
of this work. Adds DS-X-009b to the catalog for the newly-added
unit-side sweep test, and reframes Finding #6 from speculative to
confirmed with the observed outcome.
… RPC (NONE)

createProperty previously issued two separate Postgrest inserts (properties,
then user_property_mapping) with nothing wrapping them, so a failure on the
second call left an orphaned, ownerless property row behind. Both inserts now
run inside a single RPC call, which Postgres executes as one transaction.
Confirms createProperty's new atomic RPC leaves no orphaned property row
behind when the owner-mapping insert fails on a nonexistent creatorUserId.
@CRamsan
CRamsan force-pushed the cr/ds-prop-010-atomic-create-property branch from d8697ea to e9f4681 Compare July 27, 2026 07:22
@CRamsan
CRamsan changed the base branch from cr/ds-x-009-fk-cascade-sweep to main July 27, 2026 07:24
@CRamsan
CRamsan merged commit dd33db2 into main Jul 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant