Each dispatched poll is a durable job with two job log streams, so an
unbounded poll history would grow the platform store by roughly two
thousand jobs a day per server. A new poll now retires older terminal jobs
of the same template together with their job log streams, leaving at most
two rows per template while nothing is in flight.
The SCUM 用户管理 list stayed empty because the typed scum_user and
scum_vehicle tables had no producer: the run ingest endpoint is signed-run
only, and the previously registered plugin templates asked for a Run
database capability the endpoint never advertises.
The plugin now declares bounded, read-only SQLite projections for players
and vehicles (sql/scum-db-v57/*.sql with query schemas), and the platform
dispatches those templates as durable remote.run.db.sqlite.query jobs on
run heartbeat and page open, then projects the returned rows into the typed
SCUM tables through the same shared ingest path used by signed run facts.
- Drop the live-map stat strip and the half-width detail column: the map board now spans the row, is taller, and the selected point renders as a compact strip under it.
- Fit the map filters into a single row with small layer chips, and switch the board between terrain, topo and night base layers plus the extracted building-zone overlay.
- Add a searchable SCUM catalog picker with icons for gift items and event produces, show gift item and vehicle icons in the lists, and keep the picker grid closed until it is opened so no icon is requested up front.
- Resolve the 2604 extracted icons through a generated static asset URL lookup instead of an eager import.meta.glob, so opening a plugin page no longer pulls every icon as its own dev-server module.
- Keep the icon URLs cacheable per rendered element and add a test that the catalog never regains the module glob and that every declared icon file ships.
- Import 2492 entity records (2391 items, 54 vehicles, 25 zombies, 12 animals, 10 armed NPCs) with spawn commands and icon names from the SCUM Admin Helper 0.4.0.5 payload.
- Ship the 2604 extracted item/NPC icons plus 4096 terrain, topo, night and building-zone map layers.
- Resolve vehicle icons through the catalog so live-map and trajectory markers cover every known vehicle class.
- Point map geometry and the live map background at the 4096 terrain layer.
The delete confirmation adds a password field. Browsers and password managers
paired it with the only other text field on the page and filled the account
name into the server search box on the server list.
The search input now stays out of the DOM while a delete confirmation is open,
and the toolbar shows a suspended notice styled to match the field it replaces
so the row does not jump. A jsdom test drives the real action menu and dialog
instead of asserting page source strings.
Run pushes typed SCUM facts through POST /api/v1/run/scum/facts, but the
production router rejected that path before the signature middleware because
runServiceRequest listed individual Run channel prefixes, and MySQL kept SCUM
rows inside the whole metadata snapshot instead of platform tables.
- /api/v1/run/ is now the signed machine channel space while
/api/v1/run/endpoints keeps normal bearer/admin authorization.
- MySQL gets real scum_user, scum_user_trajectory, scum_vehicle,
scum_vehicle_trajectory and scum_vehicle_lock tables with parameterized
per-row repositories instead of full snapshot rewrites. Snapshot-shaped
tables from the unreleased interim build are replaced, and SCUM rows still
inside a metadata snapshot are migrated once.
- Facts ingest verifies the target server plugin type and converges stale
online users to offline after SCUMUserOfflineAfter.
- The plugin page and browser read one bounded /scum/surface response instead
of five list calls per refresh.
Call-count budget for one server: per 5s facts batch, one SELECT plus one
INSERT/UPDATE per reported user and vehicle, one INSERT per moved trajectory
sample or new lock row, one bounded stale-user SELECT, and a trajectory
retention DELETE at most once per hour. One browser refresh issues one surface
request every 15s instead of five list requests.