4d2b8b9be3
Implements the FIFA17 economy WRITER cluster on top of the landed Core
economy authority + host CoreEconomy client + identity/item-shaper infra.
Handlers are pub, unit-tested, and NOT yet routed: classify() and
ROUTE_AUTHORITY are untouched — the classifier barrier is a later single
coherent flip. No stubs; real Core-backed behavior; fail-closed on CoreError.
Pack generator (adapter fut/pack_content.rs):
generate_pack_contents(&PackDef, &mut impl Rng, &[GeneratedCandidate])
-> Vec<GeneratedCard>. Pure, seeded (deterministic), gold-tier split +
special_chance gate as documented OPENFUT PLACEHOLDER policy (Python
open_pack/_pack_body parity note inline). Fail-closed empty on empty pool.
Store/item writers (host economy_store.rs), matching oracle wire shapes:
- handle_store_buy PUT /store/transaction -> purchase_items (debit+mint N)
-> createPackResponse; cancel/unknown/owned_only -> 200 {}; insufficient
-> 461 {reason,credits}; CoreError -> 503.
- handle_pack_open POST /purchased -> owned_only consumes the unopened
entitlement (redeem_entitlement, consume-once); normal packs debit+mint.
- handle_quick_sell{_path,_body} DELETE .../item/<id> + POST /ut/delete/.../item
-> reverse-resolve wire->Core id (SquadWireResolver) -> sell_item ->
{items:[{id}],totalCredits}; not-owned skipped.
Production OwnedItemLookup = CoreItemLookup over CoreAccess.
Market (host market_store.rs / pile_store.rs / market.rs), synthetic-seller:
- MarketStore over sqlx SQLite (WAL-once + busy_timeout=5s + BEGIN IMMEDIATE
for writes, mirroring openfut-core::db). listings(active/reserved/sold/
cancelled), owner-checked cancel, CAS reserve/complete_sale/rollback.
Typed errors NotFound/Sold/Cancelled/WrongOwner/Conflict.
- PileStore: durable pile/location metadata keyed by Core item id.
- handle_market_{list,query,cancel,buy} + handle_move_items. Buy-now =
reserve (CAS) -> balance precheck (461) -> Core purchase_item (mint+debit)
-> complete_sale; any Core failure rolls the reservation back active.
Two concurrent buyers -> exactly one sale + one debit.
Deps (additive): rand 0.8 (adapter+host), sqlx 0.7 sqlite/runtime-tokio (host).
Tests: adapter +7 (pack_content), host +43 (economy_store 20, market/store 23
incl two_reservers_exactly_one_wins, two_buyers_exactly_one_sale_one_debit,
state_survives_reopen, move_persists_across_reopen). All green; clippy
-D warnings clean; rustfmt clean.
34 lines
1.6 KiB
TOML
34 lines
1.6 KiB
TOML
[package]
|
|
name = "openfut-utas-host"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
license = "MIT"
|
|
description = "FIFA 17 UTAS migration host: serves implemented routes (/club) from OpenFUT Core, transparently proxies everything else to the Python UTAS oracle"
|
|
publish = false
|
|
|
|
[dependencies]
|
|
openfut-adapter-fifa17 = { path = "../openfut-adapter-fifa17" }
|
|
openfut-http = { path = "../openfut-http" }
|
|
openfut-identity = { path = "../openfut-identity" }
|
|
serde_json = "1"
|
|
# Plain-HTTP client for Core queries and Python passthrough. UTAS is plaintext
|
|
# HTTP (worker D: no wrap_socket, no cert), so no TLS backend is linked.
|
|
reqwest = { version = "0.11", default-features = false, features = ["blocking", "json"] }
|
|
# Durable FIFA-specific market listing + item-pile state. These are host-owned
|
|
# FIFA policy stores (NOT generic Core inventory), backed by their own SQLite
|
|
# file, opened exactly like openfut-core/src/db.rs::init_pool (WAL-once +
|
|
# foreign_keys + busy_timeout, BEGIN IMMEDIATE for writes).
|
|
sqlx = { version = "0.7", features = ["sqlite", "runtime-tokio"] }
|
|
# Seeded RNG for the Store pack-content generator injected into the economy
|
|
# writer handlers (`economy_store`). Production seeds it from entropy (so minted
|
|
# Core instance ids never collide); tests seed a fixed value for reproducibility.
|
|
rand = "0.8"
|
|
|
|
[dev-dependencies]
|
|
parking_lot = "0.12"
|
|
# Real host<->Core integration harness: spawn Core (axum) against a disposable
|
|
# temp-file SQLite and drive the real CoreEconomy transport (no fakes).
|
|
openfut-core = { path = "../openfut-core" }
|
|
tokio = { version = "1", features = ["rt-multi-thread", "macros", "net"] }
|
|
axum = "0.7"
|