refactor: fix HIGH+MEDIUM architectural violations from code review
HIGH: fix watch_medium data-loss bug, standardize error handling on ApiError, fix dep direction (rss/template-askama no longer dep on application), extract ImageFetcher port (remove reqwest from app layer), move event construction from save_review to use case, extract infra-wiring crate (DbPool/EventBusBackend dedup), deduplicate presentation helpers (encode_error, export streaming, multipart parsing) MEDIUM: split LocalApContentQuery god-trait 10→3 methods, dedup movie resolution orchestration, add RemoteActorDto/PersonDto mappers, move AppConfig to infra-wiring, fix SocialQueryPort Uuid→UserId, replace stringly-typed api-types with domain enums, move count_reviews_in_year to StatsRepository, dedup event publisher cfg blocks, extract should_enrich, move group_by_month to application, dedup count_local_posts, add FederationFlags Default, TUI input helper + ShowError rename + typed auth errors, api-types cleanup (UserSettingsDto/UserProfileBase/PreviewRowData) 102 files changed, -681 lines net
This commit is contained in:
@@ -5,9 +5,17 @@ use tokio::sync::mpsc;
|
||||
use ratatui::crossterm::event::{self, Event, KeyCode, KeyModifiers};
|
||||
|
||||
use tui::app::{self, Action, App, BulkImportStage, Command, Screen, SettingsField, Tab};
|
||||
use tui::client::ApiClient;
|
||||
use tui::client::{ApiClient, ApiError};
|
||||
use tui::config::Config;
|
||||
|
||||
/// Convert an API error into either `AuthExpired` (for 401s) or a `ShowError`.
|
||||
fn api_err_action(e: ApiError) -> Action {
|
||||
match e {
|
||||
ApiError::Unauthorized => Action::AuthExpired,
|
||||
other => Action::ShowError(other.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
Config::init_keyring()?;
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
@@ -53,7 +61,7 @@ async fn run() -> anyhow::Result<()> {
|
||||
entries: r.items,
|
||||
total: r.total_count,
|
||||
},
|
||||
Err(e) => Action::DiaryLoadFailed(e.to_string()),
|
||||
Err(e) => api_err_action(e),
|
||||
};
|
||||
let _ = tx2.send(action).await;
|
||||
});
|
||||
@@ -109,7 +117,7 @@ fn handle_command(cmd: Command, app: &App, client: &Arc<ApiClient>, tx: &mpsc::S
|
||||
let tx2 = tx.clone();
|
||||
let msg = format!("Failed to save config: {e}");
|
||||
tokio::spawn(async move {
|
||||
let _ = tx2.send(Action::DiaryLoadFailed(msg)).await;
|
||||
let _ = tx2.send(Action::ShowError(msg)).await;
|
||||
});
|
||||
}
|
||||
client.update_url(&url);
|
||||
@@ -123,7 +131,7 @@ fn handle_command(cmd: Command, app: &App, client: &Arc<ApiClient>, tx: &mpsc::S
|
||||
.unwrap_or_else(|e| Err(anyhow::anyhow!(e)))
|
||||
{
|
||||
let msg = format!("Token not saved to keychain: {e}");
|
||||
let _ = tx2.send(Action::DiaryLoadFailed(msg)).await;
|
||||
let _ = tx2.send(Action::ShowError(msg)).await;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -158,7 +166,7 @@ fn handle_command(cmd: Command, app: &App, client: &Arc<ApiClient>, tx: &mpsc::S
|
||||
entries: r.items,
|
||||
total: r.total_count,
|
||||
},
|
||||
Err(e) => Action::DiaryLoadFailed(e.to_string()),
|
||||
Err(e) => api_err_action(e),
|
||||
};
|
||||
let _ = tx.send(action).await;
|
||||
});
|
||||
@@ -173,6 +181,7 @@ fn handle_command(cmd: Command, app: &App, client: &Arc<ApiClient>, tx: &mpsc::S
|
||||
tokio::spawn(async move {
|
||||
let action = match c.get_movie_history(&token, movie_id).await {
|
||||
Ok(r) => Action::HistoryLoaded(r),
|
||||
Err(ApiError::Unauthorized) => Action::AuthExpired,
|
||||
Err(e) => Action::HistoryLoadFailed(e.to_string()),
|
||||
};
|
||||
let _ = tx.send(action).await;
|
||||
@@ -188,6 +197,7 @@ fn handle_command(cmd: Command, app: &App, client: &Arc<ApiClient>, tx: &mpsc::S
|
||||
tokio::spawn(async move {
|
||||
let action = match c.create_review(&token, &req).await {
|
||||
Ok(()) => Action::ReviewCreated,
|
||||
Err(ApiError::Unauthorized) => Action::AuthExpired,
|
||||
Err(e) => Action::ReviewCreateFailed(e.to_string()),
|
||||
};
|
||||
let _ = tx.send(action).await;
|
||||
@@ -203,6 +213,7 @@ fn handle_command(cmd: Command, app: &App, client: &Arc<ApiClient>, tx: &mpsc::S
|
||||
tokio::spawn(async move {
|
||||
let action = match c.delete_review(&token, id).await {
|
||||
Ok(()) => Action::ReviewDeleted(id),
|
||||
Err(ApiError::Unauthorized) => Action::AuthExpired,
|
||||
Err(e) => Action::ReviewDeleteFailed(e.to_string()),
|
||||
};
|
||||
let _ = tx.send(action).await;
|
||||
|
||||
Reference in New Issue
Block a user