407cae2040
Build and Deploy / build-and-push (push) Successful in 5m7s
- Add migration 005: nullable avatar_url column on users table - Add GET /api/me: returns id, username, avatar_url from DB (fixes UUID-on-profile bug) - Add PUT /api/me/avatar: accepts raw image bytes (≤1 MB, jpeg/png/webp/gif), writes to avatars/ dir, updates avatar_url in DB - Serve /avatars via ServeDir so uploaded images are publicly accessible - Update account.html: fetch username from /api/me instead of parsing JWT; add circular avatar display with initials fallback and click-to-upload - Add SolitaireServerClient::fetch_me() for desktop/Android profile display - Add avatar_url field to SyncBackend::SolitaireServer settings (serde default None) - Update sqlx offline query cache for new avatar_url queries Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Database Migrations
Migrations are run automatically at server startup via sqlx::migrate!("./migrations").
Naming convention
NNN_description.sql
NNN— zero-padded three-digit sequence number (001,002, …)description— snake_case description of what the migration does
Examples:
001_initial.sql
002_add_user_display_name.sql
003_weekly_goals_table.sql
sqlx tracks which migrations have run in the _sqlx_migrations table and only applies new ones. Never edit or delete an existing migration file after it has been applied to any database — add a new migration instead.
Adding a migration
- Create
migrations/NNN_description.sqlwhereNNNis the next available number. - Write idempotent SQL (
CREATE TABLE IF NOT EXISTS,ALTER TABLE … ADD COLUMN IF NOT EXISTS, etc.) where possible. - Update the sqlx offline query cache so the server builds without a live DB:
export DATABASE_URL=sqlite://solitaire.db sqlx database create sqlx migrate run --source solitaire_server/migrations cargo sqlx prepare --workspace - Commit both the migration file and the updated
.sqlx/query cache together.
Current schema
See 001_initial.sql for the full initial schema: users, sync_state, daily_challenges, leaderboard.