XP ledger v2 upgrade and migration
McProgression 2.0 adds an audit ledger without changing where player balances are stored. Skill XP and General XP remain in the existing progress.yml or prefixed SQL state table. The ledger is additive: YAML stores it under xp-ledger.events; SQL creates <table-prefix>xp_ledger and <table-prefix>schema_migrations beside the existing state table. SQL uses one indexed table keyed by player UUID instead of creating a separate table per player, so new players do not require schema changes and an operator can query a player's history directly.
What the upgrade does
- Creates the ledger and migration-marker tables when SQL storage starts. It does not rewrite or derive balances from ledger rows.
- Imports the retained legacy
xp-history.bucketsonce. A prior daily or monthly bucket becomes alegacy-bucketrecord with the original total and award count. It is not expanded into fabricated per-action events. - Uses stable IDs and a committed migration marker, so a restart or retry does not add those legacy buckets a second time.
- Records new XP events with the state snapshot in one SQL transaction. If that transaction fails, both state and ledger events stay queued for the next save attempt.
- Keeps individual event details for
xp-history.event-detail-days(default 90, minimum 30), then replaces closed months with monthly summaries. Summaries older thanmonthly-retention-months(default 13) expire. Existing aggregate history and reports remain available.
YAML mode retains the same balances and legacy aggregate buckets in progress.yml; ledger events and summaries are stored alongside them. There is no background rewrite of player balances.
Recommended SQL upgrade
- Stop the Paper server so there is only one writer.
- Back up the complete configured progression database,
progress.yml, and configuration. For SQLite, copy the database only after shutdown; include the-waland-shmfiles if present. Keep the backup until the upgraded server has been checked. - Install the 2.0.0 plugin on the server and start it with the same backend, JDBC URL, credentials, and table prefix. Do not clear the state table or migration markers.
- Check startup logs for successful database initialization, legacy history import (when applicable), and normal state loading. A schema or import error stops startup instead of silently creating a new balance store.
- Check a known player's balance with the usual player progression command, then inspect the audit ledger with
/mcpadmin xp ledger <player> 365 1(grantmcprogression.admin.xp.ledger). Legacy entries should be labeled as aggregates; events recorded after upgrade should appear individually. - Keep the backup until the balances and ledger view have been confirmed.
The command requires an online or previously known player name/UUID accepted by the admin command's lookup. It reports the retained window only; monthly retention is configurable. The audit permission defaults to false.
YAML and backend changes
For an existing YAML installation, stop the server, back up progress.yml, and upgrade with storage.backend: yaml unchanged. Its current XP balances remain untouched while the ledger is added to that file. Changing between YAML and SQL or between SQL backends is not an automatic migration feature: changing storage.backend alone does not copy data. There is no built-in cross-backend exporter in this release. Use a separately verified export/import that preserves every state key and the ledger/migration records, or remain on the current backend; do not delete the source until the destination has been checked. Timed-key data is stored separately and needs its own migration. Do not run multiple Paper servers against one progression database.
Rollback
The ledger tables/section are additive. To roll back the plugin JAR, stop the server and restore the complete pre-upgrade backup if you need the exact prior database/file state. Older plugin versions ignore the new ledger tables; they continue using the existing state table. If you leave the additive tables in place, the old plugin's normal XP writes continue in the state table, but those actions will not be present in the v2 ledger. Preserve schema_migrations when returning to v2 so legacy buckets are not re-imported.
Never delete or rebuild the state table as a ledger migration step. The ledger is an audit trail, not the source of truth for XP balances, and it cannot reconstruct the exact sequence of actions that predates v2.
Verification limits
The automated SQLite migration tests verify unchanged balances, idempotent legacy imports, transactional event persistence, and monthly rollups. MySQL and PostgreSQL use portable table/index DDL and database-specific idempotent inserts, but should be verified against the server's actual database engine and backup before upgrading a production store. No live server database is changed by building or testing the plugin.