Public: anyone can read this; the crew can change it.
The rule closes the proposal: the decision lands once, in the transaction that cast the ballot #57
Sign in to join this conversation.
Public: anyone can read this; the crew can change it.
The second half of #5, which is cut down to recording a ballot. With ballots in the table and
tallyreading them, this is the moment the app is named for: the rule is met and the proposal is decided, exactly once, by nobody pressing anything.What done looks like
decided_attoproposal(if #5 did not already need it) and nothing else.tallysays decided — its state becomesdecided,decided_option_idis the winner anddecided_atis stamped.UPDATE proposal SET … WHERE id = ?1 AND state = 'open', and the decision is announced only if that statement changed a row. Two ballots arriving at once decide the proposal once and emit onedecision.made; a test drives two votes through the action against one database and asserts a single event.decision.madecarries the proposal, the winning option and the tally that decided it — enough for #7 to sign and send without reading anything back.vote.cast. Both events cross processes through theeventtable, as everything else does.voteanswersinvalidwith a sentence naming the state, and the existing ballots stay exactly as they are — the record of how it was decided.decided, andREADME.mdsays that in one sentence, with the reason.src/actions.test.ts: the majority threshold landing;alllanding only when every member has voted and agreed; anamed:rule landing on its own names while other ballots pile up unused; a tie deciding nothing however many ballots arrive; the single-decision.maderace; a vote after the decision refused; the winner anddecided_atunchanged by anything that happens afterwards.bun testis green.Files I expect to change:
src/db.ts,src/actions.ts,src/actions.test.ts,README.md.Risks: this is the one irreversible write in the app, so the guard and the transaction are the entire issue — a re-tally outside the transaction that wrote the ballot is a decision that can fire twice, and the only symptom will be a webhook delivered twice weeks later. Do not add a page, a route, a tool or a terminal key here: #44 and #45 are the doors, and keeping them out is what makes this fit a run. Do not let a roster change reach into this path; that is #51's problem and it must reuse this code rather than copy it.
Fit: Ledger — the one transaction the whole app exists to get right. A person assigns; I do not.