feat(admin): manual account blocking (suspensions)
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 12s
CI / ui (pull_request) Successful in 45s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m10s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 12s
CI / ui (pull_request) Successful in 45s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m10s
Operator-driven hard block, the counterpart to the soft high-rate flag: permanent or until a date, with an optional reason chosen from an editable en+ru picklist (snapshotted onto the block). A block forfeits the player's active games (opponent wins, as a resignation) and cancels their open matchmaking games. A backend gate refuses a blocked account on every /api/v1/user/* route except the block-status probe with 403 account_blocked, which threads through the gateway as the Execute result_code; the UI surfaces it as a terminal blocked screen and stops all push/poll. Temporary blocks self-expire; the operator can unblock at any time (lost games stay lost). Sessions are not revoked, so the blocked client can still reach the exempt block-status endpoint. Backend: migration 00003 (account_suspensions + suspension_reasons) + jet regen; account suspension store; game.ForfeitAllForAccount; requireNotSuspended gate + block-status endpoint; admin console block/unblock + Reasons CRUD. Wire: fbs BlockStatus + account.block_status gateway op. UI: blocked screen, app state, transport/codec, i18n. Docs: ARCHITECTURE, FUNCTIONAL(+ru), PRERELEASE (AB).
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
{{define "content" -}}
|
||||
<h1>Suspension reasons</h1>
|
||||
{{with .Data}}
|
||||
<p class="note">Reasons offered when blocking a user; each is shown to the blocked player in their own language. Editing or deleting a reason does not change a reason already shown to a currently-blocked player (blocks snapshot the text).</p>
|
||||
<section class="panel"><h2>Add reason</h2>
|
||||
<form class="form col" method="post" action="/_gm/reasons">
|
||||
<label>English <input type="text" name="text_en" required></label>
|
||||
<label>Russian <input type="text" name="text_ru" required></label>
|
||||
<div><button type="submit">Add</button></div>
|
||||
</form>
|
||||
</section>
|
||||
<section class="panel"><h2>Existing reasons</h2>
|
||||
{{range .Items}}
|
||||
<div class="row">
|
||||
<form class="form" method="post" action="/_gm/reasons/{{.ID}}/update">
|
||||
<input type="text" name="text_en" value="{{.TextEn}}" aria-label="English" required>
|
||||
<input type="text" name="text_ru" value="{{.TextRu}}" aria-label="Russian" required>
|
||||
<button type="submit">Save</button>
|
||||
</form>
|
||||
<form class="form" method="post" action="/_gm/reasons/{{.ID}}/delete">
|
||||
<button type="submit">Delete</button>
|
||||
</form>
|
||||
</div>
|
||||
{{else}}<p class="note">no reasons yet</p>{{end}}
|
||||
</section>
|
||||
{{end}}
|
||||
{{- end}}
|
||||
Reference in New Issue
Block a user