# Admin CLI Operator tools for accounts on the shared `recflare` D1 database, exposed as an `admin` command group on the repo's `runx` CLI. Each command shells out to `wrangler d1 execute recflare` — no running worker or auth token needed. Run from anywhere in the repo: ```sh bun runx admin [options] ``` ## Commands ### `set-password` — set (or replace) an account's login password ```sh bun runx admin set-password --account 1 bun runx admin set-password --username alice --remote ``` The new password is taken from `--password `, else from piped stdin, else prompted interactively. ```sh # interactive (prompts, hidden) bun runx admin set-password --account 1 # non-interactive / scripted echo "s3cret-pw" | bun runx admin set-password --account 1 bun runx admin set-password --account 1 --password "s3cret-pw" ``` ### `clear-password` — remove an account's password Leaves the account with no login credential (only platform login). ```sh bun runx admin clear-password --username alice ``` ### `grant-developer` / `grant-moderator` — grant or revoke a role Both are off by default; only these commands set them. A granted role backs its `GET /role//:id` lookup **and** rides in the login token's `role` claim, so it takes effect on the account's next login or token refresh. ```sh bun runx admin grant-developer --account 1 bun runx admin grant-developer --account 1 --revoke bun runx admin grant-moderator --username alice --remote ``` ### `reload-plus` — credit every Plus subscriber's tokens Also exposed directly as `just reload-plus`. ```sh just reload-plus 1000 --dry-run # list subscribers and their balances, change nothing just reload-plus 1000 --remote # +1000 RecCenterTokens to each subscriber, production ``` Adds `` RecCenterTokens (currency type 2) to the `balance` row of every account whose `hasPlus` flag is set — the flag `grant-plus` and the website's Discord claim write. Subscribers are found through the indexed `has_plus` column on `account` (auth migration 0009), so the reload is one statement however many accounts there are. Nothing schedules it: run it when the subscription's tokens are due, and note that running it twice credits twice. A subscriber who has never loaded the game has no balance row yet. They get one holding their signup grant **plus** the reload, so the grant is not lost — the grant amount is `RECFLARE_STARTING_TOKENS` from the environment or `.env`, falling back to econ's default of 10000. Prints every credited account with its resulting balance. This command targets the `balance` table, so it runs under `apps/econ`'s wrangler config; with `--local` that is econ's dev D1 state, which needs both `balance` and a migrated `account` table in it. ### `cai-load` — load the first-party custom avatar items ```sh bun runx admin cai-load # apps/econ/static/db/2025-1-cai.json → local bun runx admin cai-load --remote bun runx admin cai-load --file path/to/export.json --dry-run just cai-load --remote # the same, as a recipe ``` Loads an export of `CustomAvatarItem` records (a JSON array, a `{ Results }` page, or one record) into the `custom_avatar_item` table, each stored as the row's JSON with its `CreatorAccountId` forced to 1, the Coach account, whatever the export said: that is what files it as stock content (the storefront tab searches by creator) and what a purchase pays. Each save's `ThumbnailFileName` is put under `avatar/`, where this server serves those images from (a name already prefixed is left alone). It MERGES: an id already in the table has its row replaced, and nothing is deleted, so the players' own shirts, which share the table, are untouched. Re-running is safe. The load is verified by counting rows and probing ids from across the export; it fails loudly rather than report a partial load. `--dry-run` reads and validates the export and prints the statement count without writing. The saves in an export name their assetbundles by bare filename; the load stores the names only. ### `lookup` — print an account ```sh bun runx admin lookup --account 1 bun runx admin lookup --username alice ``` Prints id, username, platform, platform id, created/last-login times, and whether the account has a password, the developer role, and the moderator role. ## Options ### Selecting an account Every command except `reload-plus` and `cai-load` targets exactly one account, by **either**: - `--account ` — numeric account id - `--username ` — username (case-insensitive) ### Choosing the database - `--local` — the local dev database (**the default**) - `--remote` — the deployed (production) database Passing both is an error. `--remote` requires `RECFLARE_D1` in the gitignored root `.env` (see `.env.example`) and a wrangler login with access to the account. ## Notes - Password hashing matches the auth worker exactly (PBKDF2-SHA256), so a password set here verifies at login. - A command that matches no account exits non-zero with `no account found for …`. - Local writes target `apps/auth`'s dev D1 state; run `bun turbo -F auth migrate -- --local` first if the local database hasn't been migrated yet.