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:
@@ -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 }))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user