Files
capod/app/src/foss
darken 26633b940d fix(upgrade): Make the FOSS supporter persist create-only-if-absent
persistUpgrade() wrote an unconditional record, so any sponsor return that
got past the ViewModel's isPro guard replaced an existing supporter's
upgradedAt - the "supporter since" date the status screen shows - and, for
the legacy records every existing supporter has, their stored reason too.
That guard reads a shareIn replay and can be stale, so it is not a race-free
answer on its own.

The write now happens inside the store transaction: an existing record is
kept and reported back, only an absent one is created. The ViewModel thanks
the user only for an actual unlock and stays quiet otherwise. It also no
longer eats the sponsor visit when something fails - a failed entitlement
read or a failed write restores the pending-launch marker so the next return
can retry, while the error still travels the normal path.

FossCache gains the same constructor test seam BillingCache has, so the
transaction can be exercised against a real DataStore on a temp file.
2026-08-03 08:30:33 +02:00
..