Design and build cash history foundation
Production portal delivery is implemented and locally verified on feature/portal-cash-investigations in /home/mathias/Projects/engines, committed as 6d30922e7 (design prototype) and 8722e1f01 (production investigations), pushed with its upstream established. The working tree is clean. /Admin/Cash/{tag} reuses the existing portal shell, shared investigation partials/CSS and fresh staff-role policy. It provides bounded per-server history/search/participant and evidence drilldowns, live balance observations, full-scope SQL kind/reason aggregates, depth-first bounded chronological transfer paths, existing trade links and page/record JSON exports. No new migrations or gameplay behavior changes; existing migration 0079-CashHistory.sql and SELECT grants are prerequisites. Best-effort coverage, unknown context, currency separation, Other exclusions and fungible-money limitations remain explicit. Validation: portal and full unit-test project compile; existing test-project warnings remain. 85 targeted cash-history, trade-page/access and portal-navigation tests pass against disposable SQL, zero skips. Coverage includes server isolation, fresh/expired/wrong-client roles, filters/paging, SQL aggregates beyond one page and Int64 totals, actual summary drilldown links, bounded path branches/returns/custody, truncation and traversal ordering, encoded context and no-store scoped JSON exports, and unavailable rather than zero states. A new regression reproduced the kind/reason drilldown bug red before its fix. Five standalone prototype Node tests pass. Chrome verified real Razor desktop/tablet/phone workflows; the follow-button overflow was fixed and visually rechecked. Final direct Playwright checks and opened screenshots verify parent-child branch grouping, no duplicate IDs and page width equal to viewport width at 1440/768/390. Two static reviews were bounded/partial; both verified findings were fixed, and the focused follow-up reported no remaining verified findings, not whole-patch approval. Full suite, production queries/deployment and native browser Back were not run. One unidentified initial resource 404 remains an explicit browser limitation. Local fictional Razor preview is intentionally left running at http://127.0.0.1:8891/preview/sign-in via temporary host /tmp/prk-cash-razor-preview and disposable containers prk-cash-razor/prk-cash-sql on prk-cash-validation. Synthetic login exists only in that temporary host, never production source. Screenshots and DOM measurements are under /tmp/prk-cash-production-screens. No production change performed. This pass builds the shared data foundation: one cash-history model/table and SQL migration, recording service, bounded background batch writer, bounded character/account reads, DI/lifecycle integration and tests. Gameplay producer hooks are implemented and pushed in commit dbeee1024 to draft PR #2798; the live portal connection is now the resumed scope. The new design-taste app-screen mockup in PRK.PlayerPortal/prototypes/cash-investigations was accepted as sufficient by the user. Production implementation is now authorized: reuse the existing portal shell, role-aware tools navigation and shared investigation Razor/CSS, rather than the prototype's standalone visual design. Implement bounded per-server cash history, SQL-backed reason aggregates, participant/evidence drill-down, bounded chronological follow-money paths and safe exports. Validate authorization/server isolation, filters/paging, aggregate truthfulness, trace limits, encoding and HTTP/UI behavior. Prototype Chrome acceptance was cancelled; do not claim it passed. Preserve the original prototype for comparison. New designs must match the deployed best-effort event model: no invented balance checkpoints, verified supply totals, completeness guarantees or exact credit attribution. Cover Cash history, Faucets/Sinks and Follow money, participant drill-down and existing evidence links. Coverage is bounded by the documented application paths and best-effort persistence, not arbitrary database writes. Foundation implemented in /home/mathias/Projects/worktrees/engines-cash-tracing (feature/admin-cash-tracing), committed as 389976108 (foundation) and 48d118608 (prototype). AOEmu.Data/CashHistory contains immutable event/party/context models, typed faucet/sink/transfer reasons, non-mutating recording service, bounded batched writer, one-table EF context, per-currency bounded character/account/reference reader and integration notes. Game migration 0079 creates cash_history. PFE registers the service and drains on shutdown. Gameplay, GM, creation/clone and market producers are connected in commit dbeee1024; no production database was migrated. Prototype notes now describe this simpler implementation rather than balanced-entry accounting. Validation: data project builds; full unit-test project and referenced engines compile in a local SDK/native-toolchain container. 435 targeted .NET tests pass with zero skips across cash history, trade windows, market/work-order/recovery flows, NPC trade matching, generic Set spells, GM access, cloning and atomic persistence. The separate WebAPI project also builds successfully. SQL tests ran against an isolated disposable SQL Server and applied the real migration twice, checked filters/paging/currency separation, malformed-batch rollback and service-to-queue-to-SQL integration. Five prototype Node tests also pass. Disposable SQL container/network and generated untracked build artifacts were cleaned up. Existing repository compiler warnings remain; full test suite and live gameplay were not run. Agreed direction: pragmatic cash-history collection, not a deep ledger or cash-persistence redesign. A shared service/system is welcome; gameplay call sites must not contain raw SQL. Centralize cash-history creation and persistence behind an abstraction, reuse existing trade/market mechanics and identifiers, and use one append-only event model with enough participant, amount, reason, balance and context data for GM investigation. Keep faucets/sinks distinct from player/GMI transfers. Discuss whether the service also wraps simple cash mutations; do not force complex trade flows through a new transaction architecture. Durability is secondary: preserve existing character-save behavior; bounded background batching and explicit dropped-record/error visibility are acceptable. No requirement for atomic cash/history commits, balanced-entry accounting, an outbox, independent checkpoints or a new cross-service recovery protocol in this scope. Acceptance for eventual implementation: shared recording abstraction without per-call-site database code; coverage of agreed cash-changing paths; stable character/account/trade/market links; bounded history writes that do not block gameplay on audit failures; tests for recorded amounts/reasons/participants, failed operations and history writer behavior. Historical completeness and live-versus-saved balance limitations must be clear. GM-facing vocabulary follows the prototype: Cash history, Balance check, Follow money, Faucets and Sinks. Pull request: #2798 — https://git.project-rk.com/prk/engines/pulls/2798 (draft/WIP), feature/admin-cash-tracing → develop. Gameplay producer integration is implemented, verified, committed as dbeee1024 (feature: Record gameplay cash changes), and pushed to this draft PR. Its summary and testing sections now include the hooks and 435-test result. The worktree is clean. A player cash base-value observer catches unclassified writes, direct stat-block access, replacement and bulk loops; scoped attribution covers rewards, loot, mission rolls, save terminals, NPC payments, online/offline GM edits/reset, generic stat functions, creation and clones. Trades suppress tentative application/rollback and emit confirmed gross directions; post-payment effects remain visible. GMI hooks cover successful deduplicated PFE mutations, normal/reprice/recovery matches, refund metadata and work-order buyer-to-crafter ownership. Unknown source ownership remains unknown. Negative GM edits and copied negative starting balances are retained, with no fictional debit from the staff actor. Legacy portal/WebAPI clone paths are included. Actor character/account IDs, evidence IDs and available market tokens/listing/work-order IDs are retained in context. Coverage and exclusions are documented in AOEmu.Data/CashHistory/README.md. Team mission recipients are recorded individually; corpse cash currently pays the opener, with no separate team cash-split writer found. Temporary modifiers/overrides, hydration, NPC/unclaimed loot generation, retained balances on deletion, same-owner internal market reallocation and external/manual SQL are not recorded as gameplay cash payments. Five prototype Node tests pass again; source diff whitespace checks pass. Disposable SQL resources and generated untracked build artifacts were cleaned up. Live-client/production validation and the full test suite were not run. Live portal connection remains follow-up work. PR #2798 rebased cleanly onto origin/develop 78bd6621e and pushed with an explicit force-with-lease; new head 11cb46e97. Range-diff confirms all three patches are unchanged; diff whitespace validation passes. Static four-perspective review identified two gaps, now fixed locally: overflow/underflow observations with an unexpected direction are retained as Other with the original scoped reason and direction in a bounded context note, preserving actual balances and references; reason/kind validation is shared without weakening explicit recording validation. WebAPI cloning captures the source persistent ID before cloning and uses it for character_clone references. No additional implemented faucet/sink was identified by this bounded review. Deletion remains an intentional supply-scope exclusion; the inspected organization-bank handler has no implemented bank mutations. Initial host dotnet invocation produced no results. Follow-up validation used the local SDK/native-toolchain container and an isolated disposable SQL Server: 423 targeted tests passed with zero skips across cash history, trade windows, atomic trade persistence, market, GM access, Set spells and cloning. Red controls reproduced all eight overflow/underflow omissions and the wrong clone reference before their fixes. Regression tests cover bounded anomaly notes, retained balances/context, strict explicit reason validation, successful clone source/owner attribution, missing source and failed clone. The production WebAPI project builds with zero errors; existing compiler warnings remain. Diff whitespace checks pass. Disposable SQL container/network and generated untracked build directories were removed. Fixes committed as 997211ed6 (fix: Preserve anomalous cash history and clone source references) and pushed normally to feature/admin-cash-tracing. Existing PR #2798 (https://git.project-rk.com/prk/engines/pulls/2798) now has the title feature: Add cash history and investigation prototype, is marked ready, and uses capability-based Before/Now sections with live-portal and best-effort limitations explicit. Worktree is clean. Five prototype Node tests also passed again. Full suite and live gameplay remain unrun. Read-only Ergo post-deployment inspection on 2026-10-26 around 23:11 UTC confirmed both PFEs and MarketEngine run revision 2d93d84df and migration 0079-CashHistory.sql is applied. Four real credit events for Gareth (character 5068) were inspected: loot +53 and +23, shop sale +14742 and purchase -2472. All retain character/account IDs and appropriate corpse/trade references; recorded balances form a continuous chain from 105719070 to 105731416. No per-record balance-delta errors, missing character identities or Other classifications were found. Saved cash equals the final observed balance, and both shop references resolve to completed trade audits with matching amounts and currency. Startup-to-inspection logs from both PFEs and MarketEngine showed no cash-history rejection/drop/write errors. This validates only the observed loot/shop paths; no player trade, GMI, GM edit, mission reward or clone events were present. No database or deployment changes were made. Portal pull request: #2947 — https://git.project-rk.com/prk/engines/pulls/2947 — feature: Add portal cash history investigations. Open, non-draft, feature/portal-cash-investigations → develop in prk/engines. Complete comparison contains only the two session commits; Git merge-tree and Gitea report no conflicts with current develop. Five prototype Node tests passed again; the previous successful 85-test SQL/HTTP run and desktop/tablet/phone browser validation remain applicable (only bundled-license trailing whitespace changed during PR preparation). Full suite and production deployment remain unrun.
Checklist
4 of 4 complete- Agree a shared cash-history service, event fields, reason taxonomy and initial coverage without redesigning cash persistence.
- Implement and verify the shared data model, recording abstraction, bounded batch writer, bounded reader, SQL migration and PFE service lifecycle.
- Verify recorded amounts, participants, reasons and links; failed-operation handling and writer failures; connect history to the portal with coverage limitations.
- Wire gameplay, trade and GMI cash-changing paths through the shared recording service; record and verify actual coverage.
- Area
- Project Rubi-Ka
- Project
- engines
- Kind
- Feature
- Task ID
tsk_8u7nzknbw3- Updated