Skip to content

0.3.5

Choose a tag to compare

@Sparks-code1 Sparks-code1 released this 04 Sep 03:07
· 50 commits to main since this release
The delete refuses, says so, and is no longer offered.

An RLS-refused DELETE is not an error: it matches no rows and returns success.
deleteCampaign checked only `error`, so the picker's ✕ opened a confirmation,
took the press, refreshed the list, and left the campaign sitting there — a
control that appeared to do the one irreversible thing in the app and did
nothing at all.

BOTH HALVES. deleteCampaign counts what it removed and raises on zero, so the
API tells the truth to whatever calls it. And the ✕ is gone: with no DELETE
policy nobody is entitled, not even the campaign's owner, so there is nobody to
offer it to. The confirmation row, the busy state and the handler went with it
rather than being left behind implying a feature that no longer exists.

deleteCampaign is kept, uncalled, because the refusal it now reports is the
useful part — if a policy is ever added, or a script or admin path wants it, it
behaves correctly instead of lying. Its doc says so.

The RLS check gained the assertion behind all of it: a refused delete is silent
but countable — no error, count zero — which is the exact shape the fixed
deleteCampaign reads. Three sabotages on the client pins, all red: dropping the
count option, dropping the raise, and putting a delete call back in the picker.

The migration records the decision where the two options were written down,
and its breakage list no longer warns about a button that is gone.

110 suites, 23 browser tests, 12 RLS checks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>