## ADDED Requirements ### Requirement: Generic Plugin Collection Storage Platform SHALL persist opaque plugin records scoped by plugin identifier, server instance identifier, collection name, and record key. #### Scenario: SCUM stores a user projection - **WHEN** the SCUM plugin writes key `7656119...` to its `scum_users` collection for an authorized server instance - **THEN** Platform stores the opaque record without interpreting SCUM fields - **AND** another plugin or server instance cannot read the record through the scoped API #### Scenario: Plugin updates a collection atomically - **WHEN** an authorized plugin page submits a transaction containing collection puts and deletes - **THEN** Platform validates the complete transaction before applying it - **AND** the repository exposes the resulting records as one collection change ### Requirement: Plugin-Owned SCUM Domain The SCUM plugin SHALL own its collection names, record schemas, gift behavior, map behavior, and version-specific data extraction assets. #### Scenario: SCUM version changes - **WHEN** a SCUM database or log format changes - **THEN** the SCUM plugin updates its versioned query/parser assets - **AND** Platform does not require a SCUM business-logic change ### Requirement: Machine Data Relay SCUM machine SQLite, configuration, and log operations SHALL remain plugin-declared and Platform-dispatched to Run. #### Scenario: Declared SQLite read - **WHEN** a SCUM page requests a declared data refresh - **THEN** Platform routes the declared operation through Run - **AND** neither the page nor Platform's generic collection API accepts a raw host path or arbitrary SQLite statement #### Scenario: Run reports declared query rows - **WHEN** Run completes a declared SQLite query with a structured `rows` result - **THEN** Platform uses only the plugin-declared collection, upsert keys, and column mappings to persist the rows - **AND** Platform does not branch on the game, query key, collection name, or row fields ### Requirement: Browser-Independent Automatic Collection Platform SHALL schedule plugin-declared collection queries from the authenticated Run work-poll path without requiring a browser, page load, or manual synchronization action. #### Scenario: Coordinate templates become due - **WHEN** Run polls for work at least three seconds after the latest matching player, vehicle, or map-position query - **THEN** Platform queues the due plugin-declared SQLite query before selecting work - **AND** a still-active matching query prevents duplicate queued work #### Scenario: Squad templates become due - **WHEN** Run polls for work at least thirty minutes after the latest matching squad or squad-member query - **THEN** Platform queues the due declared query - **AND** no page action or open browser is involved #### Scenario: Complete snapshot removes absent records - **WHEN** a replace-mode query succeeds with a complete row set - **THEN** Platform upserts the returned mapped rows and deletes prior records in that scoped collection whose keys are absent - **AND** an empty successful snapshot clears the collection ### Requirement: Plugin-Declared Login Presence Projection Platform SHALL apply ordered plugin-declared log projections to durable Run log batches and SHALL NOT hard-code SCUM or BattlEye parsing rules in service code. #### Scenario: New player completes the BattlEye login sequence - **WHEN** one supervised stdout stream reports a player name and slot and later reports the same slot's Steam ID within the declared line gap - **THEN** Platform creates the Steam-ID-keyed `scum_users` record immediately - **AND** records the login activity - **AND** queues exactly one plugin-declared global new-player announcement #### Scenario: Existing player reconnects inside ten minutes - **WHEN** the same Steam ID completes another login sequence within ten minutes of its stored login observation - **THEN** Platform treats the player as already online - **AND** queues no additional welcome announcement #### Scenario: Existing player returns after ten minutes - **WHEN** the same Steam ID completes a login sequence after the ten-minute window - **THEN** Platform updates the stored name and login observation - **AND** queues exactly one plugin-declared returning-player announcement #### Scenario: Database enrichment follows stdout identity - **WHEN** a later SQLite user query returns the same Steam ID with profile, economy, squad, or coordinate fields - **THEN** Platform merges those fields into the stdout-created record - **AND** does not create a second user keyed by profile ID or display name ### Requirement: Read-Only Collection Page Loading The SCUM plugin page SHALL read Platform records automatically and SHALL NOT expose a control that dispatches machine collection. #### Scenario: User opens a SCUM management page - **WHEN** any users, squads, activity, gifts, or map page is opened - **THEN** it reads only the relevant `scum_*` Platform collections and existing command/snapshot results - **AND** it periodically rereads Platform data for display freshness - **AND** it contains no `同步 SCUM.db`, projection refresh, audit, or sample-data action