Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- Fix TIMESTAMPTZ decode errors: add ::TEXT cast to all SELECT queries
where Row structs use String for TIMESTAMPTZ columns (~22 locations)
- Fix Axum 0.7 route params: {id} → :id in billing/knowledge/scheduled_task routes
- Fix JSONB bind: scheduled_task INSERT uses ::jsonb cast for input_payload
- Add billing_test.rs (14 tests): plans, subscription, usage, payments, invoices
- Add scheduled_task_test.rs (12 tests): CRUD, validation, isolation
- Add knowledge_test.rs (20 tests): categories, items, versions, search, analytics, permissions
- Fix auth test regression: 6 tests were failing due to TIMESTAMPTZ type mismatch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
47 lines
1.2 KiB
Rust
47 lines
1.2 KiB
Rust
//! 异步操作日志 Worker
|
|
|
|
use async_trait::async_trait;
|
|
use sqlx::PgPool;
|
|
use serde::{Serialize, Deserialize};
|
|
use crate::error::SaasResult;
|
|
use super::Worker;
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct LogOperationArgs {
|
|
pub account_id: String,
|
|
pub action: String,
|
|
pub target_type: String,
|
|
pub target_id: String,
|
|
pub details: Option<String>,
|
|
pub ip_address: Option<String>,
|
|
}
|
|
|
|
pub struct LogOperationWorker;
|
|
|
|
#[async_trait]
|
|
impl Worker for LogOperationWorker {
|
|
type Args = LogOperationArgs;
|
|
|
|
fn name(&self) -> &str {
|
|
"log_operation"
|
|
}
|
|
|
|
async fn perform(&self, db: &PgPool, args: Self::Args) -> SaasResult<()> {
|
|
let now = chrono::Utc::now();
|
|
sqlx::query(
|
|
"INSERT INTO operation_logs (account_id, action, target_type, target_id, details, ip_address, created_at)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7)"
|
|
)
|
|
.bind(&args.account_id)
|
|
.bind(&args.action)
|
|
.bind(&args.target_type)
|
|
.bind(&args.target_id)
|
|
.bind(&args.details)
|
|
.bind(&args.ip_address)
|
|
.bind(&now)
|
|
.execute(db)
|
|
.await?;
|
|
Ok(())
|
|
}
|
|
}
|