Initial commit: OpenFUT Core
Offline Ultimate Team backend — game-independent REST API. - 19 API endpoints: auth, profiles, clubs, cards, packs, squads, objectives, SBCs, match rewards, NPC market, statistics - Axum + SQLite + SQLx with full migrations - Weighted pack generator, SBC validation engine - JSON-driven mod data (cards, packs, objectives, SBCs) - 5 integration tests passing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
use crate::{
|
||||
db::Pool,
|
||||
error::{AppError, AppResult},
|
||||
models::profile::Profile,
|
||||
};
|
||||
use chrono::Utc;
|
||||
|
||||
pub async fn get_active_profile(pool: &Pool) -> AppResult<Profile> {
|
||||
sqlx::query_as::<_, Profile>(
|
||||
"SELECT id, username, level, xp, created_at, updated_at FROM profiles ORDER BY created_at ASC LIMIT 1"
|
||||
)
|
||||
.fetch_optional(pool)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("no profile exists; call POST /auth/local first".into()))
|
||||
}
|
||||
|
||||
pub async fn create_profile(pool: &Pool, username: &str) -> AppResult<Profile> {
|
||||
let existing = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM profiles")
|
||||
.fetch_one(pool)
|
||||
.await?;
|
||||
if existing > 0 {
|
||||
return Err(AppError::Conflict(
|
||||
"a profile already exists; OpenFUT is single-player only".into(),
|
||||
));
|
||||
}
|
||||
|
||||
let profile = Profile::new(username);
|
||||
sqlx::query(
|
||||
"INSERT INTO profiles (id, username, level, xp, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)"
|
||||
)
|
||||
.bind(&profile.id)
|
||||
.bind(&profile.username)
|
||||
.bind(profile.level)
|
||||
.bind(profile.xp)
|
||||
.bind(profile.created_at)
|
||||
.bind(profile.updated_at)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
Ok(profile)
|
||||
}
|
||||
|
||||
pub async fn add_xp(pool: &Pool, profile_id: &str, xp: i64) -> AppResult<()> {
|
||||
let now = Utc::now();
|
||||
sqlx::query("UPDATE profiles SET xp = xp + ?, updated_at = ? WHERE id = ?")
|
||||
.bind(xp)
|
||||
.bind(now)
|
||||
.bind(profile_id)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user