Merge pull request 'docs(account): record step 3 (module hooks, kit re-pin) as built' (#394) from docs/account-deletion-modules into main
Reviewed-on: #394
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# module-uo — the tables it owns
|
||||
|
||||
The 27 tables `module-uo` creates and owns, and the reasoning behind their shapes. **26 `shard_*`
|
||||
The 33 tables `module-uo` creates and owns, and the reasoning behind their shapes. **32 `shard_*`
|
||||
plus `uo_link_config`**, all created by the idempotent `server/db/schema.sql` fragment core replays
|
||||
after its own schema on every boot, and all dropped by `server/db/purge.sql` when an operator purges
|
||||
the module's data.
|
||||
@@ -263,6 +263,36 @@ same way — `uo-static-3922-h33-<sha8>.png`. A key the shard has no art for wri
|
||||
an empty row would make it "held" and it would never be asked again, including after the operator
|
||||
patches in the graphic that was missing.
|
||||
|
||||
## shard_pending_unlinks — what an account deletion left linked on the shard (MODULE_API 1.20.0)
|
||||
|
||||
When a website account is deleted, core asks the module first (`api.onUserDeleting`,
|
||||
[`ACCOUNT_DELETION.md`](../../website/ACCOUNT_DELETION.md) §4.4). `shard_account_links` is only a
|
||||
mirror: the shard keeps the site user id on the game account and reports it as `webId` on every
|
||||
`mob.login`, so the module unlinks each game account on the shard, through the staff unlink's
|
||||
`DELETE /link/{account}` (actor `web:account-deletion`), before the users row goes. This table is
|
||||
what that unlink could not finish.
|
||||
|
||||
| Column | Meaning |
|
||||
|---|---|
|
||||
| `account` | PK, the game account |
|
||||
| `web_user_id` | the deleted user's id, which the shard may still report |
|
||||
| `state` | `pending` (the shard was away) or `refused` (a protected staff account, 403) |
|
||||
| `queued_at`, `attempts`, `last_attempt_at`, `last_error` | the retry's own record |
|
||||
|
||||
Four rules that are load-bearing:
|
||||
|
||||
- **Every linked account is written here BEFORE the first call to the shard**, and dropped when the
|
||||
shard answers 200 or 404 (404: nothing to clear). Core gives the hook 10 s and one sidecar call can
|
||||
take 12, so a hook core stops waiting for still leaves everything it had not finished queued.
|
||||
- **No foreign key, on purpose.** Every row outlives the user it names; that is the point of it.
|
||||
The mirror row in `shard_account_links` goes with the users cascade either way.
|
||||
- **`pending` is retried; `refused` never is.** The retry runs when the WebSocket opens (which is
|
||||
also the boot path, since boot never calls the shard) and on every live `server.hello`. A refused
|
||||
row waits for the shard's staff to clear the tag by hand; Admin → Shard lists both kinds as *Still
|
||||
linked on the shard*, from `GET /admin/uo-link/config`'s `pendingUnlinks`.
|
||||
- **A live `mob.login` on the account with no `webId`, or another one, clears the row**, whoever
|
||||
cleared the tag. A replayed login never does: one from before the link carries no `webId` either.
|
||||
|
||||
## shard_clilocs / shard_cliloc_meta — UO's localization table (Protocol 3.0)
|
||||
|
||||
Items on the wire carry a `LabelNumber`, not a name. The bridge has always sent it —
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Account deletion — a member deletes their own account, on the website and in the app
|
||||
|
||||
**Status:** plan of record, 2026-10-29, with every question answered (AD4-AD13). **§6 step 2
|
||||
(core) built 2026-10-29** as website `feature/account-deletion`, `MODULE_API` 1.20.0; steps 3-6 are
|
||||
next. Each phase in §6 stops for the org lead before the next one starts.
|
||||
(core) built 2026-10-29** and merged as website#232 (`7bd93b8`), `MODULE_API` 1.20.0. **Step 3
|
||||
(modules and kit) built 2026-10-30**; steps 4-6 are next. Each phase in §6 stops for the org lead before the next one starts.
|
||||
|
||||
**Why now.** Google Play's Data safety form asks whether the app lets people create an account, and
|
||||
an app that does must let them delete it, both **in the app** and at a **web address** given to Play
|
||||
@@ -333,6 +333,23 @@ Asked while building core (§6 step 2), the same day:
|
||||
3. **Module-Rust** (`edge`) and **Module-uo**: §4.4's hooks plus their core-ref pins, one PR
|
||||
each. Module-uo's PR adds `shard_pending_unlinks`, the retry, and the *still linked on the
|
||||
shard* list. **Integration Kit**: the re-pin and the paragraph, one PR.
|
||||
**Built 2026-10-30**, all three pinned to `7bd93b8` with `coreApi` `^1.20.0`:
|
||||
- **Module-Rust** (`edge`): `links.unlinkForDeletion`, as §4.4 says.
|
||||
- **Module-uo**: `utils/accountDeletion.js`. Beyond §4.4:
|
||||
- every account is queued *before* the first sidecar call, because one call can outlast the
|
||||
hook's 10 s;
|
||||
- the retry also runs on every live `server.hello` (the plugin reconnecting to a sidecar that
|
||||
stayed up);
|
||||
- a `pending` row clears on a live login without the `webId`, as a `refused` one does;
|
||||
- *still linked on the shard* is `pendingUnlinks` on `GET /admin/uo-link/config` and a section
|
||||
on Admin → Shard, so there is no new route.
|
||||
|
||||
The table is in [`modules/uo/SCHEMA.md`](../modules/uo/SCHEMA.md).
|
||||
- **Integration Kit**: chapter 2 also gained the demo's two unlisted refusals (multipart and
|
||||
`data:` URIs), which it had never taught.
|
||||
- **Checked:** each repo's tests, and both modules' frozen-manifest job reproduced against
|
||||
`7bd93b8`.
|
||||
- **Not walked:** the live deletions are step 6.
|
||||
4. **Android** (`edge`): §4.3. One PR.
|
||||
5. **runicgateway.com**: §4.5, plus `PLAY_DATA_SAFETY.md` regenerated. One PR.
|
||||
6. **A walk**, using a throwaway account on each surface:
|
||||
|
||||
Reference in New Issue
Block a user