Fix additional clippy warnings and update progress

- Add #[allow(dead_code)] to temporarily unused functions
- Remove unused is_expired() and UserRole::as_str()
- Fix unused variable warnings (token, theme)
- Update progress.txt: mark all stories complete

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
xfy 2026-05-25 17:02:14 +08:00
parent 5afd8b597c
commit c4dfd1f445
11 changed files with 43 additions and 33 deletions

View File

@ -6,9 +6,33 @@
- User requirement: 每完成一个功能,提交一次
## Stories
- [ ] US-001: 数据库配置与建表
- [ ] US-002: 用户模型与认证模块
- [ ] US-003: 认证 API
- [ ] US-004: 前端页面 - 注册与登录
- [ ] US-005: 后台页面与路由整合
- [ ] US-006: 验证
- [x] US-001: 数据库配置与建表
- [x] US-002: 用户模型与认证模块
- [x] US-003: 认证 API
- [x] US-004: 前端页面 - 注册与登录
- [x] US-005: 后台页面与路由整合
- [x] US-006: 验证
## Commits
1. US-001: 数据库配置与建表
2. US-002: 用户模型与认证模块
3. US-003: 认证 API (Server Functions)
4. US-004: 前端页面 - 注册与登录
5. US-005: 后台页面与路由整合
6. US-006: 验证 + 修复编译和运行时问题
7. Fix clippy warnings
## Implementation Details
- PostgreSQL + tokio-postgres + deadpool 连接池
- argon2 密码哈希
- UUID v4 session token + 30天过期
- Dioxus 0.7.9 SSR Fullstack + `#[server]` 函数
- Tailwind CSS CDN + darkMode class 主题切换
- 首个注册用户自动 admin后续注册关闭
- wasm32 和 server 双目标编译
## Verification Results
- cargo check (server) ✅
- cargo check (wasm32) ✅
- cargo clippy ✅ (warnings only)
- API tests: register ✅, login ✅, get_current_user ✅, re-register blocked ✅, wrong password ✅

View File

@ -1,9 +1,12 @@
#![allow(clippy::unused_unit, deprecated, unused_imports)]
use dioxus::prelude::*;
use crate::auth::{password, session};
use crate::db::pool::DB_POOL;
use crate::models::user::{User, UserRole};
#[allow(dead_code)]
fn validate_username(username: &str) -> Result<(), String> {
if username.len() < 3 || username.len() > 50 {
return Err("用户名长度必须在 3-50 字符之间".to_string());
@ -14,6 +17,7 @@ fn validate_username(username: &str) -> Result<(), String> {
Ok(())
}
#[allow(dead_code)]
fn validate_email(email: &str) -> Result<(), String> {
let re = regex::Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap();
if !re.is_match(email) {
@ -22,6 +26,7 @@ fn validate_email(email: &str) -> Result<(), String> {
Ok(())
}
#[allow(dead_code)]
fn validate_password(password: &str) -> Result<(), String> {
if password.len() < 8 {
return Err("密码长度至少 8 位".to_string());

View File

@ -4,6 +4,7 @@ use argon2::{
};
use rand::rngs::OsRng;
#[allow(dead_code)]
pub fn hash_password(password: &str) -> Result<String, argon2::password_hash::Error> {
let salt = SaltString::generate(&mut OsRng);
let argon2 = Argon2::default();
@ -11,6 +12,7 @@ pub fn hash_password(password: &str) -> Result<String, argon2::password_hash::Er
Ok(password_hash.to_string())
}
#[allow(dead_code)]
pub fn verify_password(password: &str, hash: &str) -> Result<bool, argon2::password_hash::Error> {
let parsed_hash = PasswordHash::new(hash)?;
let argon2 = Argon2::default();

View File

@ -1,14 +1,12 @@
use chrono::{DateTime, Duration, Utc};
use uuid::Uuid;
#[allow(dead_code)]
pub fn generate_token() -> String {
Uuid::new_v4().to_string()
}
#[allow(dead_code)]
pub fn default_expiry() -> DateTime<Utc> {
Utc::now() + Duration::days(30)
}
pub fn is_expired(expires_at: DateTime<Utc>) -> bool {
Utc::now() > expires_at
}

View File

@ -2,6 +2,7 @@
pub mod pool;
#[cfg(not(feature = "server"))]
#[allow(dead_code)]
pub mod pool {
pub struct DummyPool;
impl DummyPool {

View File

@ -1,5 +1,3 @@
use dioxus::prelude::*;
mod api;
mod auth;
mod db;

View File

@ -1,2 +1 @@
pub mod session;
pub mod user;

View File

@ -1,11 +0,0 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Session {
pub id: i32,
pub user_id: i32,
pub token: String,
pub expires_at: DateTime<Utc>,
pub created_at: DateTime<Utc>,
}

View File

@ -8,13 +8,7 @@ pub enum UserRole {
}
impl UserRole {
pub fn as_str(&self) -> &'static str {
match self {
UserRole::Admin => "admin",
UserRole::Blocked => "blocked",
}
}
#[allow(dead_code)]
pub fn from_str(s: &str) -> Option<Self> {
match s {
"admin" => Some(UserRole::Admin),

View File

@ -19,7 +19,7 @@ pub fn LoginPage() -> Element {
spawn(async move {
match login(username_val, password_val).await {
Ok(AuthResponse { success: true, token: Some(token), .. }) => {
Ok(AuthResponse { success: true, token: Some(_token), .. }) => {
// 设置 cookie (client-side, not HttpOnly but works for now)
#[cfg(target_arch = "wasm32")]
{

View File

@ -19,7 +19,7 @@ pub enum Route {
#[component]
pub fn AppRouter() -> Element {
let mut theme = use_theme();
let theme = use_theme();
let theme_class = match theme() {
Theme::Dark => "dark",
Theme::Light => "",