Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [Unreleased]

### Changed

- **Each game system has its own bank.** A character's money now belongs to the game it was
earned in: starting a new campaign on another system opens fresh accounts, and switching
back finds the old money exactly where it was. On the first start after updating, every
player's current balance, debt and bonuses are copied into each system they have a
character in, so nothing looks different in any existing game. A full copy of the
database is saved beside it first (when the disk has room), and the old bank records are
kept untouched.

### Security

- **Players can no longer use the GM's tools.** A player's own login worked as a key to the GM's
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,8 @@ CITY_NET/
│ ├── bulk.js # Reads and deletes by id in pieces of 500, one transaction per delete so it still happens entirely or not at all. A map-sized city is more ids than SQLite takes in one statement
│ ├── updater.js # In-app self-update — paginated registry tag listing so a run of dev builds cannot hide a stable release; release channels selected by IMAGE_TAG alone, the same variable compose pulls with (X.Y.Z-dev tags with an optional counter, ordered so a release supersedes its own dev builds); preflight (compose file mounted, docker socket, compose project labels) so a stack that cannot update says why instead of hanging, and offers updating from the host as an equal option since running without the socket is a supported posture; one update at a time, refused rather than queued, with a stale-run release so a hung pull does not deaden the button; the helper command passed as argv rather than through `sh -c`, so a compose label containing a command substitution is data and not code; upgrade-only semver check; update log on the data volume; boot id so a restart is detectable without a version change; the registry read goes through net/outbound, and the docker probe behind GET /api/version is asked once per process rather than once per request — execSync holds the event loop, so a probe on an open route was a way to stall the server
│ ├── buildingTypes.js # What a building is for, which catalogues it sells, and which of those a shelf can actually show. Distinct from `classification`, which is the mesh a custom structure is drawn from - a ripperdoc and a noodle bar can share a shape
│ ├── bank/
│ │ └── accounts.js # Bank accounts, one per player per game system (`bank_accounts`): a character's money belongs to the game it was earned in. Every read and write goes through here and waits for the one-time move from the old per-player table to finish
│ ├── buildings/
│ │ ├── gmNotes.js # The GM's notes, in their own table rather than a column every player downloads. Kept through a single delete so undo brings them back; pruned on a map clear and replaced on a map load, the two places location ids are reused
│ │ ├── locationRows.js # Putting whole location rows back - a saved map loading, a delete being undone - with every column the table has, read from the table. The hand-kept lists it replaced had fallen behind and dropped building types, buy-back rates, AC and more
Expand Down Expand Up @@ -410,6 +412,8 @@ CITY_NET/
│ │ ├── definition.js # The system definition format (1: name, description, words, parts, lookups, derived) and its server-side checks. Fatal (cannot be stored: not an object, too large, not JSON) vs ordinary problems (saved in a draft, block publishing), all reported with where they are. Also the app's renamable terms and switchable parts, with wordFor / partOn
│ │ └── store.js # `custom_systems`: a draft the builder edits and the published copy a game runs. Ids are sys_ + hex, never a built-in id; publishing refuses a draft with problems; the running system cannot be deleted
│ ├── startup/
│ │ ├── backup.js # A whole copy of the database (VACUUM INTO, beside it) before a migration changes real data; skipped, and logged, when the disk lacks room
│ │ ├── bankAccounts.js # The one-time move from one bank per player (`player_banks`, kept untouched) to one per player per system: the database copied first, each balance copied into every system the player has a sheet in plus the running one, in one transaction, with a marker so it never runs twice
│ │ └── sanity_checks.js # In-memory DB checks on boot
│ ├── utils/
│ │ └── random.js # cryptoRng — uniform [0,1) from OS entropy (crypto.randomInt); default rng for every roll that decides an outcome
Expand Down Expand Up @@ -442,6 +446,7 @@ CITY_NET/
│ ├── signs.test.js # Sign API (GET / POST / PATCH / DELETE, auth, image-only, filter_intensity clamping, XSS)
│ ├── sheets.test.js # Sheet routes (system switch, admin access, portraits, derived fields, GET /own player self-fetch)
│ ├── system_builder_parity.test.js # CWN and Shadowrun as data against cwnRecompute and sr6Recompute over 3,000 seeded sheets each (blank, text, decimal, huge and stale values, broken JSON): same sheet, same changed fields, same order
│ ├── bank_accounts.test.js # Per-system accounts kept apart; the one-time move (every sheet's system plus the running one, the old table untouched, once only, all or nothing); the database copy and its disk-space check; switching systems in play; and db.js opening a 1.14.4-shaped database file in a child process
│ ├── system_builder_store.test.js # The definition checks (every problem at once, fatal vs ordinary, words and parts), and the routes: main admin only, drafts saved with problems but not published, the published copy untouched while the draft moves on, the running system not deletable
│ ├── system_builder_engine.test.js # The formula language (precedence, functions, 0 for NaN, and a list of script-shaped inputs it refuses), limits, and definitions: dependency order, lookups, conditions, rules, and every mistake reported at once
│ ├── npc_privacy.test.js # The map list and token card as anonymous, player and revoked-editor callers see them: no NPC sheet, no silhouetted face, even in the raw response text; the GM and a granted editor still get both
Expand Down
Loading
Loading