mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 17:02:42 +00:00
mischief: gogobee learns to fill orders placed on Pete's web board
The game-side half of Mischief Makers M3. gogobee polls Pete for storefront orders and opens the contract itself — the money, the eligibility, the fight are all its own, exactly as a Matrix !mischief buy. - roster push now carries each buyer's advisory euro balance (keyed by localpart, a separate keyspace from the anonymous board token) and the live tier catalog, so the storefront renders gogobee's current prices and never hardcodes one - placeWebMischief: the fulfilment path, debit-first-then-refund so the money state is a pure function of the order guid. DebitIdem + an order_guid stamp on the contract make a retried claim neither double-charge nor double-open - resolveRosterToken recomputes the one-way board token per live player to name a mark; the buyer is @<username>:<homeserver> from Authentik's preferred_username - a 30s poll loop drives it; a lost verdict just leaves the order pending to re-run, so the loop is its own retry and needs no durable queue - euro.HasExternalTx lets the affordability gate tell a first attempt (no debt for a mischief buy, like Matrix) from a retry of one already paid order_guid column added to mischief_contracts (schema + idempotent ALTER).
This commit is contained in:
@@ -416,6 +416,21 @@ func (p *EuroPlugin) GetBalance(userID id.UserID) float64 {
|
||||
return balance
|
||||
}
|
||||
|
||||
// HasExternalTx reports whether a money move with this externalID has already
|
||||
// been applied. It lets a retrying web caller tell a first attempt from a replay:
|
||||
// on a first attempt the affordability gate must run, but on a retry of an order
|
||||
// already debited the gate must be skipped — the debit is a settled fact, and
|
||||
// re-reading the now-lower balance would wrongly bounce a hit the buyer paid for.
|
||||
func (p *EuroPlugin) HasExternalTx(externalID string) bool {
|
||||
if externalID == "" {
|
||||
return false
|
||||
}
|
||||
var one int
|
||||
err := db.Get().QueryRow(
|
||||
`SELECT 1 FROM euro_transactions WHERE external_id = ? LIMIT 1`, externalID).Scan(&one)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Idempotent money moves
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user