Implement SCUM direct data plane
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-08-13
|
||||
@@ -0,0 +1,57 @@
|
||||
## Context
|
||||
|
||||
SCUM database schema, log grammar, and configuration files change with the game. The present Platform implementation identifies SCUM row types from query-key substrings and shapes data into fixed projection structs. That puts version-specific knowledge in the wrong component and forces a Platform update for routine game changes.
|
||||
|
||||
The supplied SCUM v57 sample confirms the required real sources: SQLite tables (`user_profile`, `prisoner`, `squad`, `squad_member`, `vehicle_spawner`, `base`, timed gifts/tasks), UTF-16LE server logs, and INI/JSON configuration. Platform needs durable, queryable `scum_*` records; Run remains an independent generic executor and is not changed in this repository.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Package SCUM v57 SQL, log grammar, and configuration mappings with the SCUM plugin.
|
||||
- Make manifest validation accept safe package-relative SQL references and declarative row destinations while rejecting browser-provided or inline SQL.
|
||||
- Make Platform ingest typed result rows through declaration metadata and upsert relational `scum_*` tables without SCUM query-name dispatch.
|
||||
- Provide users, squads, activity, gifts, and map data to the management console from those persisted tables.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- Adding a `run/` tree, implementing Run-side executors, or adding SCUM game details to Run.
|
||||
- Parsing a SCUM database from the browser or exposing host paths/raw SQL to browser users.
|
||||
- Supporting every historical SCUM database version in the initial pack, changing lifecycle management, or adding unrelated product areas.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Plugin package owns version-specific declarations
|
||||
|
||||
Each SCUM query template declares a package-relative `sqlRef`, `targetTable`, `upsertKeys`, and optional column mapping. SQL source is a `.sql` package asset named for SCUM database version. Logs/configuration use package assets with explicit encoding/format metadata.
|
||||
|
||||
This gives a SCUM version update one editable location: the plugin package. Inline SQL remains invalid so the browser continues to request only named templates and typed parameters. Storing SQL in Platform would reproduce the current coupling; accepting arbitrary browser SQL would make the contract unauditable.
|
||||
|
||||
### Platform performs generic declaration-driven ingestion
|
||||
|
||||
The execution path resolves a registered plugin declaration, validates the reported columns/keys, and applies its rows to the named `scum_*` relation. The generic layer never infers destination type by matching `player`, `squad`, or other SCUM words in a query key.
|
||||
|
||||
Tables are deliberately shaped for the first console features: sync runs, users, squads, squad members, vehicles, flags, map points, activity events, gift catalogs/grants, and configuration files. A generic JSON payload retains plugin-version fields not promoted to columns, avoiding a Platform release for every added SCUM field.
|
||||
|
||||
### APIs and console read persisted projections only
|
||||
|
||||
Platform dataset endpoints list scoped persisted rows. The console renders the five requested real datasets and uses empty states until a sync exists; it does not invent demo state or query SQLite directly.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [SCUM schema drift invalidates a SQL asset] -> Version the asset directory, identify its schema version in the plugin manifest, and return a typed sync error rather than corrupting a table.
|
||||
- [A mapping declares an unexpected relation] -> Manifest validation limits targets to `scum_*`, validates relative asset paths, key names, and declared columns before plugin registration.
|
||||
- [Initial normalized tables omit a future game field] -> Preserve unmapped source values in row payload JSON and add columns only when they become a first-class console field.
|
||||
- [Existing fixed projections have callers] -> Retain compatibility responses while migrating callers, then remove string-key dispatch in the same change after tests cover declaration-driven ingestion.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Register the new manifest schema and v57 package assets alongside existing declarations.
|
||||
2. Add relational `scum_*` repository models/migrations and generic ingest APIs.
|
||||
3. Switch SCUM sync result handling and console APIs to the declarations.
|
||||
4. Verify against fixture rows derived from the supplied SCUM v57 database/log/config corpus.
|
||||
5. Roll back by deploying the previous Platform and plugin version; existing `scum_*` rows are additive and can be ignored by the old runtime.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- The first pack uses `pragma user_version = 57`; future versions will be added as plugin package assets when their actual schema is supplied.
|
||||
@@ -0,0 +1,29 @@
|
||||
## Why
|
||||
|
||||
The current SCUM integration keeps game-version SQL and data-shaping knowledge in Platform projections, which makes a SCUM update require coordinated changes across components. The management console needs to operate on actual SCUM v57 users, squads, activity, gifts, and map data with game-specific knowledge packaged alongside the SCUM plugin.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add a plugin-packaged SCUM data plane: versioned SQL files, log parser definitions, and configuration mappings referenced from the plugin manifest.
|
||||
- Let Platform validate and distribute those declarations, accept typed result rows, and persist them in relational `scum_*` tables without dispatching on SCUM query-name substrings.
|
||||
- Expose persisted SCUM user, squad, activity, gift, and map datasets through Platform APIs and the first-party game operations console.
|
||||
- Replace the old hard-coded SCUM projection pathway with declaration-driven target-table and upsert metadata.
|
||||
- **BREAKING** Plugin query-template declarations gain package-relative SQL references and row-target metadata; inline SQL remains invalid.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `scum-direct-data-plane`: Plugin-owned versioned SCUM data declarations, generic Platform ingestion, and `scum_*` persistence.
|
||||
- `scum-operations-console`: First-party views and APIs for persisted SCUM users, squads, activity, gifts, and map points.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
<!-- None. -->
|
||||
|
||||
## Impact
|
||||
|
||||
- `plugins/`: SCUM manifest/schema/validator/tests and versioned SQL, log, and config packages.
|
||||
- `platform/`: plugin contracts, generic ingest service, relational repository models/migrations, and SCUM dataset APIs.
|
||||
- `platform_web/`: server management SCUM data views using existing themed console conventions.
|
||||
- No `run/` source is added; Run continues to perform only generic plugin-declared SQL and file jobs supplied by Platform.
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Plugin-declared SCUM data packs
|
||||
The system SHALL allow a SCUM plugin manifest to reference package-relative versioned SQL, log parser, and configuration mapping assets. Every query declaration that produces persisted SCUM rows MUST declare a `scum_*` target table and non-empty upsert keys; inline SQL and browser-supplied SQL MUST be rejected.
|
||||
|
||||
#### Scenario: v57 query declaration resolves a packaged statement
|
||||
- **WHEN** the SCUM v57 plugin package declares a query with a relative `.sql` reference and row-target metadata
|
||||
- **THEN** manifest validation accepts the declaration and distribution includes the referenced asset
|
||||
|
||||
#### Scenario: inline statement is rejected
|
||||
- **WHEN** a manifest contains SQL text instead of a package-relative SQL reference
|
||||
- **THEN** manifest validation rejects the manifest with a declaration error
|
||||
|
||||
### Requirement: Generic SCUM row ingestion
|
||||
The system SHALL ingest rows returned for a registered SCUM data template according to that template's declared target table, upsert keys, and column mappings, without routing by a query-key substring.
|
||||
|
||||
#### Scenario: user rows are ingested
|
||||
- **WHEN** a registered user template returns rows containing its declared key and columns
|
||||
- **THEN** Platform upserts those rows into `scum_users` and records their plugin payload
|
||||
|
||||
#### Scenario: unsupported row target is rejected
|
||||
- **WHEN** a registered data template names a target outside the allowed `scum_*` tables
|
||||
- **THEN** Platform rejects the result before any dataset row is written
|
||||
|
||||
### Requirement: SCUM v57 source coverage
|
||||
The initial SCUM pack SHALL include data declarations for users, squads and members, activity, gifts, and map points, plus parser/mapping declarations for supplied SCUM logs and configuration formats.
|
||||
|
||||
#### Scenario: operators inspect supplied source families
|
||||
- **WHEN** the SCUM plugin package is assembled for database version 57
|
||||
- **THEN** it contains SQL assets and declarations for all five console datasets and log/config parser assets
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Persisted SCUM operations datasets
|
||||
The system SHALL expose persisted SCUM users, squads, activity events, gifts, and map points through Platform APIs scoped to a server instance.
|
||||
|
||||
#### Scenario: a completed sync is queried
|
||||
- **WHEN** an operator requests a SCUM dataset for an instance with persisted records
|
||||
- **THEN** Platform returns only the corresponding persisted `scum_*` rows for that instance
|
||||
|
||||
### Requirement: SCUM operations console views
|
||||
The first-party management console SHALL provide themed views for 用户, 队伍, 活动, 礼包, and 地图 using Platform's persisted SCUM dataset APIs, with an explicit empty state when no sync has completed.
|
||||
|
||||
#### Scenario: data is available
|
||||
- **WHEN** an operator opens a SCUM-enabled server after a data sync
|
||||
- **THEN** the console displays the returned persisted dataset without browser-side SQLite or log access
|
||||
|
||||
#### Scenario: no data is available
|
||||
- **WHEN** an operator opens a SCUM-enabled server with no completed data sync
|
||||
- **THEN** each dataset view displays an empty state rather than synthetic records
|
||||
@@ -0,0 +1,20 @@
|
||||
## 1. Plugin Data Pack
|
||||
|
||||
- [x] 1.1 Extend plugin manifest schema and validator with package-relative SQL references and declared SCUM row targets, keys, and mappings.
|
||||
- [x] 1.2 Add tested SCUM v57 SQL assets for users, squads/members, activity, gifts, and map data.
|
||||
- [x] 1.3 Add plugin-declared UTF-16LE log parser and INI/JSON configuration mapping assets for the supplied SCUM formats.
|
||||
|
||||
## 2. Platform Data Plane
|
||||
|
||||
- [x] 2.1 Replace SCUM query-key projection dispatch with declaration-driven row ingestion contracts and tests.
|
||||
- [x] 2.2 Add scoped relational `scum_*` repository models/migrations and generic upsert/list operations for the first five datasets.
|
||||
- [x] 2.3 Expose server-instance APIs for persisted users, squads, activity, gifts, and map points.
|
||||
|
||||
## 3. Operations Console
|
||||
|
||||
- [x] 3.1 Add themed server-management views and API clients for the five persisted SCUM datasets with real empty states.
|
||||
|
||||
## 4. Verification and Delivery
|
||||
|
||||
- [x] 4.1 Run manifest, Platform, frontend, OpenSpec strict, and structure checks; record evidence.
|
||||
- [ ] 4.2 Stage only this change, commit on `main`, and push the configured remote.
|
||||
Reference in New Issue
Block a user