Phase 9: division/season tracking, club customization, pack history, notifications
CI / Build, lint & test (push) Failing after 1m42s
CI / Build, lint & test (push) Failing after 1m42s
- GET /division returns live season stats (points, record, promotion threshold) - PUT /club allows updating club name and manager_name - GET /packs/history returns opened packs with full card definitions - GET /notifications dynamically surfaces completed objectives, expiring loans, season end - Club model gains manager_name column (migration 0006 already added it) - Pack model gains opened_cards and opened_at; pack SELECT queries updated - 9 new integration tests — all 45 pass, clippy clean Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -57,6 +57,50 @@ pub async fn get_packs(State(state): State<AppState>) -> AppResult<Json<Value>>
|
||||
Ok(Json(json!({ "packs": with_defs })))
|
||||
}
|
||||
|
||||
/// Return recently opened packs with the card IDs they contained.
|
||||
pub async fn get_pack_history(State(state): State<AppState>) -> AppResult<Json<Value>> {
|
||||
let profile = profile_svc::get_active_profile(&state.pool).await?;
|
||||
let club = club_svc::get_club_by_profile(&state.pool, &profile.id).await?;
|
||||
|
||||
let opened = sqlx::query_as::<_, crate::models::pack::Pack>(
|
||||
"SELECT id, club_id, definition_id, opened, created_at, opened_cards, opened_at \
|
||||
FROM packs WHERE club_id = ? AND opened = 1 ORDER BY opened_at DESC LIMIT 50",
|
||||
)
|
||||
.bind(&club.id)
|
||||
.fetch_all(&state.pool)
|
||||
.await?;
|
||||
|
||||
let history: Vec<Value> = opened
|
||||
.iter()
|
||||
.map(|p| {
|
||||
let def = state.pack_defs.iter().find(|d| d.id == p.definition_id);
|
||||
// Expand card_ids into full card definitions
|
||||
let cards: Vec<Value> = p
|
||||
.opened_cards
|
||||
.as_deref()
|
||||
.and_then(|s| serde_json::from_str::<Vec<String>>(s).ok())
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.map(|id| {
|
||||
json!({
|
||||
"card_id": id,
|
||||
"card": state.card_db.get(id),
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
json!({
|
||||
"pack_id": p.id,
|
||||
"definition_id": p.definition_id,
|
||||
"name": def.map(|d| &d.name),
|
||||
"opened_at": p.opened_at,
|
||||
"cards": cards,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(Json(json!({ "history": history, "total": history.len() })))
|
||||
}
|
||||
|
||||
pub async fn post_open_pack(
|
||||
State(state): State<AppState>,
|
||||
Path(pack_id): Path<String>,
|
||||
|
||||
Reference in New Issue
Block a user