Files
mono/components
coopops b67581ce80
Typecheck / desktop (pull_request) Failing after 22m0s
Typecheck / controller (pull_request) Successful in 13m37s
fix(extension): atomic jsonb config patch to stop onboarding flag lost-updates
extensions.config is a single jsonb blob shared by every flag/hash the L1
onboarding wizards (capital, chairman) write to. Every write site did the
classic read-modify-write: findByName() the whole row, spread+mutate one key
in app memory, then update() the whole config back. Two DecisionTrackedEvent
handlers firing concurrently (two council decisions tracked near-simultaneously)
each read the same stale snapshot and each write their own flag back — whichever
write lands last wins and silently reverts the other one's flag to its old value.
Symptom hit live: onboarding_generator_program_template_done reverted to false
(with its hash still present, proving the decision really was tracked) after
onboarding_generation_contract_template_done raced it to true.

Added ExtensionDomainRepository.patchConfig(name, patch), implemented as a single
`UPDATE extensions SET config = config || patch::jsonb ... RETURNING *` — no
app-side read before the write, Postgres serializes concurrent UPDATEs on the
row so two different-key patches can no longer clobber each other. Replaced
every config read-modify-write in capital's and chairman's onboarding services
(the events handler's flag write, loadPlugin's init/expire timestamps, the
hash writes in completeStep/completeGeneralMeet, saveProgramDocDataHash) with
this atomic patch. update() is untouched for other callers.

Live data recovered manually: onboarding_generator_program_template_done was
patched back to true for voskhod/capital (hash was already present, confirming
the decision had in fact been tracked before the race reverted the flag).
2026-07-19 07:56:00 +00:00
..
2026-06-24 22:04:51 +05:00
2026-06-24 22:04:51 +05:00
2026-06-24 22:04:51 +05:00
2026-06-24 22:04:51 +05:00
2026-06-24 22:04:51 +05:00
2026-06-24 22:04:51 +05:00
2026-06-24 22:04:51 +05:00
2026-06-24 22:04:51 +05:00
2026-06-24 22:04:51 +05:00
2026-06-24 22:04:51 +05:00
2026-07-14 22:31:19 +03:00
2026-06-24 22:04:51 +05:00