feat(economy): purchase_items primitive + entitlement import seeding

purchase_items: generic atomic debit + mint of several items (fail-closed) for
open-on-buy Store packs (Store BUY returns items immediately) + POST
/economy/purchase-items route. Import: add optional entitlements[] to
ProfileImportRequest, seeding unconsumed packs rows in the same transaction (so a
source's unopened packs become Core entitlements); idempotency via the existing
import fingerprint. Tests: 2 purchase_items unit + endpoint + entitlement-seed
import. Core matrix 45 lib + 116 integration + 9 import green; clippy clean.
This commit is contained in:
OpenFUT Agent
2026-08-13 19:27:06 +00:00
parent d32dc6e3ae
commit bcc4f5104a
6 changed files with 150 additions and 2 deletions
+17
View File
@@ -144,3 +144,20 @@ pub async fn post_purchase_item(
economy::purchase_item(&state.pool, &club, req.cost, &req.item_id, &req.card_id).await?;
Ok(Json(BalanceResponse { balance }))
}
#[derive(Deserialize)]
pub struct PurchaseItemsRequest {
pub cost: i64,
pub items: Vec<GrantedItem>,
}
/// `POST /economy/purchase-items` — atomic debit + mint several items.
pub async fn post_purchase_items(
State(state): State<AppState>,
game: GameId,
Json(req): Json<PurchaseItemsRequest>,
) -> AppResult<Json<BalanceResponse>> {
let club = resolve_club(&state, &game).await?;
let balance = economy::purchase_items(&state.pool, &club, req.cost, &req.items).await?;
Ok(Json(BalanceResponse { balance }))
}