DEV Community

desgh white
desgh white

Posted on

Modeling Self-Exclusion as an Explicit State Machine

Some product rules are too important to live as scattered if checks. Account restrictions — cooling-off, self-exclusion, reactivation — are one of them: get the transitions wrong and you either trap a user or fail to honor a limit they set. A finite state machine makes the rules auditable.

Enumerate states and legal transitions

from enum import Enum

class State(Enum):
    ACTIVE = "active"
    COOLING_OFF = "cooling_off"     # short, timed, auto-reverts
    EXCLUDED = "excluded"           # long, cannot self-reverse
    CLOSED = "closed"

TRANSITIONS = {
    State.ACTIVE:      {State.COOLING_OFF, State.EXCLUDED, State.CLOSED},
    State.COOLING_OFF: {State.ACTIVE},          # only after the timer
    State.EXCLUDED:    {State.CLOSED},          # no path back to ACTIVE
    State.CLOSED:      set(),
}

def transition(current, target, *, timer_elapsed=False):
    if target not in TRANSITIONS[current]:
        raise ValueError(f"illegal {current}->{target}")
    if current is State.COOLING_OFF and not timer_elapsed:
        raise ValueError("cooling-off still active")
    return target
Enter fullscreen mode Exit fullscreen mode

The value is in the transitions you forbid

Making EXCLUDED -> ACTIVE unreachable in code means no endpoint, feature flag, or support tool can accidentally re-enable a self-excluded account. The illegal transition throws instead of silently succeeding. That's a guarantee a pile of booleans can't give you.

Log every transition

Persist an append-only history of (from, to, actor, reason, ts). When someone asks "why is this account restricted," the answer is a query, not an archaeology dig — and it's the record you'll want during an audit.

Reference

Responsible-play controls are a good real-world example because the transitions are legally load-bearing. Seeing how a site like here presents its deposit-limit and self-exclusion options maps neatly onto states a user can enter freely but not always exit on demand.

Takeaway

Name the states, whitelist the legal transitions, make the dangerous ones unrepresentable, and log the rest. The state machine turns a safety-critical rule from hopeful if-checks into something you can prove.

Top comments (0)