feat(workspace): full server + sync implementation, all tests green
- solitaire_server: Axum auth, sync push/pull, leaderboard, daily challenge, account deletion, JWT middleware, rate limiting via tower_governor, SQLite migrations, health endpoint - solitaire_server: expose build_test_router (no rate limiting) so integration tests work without a peer IP in oneshot requests - solitaire_sync: SyncPayload, merge logic, shared API types - solitaire_data: SyncProvider trait, LocalOnlyProvider, SolitaireServerClient, auth_tokens keyring integration, blanket Box<dyn SyncProvider> impl - solitaire_data/settings: derive Default on SyncBackend (clippy fix) - .sqlx/: offline query cache so server compiles without a live DB - sqlx: removed non-existent "offline" feature flag - keyring v2: fixed Entry::new() returning Result<Entry> - sqlx 0.8: all SQLite TEXT columns wrapped in Option<T> - Integration tests: max_connections(1) on in-memory pool so all connections share the same schema All 191 tests pass; cargo clippy -D warnings clean. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -35,11 +35,35 @@ pub trait SyncProvider: Send + Sync {
|
||||
}
|
||||
}
|
||||
|
||||
/// Blanket impl so `Box<dyn SyncProvider + Send + Sync>` (returned by
|
||||
/// `provider_for_backend`) can be passed directly to `SyncPlugin::new`.
|
||||
#[async_trait]
|
||||
impl SyncProvider for Box<dyn SyncProvider + Send + Sync> {
|
||||
async fn pull(&self) -> Result<SyncPayload, SyncError> {
|
||||
(**self).pull().await
|
||||
}
|
||||
async fn push(&self, payload: &SyncPayload) -> Result<SyncResponse, SyncError> {
|
||||
(**self).push(payload).await
|
||||
}
|
||||
fn backend_name(&self) -> &'static str {
|
||||
(**self).backend_name()
|
||||
}
|
||||
fn is_authenticated(&self) -> bool {
|
||||
(**self).is_authenticated()
|
||||
}
|
||||
async fn mirror_achievement(&self, id: &str) -> Result<(), SyncError> {
|
||||
(**self).mirror_achievement(id).await
|
||||
}
|
||||
}
|
||||
|
||||
pub mod stats;
|
||||
pub use stats::StatsSnapshot;
|
||||
pub use stats::{StatsExt, StatsSnapshot};
|
||||
|
||||
pub mod storage;
|
||||
pub use storage::{load_stats, load_stats_from, save_stats, save_stats_to, stats_file_path};
|
||||
pub use storage::{
|
||||
cleanup_orphaned_tmp_files, load_stats, load_stats_from, save_stats, save_stats_to,
|
||||
stats_file_path,
|
||||
};
|
||||
|
||||
pub mod achievements;
|
||||
pub use achievements::{
|
||||
@@ -62,4 +86,15 @@ pub mod challenge;
|
||||
pub use challenge::{challenge_count, challenge_seed_for, CHALLENGE_SEEDS};
|
||||
|
||||
pub mod settings;
|
||||
pub use settings::{load_settings_from, save_settings_to, settings_file_path, Settings};
|
||||
pub use settings::{
|
||||
load_settings_from, save_settings_to, settings_file_path, AnimSpeed, Settings, SyncBackend,
|
||||
Theme,
|
||||
};
|
||||
|
||||
pub mod auth_tokens;
|
||||
pub use auth_tokens::{
|
||||
delete_tokens, load_access_token, load_refresh_token, store_tokens, TokenError,
|
||||
};
|
||||
|
||||
pub mod sync_client;
|
||||
pub use sync_client::{provider_for_backend, LocalOnlyProvider, SolitaireServerClient};
|
||||
|
||||
Reference in New Issue
Block a user