feat(panel): implement wizard setup - #434
Merged
Merged
Conversation
… Docker compatibility
Closed
Contributor
There was a problem hiding this comment.
Pull request overview
Implements a first-run setup wizard for Rustmail (backend setup-mode HTTP endpoints + frontend Yew wizard), alongside broad backend refactors/cleanups (router construction simplification, let-chains, and clippy-driven lint fixes) and config/env improvements.
Changes:
- Add “setup mode” server path when
config.tomlis missing, with/api/setup/*endpoints to validate Discord inputs, save config, and trigger a restart. - Add a new
/setupwizard UI inrustmail_panelwith EN/FR dictionaries and a setup detector that routes users into the wizard. - Refactor many backend modules for clippy fixes (needless borrows, simplified conditionals) and add
chrono-tzusage + new env-based config/path helpers.
Reviewed changes
Copilot reviewed 109 out of 110 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/rustmail/src/utils/thread/send_to_thread.rs | Minor borrow cleanup when fetching thread status. |
| crates/rustmail/src/utils/message/message_builder.rs | Clippy cleanups (needless borrows, boolean style). |
| crates/rustmail/src/setup/state.rs | New setup-state model for wizard progress + shutdown trigger. |
| crates/rustmail/src/setup/router.rs | New setup router exposing /api/setup/* endpoints. |
| crates/rustmail/src/setup/mod.rs | Wires new setup module. |
| crates/rustmail/src/setup/handlers/validate.rs | New validation handlers (token/guild/channel/oauth2) via Discord API. |
| crates/rustmail/src/setup/handlers/status.rs | New status handler for setup wizard bootstrap info. |
| crates/rustmail/src/setup/handlers/save.rs | New handler to build/validate/save config from wizard input. |
| crates/rustmail/src/setup/handlers/restart.rs | New handler to trigger graceful shutdown/restart transition. |
| crates/rustmail/src/setup/handlers/mod.rs | Exports setup handlers. |
| crates/rustmail/src/modules/threads.rs | Let-chain refactors + interaction followup builder simplification. |
| crates/rustmail/src/modules/scheduled_closures.rs | Let-chain refactors; simplify logs emission conditionals. |
| crates/rustmail/src/modules/reminders.rs | Borrow cleanup when spawning reminders. |
| crates/rustmail/src/modules/message_recovery.rs | Borrow cleanup for message recovery pipeline. |
| crates/rustmail/src/modules/commands.rs | Borrow cleanup for i18n calls + MessageBuilder usage. |
| crates/rustmail/src/modules/categories.rs | Let-chain refactors + simplified timeout/forwarding flows. |
| crates/rustmail/src/main.rs | Adds setup-mode runtime path; adds bind/port resolution helpers. |
| crates/rustmail/src/handlers/guild_moderation_handler.rs | Let-chain refactors + borrow cleanup. |
| crates/rustmail/src/handlers/guild_messages_handler.rs | Let-chain refactors for maintenance mode + closure cancel flow. |
| crates/rustmail/src/handlers/guild_interaction_handler.rs | Let-chain refactors for maintenance gating + error handling. |
| crates/rustmail/src/handlers/guild_ban_handler.rs | Let-chain refactor in audit log parsing. |
| crates/rustmail/src/handlers/audit_log/formatters/mod.rs | Minor pattern simplification in change formatting. |
| crates/rustmail/src/handlers/audit_log/formatters/member.rs | Let-chain refactors in formatter logic. |
| crates/rustmail/src/db/operations/init.rs | DB path now env-resolved (via resolve_db_path). |
| crates/rustmail/src/db/operations/banned_users.rs | Removes comments; keeps bulk upsert logic unchanged. |
| crates/rustmail/src/config.rs | Adds env/path/port helpers + env overrides; moves config save/validate here. |
| crates/rustmail/src/commands/take/text_command/take.rs | Borrow cleanup in ticket-channel detection. |
| crates/rustmail/src/commands/take/slash_command/take.rs | Borrow cleanup in ticket-channel detection. |
| crates/rustmail/src/commands/status/slash_command/status.rs | Let-chain refactor when extracting option value. |
| crates/rustmail/src/commands/snippet/text_command/snippet.rs | Borrow cleanup when deleting snippet. |
| crates/rustmail/src/commands/snippet/slash_command/snippet.rs | Let-chain refactors + borrow cleanup for interaction followups. |
| crates/rustmail/src/commands/reply/text_command/reply.rs | Let-chain refactor for snippet expansion. |
| crates/rustmail/src/commands/rename/text_command/rename.rs | Borrow cleanup in ticket-channel detection. |
| crates/rustmail/src/commands/rename/slash_command/rename.rs | Borrow cleanup + let-chain refactor for option parsing. |
| crates/rustmail/src/commands/remove_staff/text_command/remove_staff.rs | Simplify ok_or_else to ok_or. |
| crates/rustmail/src/commands/remove_reminder/text_command/remove_reminder.rs | Borrow cleanup for MessageBuilder. |
| crates/rustmail/src/commands/remove_reminder/slash_command/remove_reminder.rs | Let-chain style refactor for option parsing. |
| crates/rustmail/src/commands/reminder_subscription/slash_command/reminder_subscription.rs | Simplify ok_or_else to ok_or. |
| crates/rustmail/src/commands/release/text_command/release.rs | Borrow cleanup in ticket-channel detection. |
| crates/rustmail/src/commands/release/slash_command/release.rs | Borrow cleanup in ticket-channel detection. |
| crates/rustmail/src/commands/ping/text_command/ping.rs | Borrow cleanup for MessageBuilder. |
| crates/rustmail/src/commands/new_thread/text_command/new_thread.rs | Borrow cleanup for i18n + MessageBuilder. |
| crates/rustmail/src/commands/new_thread/slash_command/new_thread.rs | Minor formatting cleanup in logs output. |
| crates/rustmail/src/commands/move_thread/slash_command/move_thread.rs | Simplifies “not in thread” check logic. |
| crates/rustmail/src/commands/move_thread/common.rs | Removes comments; keeps error mapping logic. |
| crates/rustmail/src/commands/logs/text_command/logs.rs | Borrow cleanup passing ctx/config/pool. |
| crates/rustmail/src/commands/logs/slash_command/logs.rs | Option parsing cleanup; simplifies is_none check. |
| crates/rustmail/src/commands/logs/common.rs | Pagination rendering tweaks + minor control-flow cleanup. |
| crates/rustmail/src/commands/id/text_command/id.rs | Borrow cleanup + simpler string formatting. |
| crates/rustmail/src/commands/id/slash_command/id.rs | Simpler string formatting. |
| crates/rustmail/src/commands/help/text_command/help.rs | Minor string split simplification. |
| crates/rustmail/src/commands/help/slash_command/help.rs | Let-chain refactor for option parsing. |
| crates/rustmail/src/commands/help/common.rs | Iteration simplification; borrow cleanup; string conversion cleanup. |
| crates/rustmail/src/commands/force_close/text_command/force_close.rs | Let-chain refactor for logs emission conditions. |
| crates/rustmail/src/commands/force_close/slash_command/force_close.rs | Let-chain refactor for logs emission conditions. |
| crates/rustmail/src/commands/edit/message_ops.rs | Let-chain refactor when resolving guild id. |
| crates/rustmail/src/commands/edit/common.rs | Updates test config to include panel_port. |
| crates/rustmail/src/commands/delete/slash_command/delete.rs | Let-chain refactor for option parsing. |
| crates/rustmail/src/commands/delete/common.rs | Borrow cleanup for DB lookups. |
| crates/rustmail/src/commands/close/text_command/close.rs | Let-chain refactors around scheduled closure + logs emission. |
| crates/rustmail/src/commands/close/slash_command/close.rs | Let-chain refactors around duration parsing + logs emission. |
| crates/rustmail/src/commands/category/text_command/category.rs | Removes comment + let-chain refactor in rename conflict check. |
| crates/rustmail/src/commands/category/slash_command/category.rs | Let-chain refactors in option parsing + rename conflict check. |
| crates/rustmail/src/commands/baninfo/slash_command/baninfo.rs | Let-chain refactor + simplify missing-arg error creation. |
| crates/rustmail/src/commands/anonreply/text_command/anonreply.rs | Let-chain refactor for snippet expansion. |
| crates/rustmail/src/commands/alert/common.rs | Simplifies error propagation using ?. |
| crates/rustmail/src/commands/add_staff/text_command/add_staff.rs | Simplify ok_or_else to ok_or. |
| crates/rustmail/src/commands/add_reminder/text_command/add_reminder.rs | Borrow cleanup + simplify ok_or_else to ok_or. |
| crates/rustmail/src/commands/add_reminder/slash_command/add_reminder.rs | Simplify ok_or_else to ok_or; let-chain refactors in role parsing. |
| crates/rustmail/src/commands/add_reminder/common.rs | Borrow cleanup for MessageBuilder + interaction followup call. |
| crates/rustmail/src/bot.rs | init_bot_state now accepts config path; uses env-resolved config path. |
| crates/rustmail/src/api/utils/user_permissions.rs | Let-chain refactors in overwrite evaluation. |
| crates/rustmail/src/api/utils/panel_permissions.rs | Let-chain refactors in permission extraction loops. |
| crates/rustmail/src/api/routes/user.rs | Router-construction simplification. |
| crates/rustmail/src/api/routes/panel.rs | Router-construction simplification. |
| crates/rustmail/src/api/routes/externals/tickets.rs | Router-construction simplification. |
| crates/rustmail/src/api/routes/externals/mod.rs | Router-construction simplification. |
| crates/rustmail/src/api/routes/bot.rs | Router-construction simplification. |
| crates/rustmail/src/api/routes/auth.rs | Router-construction simplification. |
| crates/rustmail/src/api/routes/apikeys.rs | Router-construction simplification. |
| crates/rustmail/src/api/router.rs | Router-construction simplification. |
| crates/rustmail/src/api/middleware/auth.rs | Simplifies membership check; let-chain refactor for API key header. |
| crates/rustmail/src/api/handler/health.rs | Let-chain refactor for DB health check. |
| crates/rustmail/src/api/handler/categories/categories.rs | Let-chain refactors for conflict/enabled-limit/ID parsing. |
| crates/rustmail/src/api/handler/bot/tickets.rs | Let-chain refactor in permission check; uses or_default grouping. |
| crates/rustmail/src/api/handler/bot/config.rs | Removes duplicated save/validate; uses shared config helpers. |
| crates/rustmail/src/api/handler/auth/logout.rs | Borrow cleanup passing session_id. |
| crates/rustmail/src/api/handler/admin/permissions.rs | Let-chain refactor parsing rows into typed entries. |
| crates/rustmail/Cargo.toml | Adds chrono-tz dependency. |
| crates/rustmail_types/src/config/bot.rs | Adds panel_port with default 3002. |
| crates/rustmail_panel/src/router.rs | Adds /setup route. |
| crates/rustmail_panel/src/pages/setup.rs | New Setup page driving step components and i18n titles/descriptions. |
| crates/rustmail_panel/src/pages/mod.rs | Exposes new setup page module. |
| crates/rustmail_panel/src/main.rs | Mounts SetupDetector to redirect into setup mode. |
| crates/rustmail_panel/src/i18n/fr/fr.json | Adds full wizard translation keys (FR). |
| crates/rustmail_panel/src/i18n/en/en.json | Adds full wizard translation keys (EN). |
| crates/rustmail_panel/src/components/wizard/types.rs | Defines wizard data model + request/response DTOs. |
| crates/rustmail_panel/src/components/wizard/step6_review.rs | Final review/save step + restart/redirect behavior. |
| crates/rustmail_panel/src/components/wizard/step5_language.rs | Language/timezone/messages step (i18n-driven). |
| crates/rustmail_panel/src/components/wizard/step4_panel.rs | Panel/OAuth2 settings + validation step. |
| crates/rustmail_panel/src/components/wizard/step3_thread.rs | Thread/category settings + category validation step. |
| crates/rustmail_panel/src/components/wizard/step2_guilds.rs | Server mode + guild validation step. |
| crates/rustmail_panel/src/components/wizard/step1_token.rs | Bot token validation step. |
| crates/rustmail_panel/src/components/wizard/progress_bar.rs | Wizard progress bar component. |
| crates/rustmail_panel/src/components/wizard/mod.rs | Exports wizard components. |
| crates/rustmail_panel/src/components/wizard/layout.rs | Wizard layout + in-wizard language switcher placement. |
| crates/rustmail_panel/src/components/setup_detector.rs | Detects setup mode and routes to /setup. |
| crates/rustmail_panel/src/components/mod.rs | Exposes new setup/wizard components. |
| crates/rustmail_panel/Cargo.toml | Adds gloo-timers dependency for restart delay. |
| Cargo.lock | Updates lockfile for new deps (chrono-tz, gloo-timers). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
50
to
53
| let _ = writeln!( | ||
| desc, | ||
| "**#{}** | [`🎫 {}`]({}) | 🔒 {} {}", | ||
| "**#{}** | [`🎫 {}`]({}) | 🔒 {} \n", | ||
| log.id, |
Comment on lines
+12
to
15
| let db_path = resolve_db_path("db/db.sqlite"); | ||
|
|
||
| fs::create_dir_all("db")?; | ||
|
|
| client_id: payload.client_id.unwrap_or(0), | ||
| client_secret: payload.client_secret.unwrap_or_default(), | ||
| redirect_url: payload.redirect_url.unwrap_or_default(), | ||
| timezone: payload.timezone.parse().unwrap_or(chrono_tz::UTC), |
| let target_url = if panel_url.is_empty() { | ||
| format!("http://localhost:{}", api_port) | ||
| } else { | ||
| let has_port = panel_url.matches(':').count() > 1; |
Comment on lines
+50
to
+54
| auto_archive_duration: 1440, | ||
| panel_url: String::new(), | ||
| api_port: 8080, | ||
| client_id: String::new(), | ||
| client_secret: String::new(), |
Comment on lines
+41
to
+49
| if *is_checking { | ||
| html! { | ||
| <div class="flex items-center justify-center min-h-screen bg-slate-900 text-white"> | ||
| <div class="text-gray-400 animate-pulse">{ "Checking setup mode..." }</div> | ||
| </div> | ||
| } | ||
| } else { | ||
| html! {} | ||
| } |
Comment on lines
+4
to
+8
| pub struct ProgressBarProps { | ||
| pub current_step: usize, | ||
| pub total_steps: usize, | ||
| pub step_names: Vec<&'static str>, | ||
| } |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces several codebase cleanups and refactors, mainly focused on simplifying router construction, improving conditional logic, and removing redundant code. It also adds a new dependency, makes some minor fixes, and brings full internationalization to the frontend setup wizard.
Below are the most important changes:
Router Construction Simplification
create_api_router,create_apikeys_router,create_auth_router, etc.) to return the router directly instead of assigning to a local variable and returning it, resulting in more concise and readable code.Conditional Logic Improvements
if letand nestedifstatements to use Rust's new "let-chains" (if ... && let ...) syntax, making conditions more concise and readable in several handlers and utility functions.matchstatements and error handling, such as replacing amatchwith a single.is_ok()check.Code Cleanup and Redundancy Removal
Dependency and Utility Changes
chrono-tzcrate as a new dependency inCargo.toml.config.rs, removed local implementations ofsave_config_with_backupandvalidate_configin favor of using the versions imported from the config module, reducing code duplication.Minor Fixes
handle_logoutby removing an unnecessary reference in a function call..or_insert_with(Vec::new)to.or_default()for improved clarity in message grouping.Setup Wizard Internationalization (i18n)
use_translation()hook across all Setup Wizard steps (Step 1 to Step 6) in therustmail_panelcrate.LanguageSwitchercomponent to theWizardLayout, allowing users to seamlessly toggle between English and French in real-time during the setup process.LanguageSwitcherto ensure it remains visible and correctly placed in the top-right corner on both desktop and mobile devices.en.jsonandfr.jsonwith all the necessary keys for the setup wizard, including dynamic translations (e.g. injecting the panel URL dynamically in the final step).Compiler Warnings & Errors Cleanup
never_looperrors inmain.rsthat were causing the build to fail under strict lints (clippy::never_loop).SetupStatusResponse,GuildInfo, andStatusResponseby explicitly allowing them.cargo clippy --fixon therustmailbackend crate, automatically resolving over 200 minor linting issues across the codebase (e.g. eliminating needless memory borrows, optimizing boolean comparisons, and replacing redundant pattern matching).These changes collectively improve code readability, maintainability, and reduce redundancy across the codebase.