fix: Schema alignment and code corrections (COA 2)
All checks were successful
Test Asgard Runner / test (push) Successful in 3s
All checks were successful
Test Asgard Runner / test (push) Successful in 3s
- Replace owner_id → owner_user_id in all queries - Replace auth_token → companion_agent_token in server_connections - Replace l.active → (l.status = 'active') checks using ENUM - Fix AppError → ApiError in all new API files - Add missing imports (Path, PanelAdapter trait) - Fix StoreConfig nullable type mismatches Resolves 122 compilation errors. Only sqlx cache generation remains. Phase 3: EXECUTE complete per V4_WORKFLOW
This commit is contained in:
@@ -10,7 +10,7 @@ use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
models::error::AppError,
|
||||
models::error::ApiError,
|
||||
services::payment_processor::PayPalProcessor,
|
||||
AppState,
|
||||
};
|
||||
@@ -35,14 +35,14 @@ struct PublicStoreInfo {
|
||||
async fn get_store_info(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path(subdomain): Path<String>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
// Get license_id from subdomain
|
||||
let license = sqlx::query!("SELECT id FROM licenses WHERE subdomain = $1", subdomain)
|
||||
.fetch_optional(&state.db)
|
||||
.await?;
|
||||
|
||||
let license_id = license
|
||||
.ok_or_else(|| AppError::NotFound("Store not found".to_string()))?
|
||||
.ok_or_else(|| ApiError::NotFound("Store not found".to_string()))?
|
||||
.id;
|
||||
|
||||
// Get store config
|
||||
@@ -58,11 +58,11 @@ async fn get_store_info(
|
||||
|
||||
if let Some(config) = config {
|
||||
if !config.enabled {
|
||||
return Err(AppError::NotFound("Store is currently disabled".to_string()));
|
||||
return Err(ApiError::NotFound("Store is currently disabled".to_string()));
|
||||
}
|
||||
Ok(Json(config))
|
||||
} else {
|
||||
Err(AppError::NotFound("Store not configured".to_string()))
|
||||
Err(ApiError::NotFound("Store not configured".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,13 +82,13 @@ struct PublicStoreItem {
|
||||
async fn get_store_items(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path(subdomain): Path<String>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license = sqlx::query!("SELECT id FROM licenses WHERE subdomain = $1", subdomain)
|
||||
.fetch_optional(&state.db)
|
||||
.await?;
|
||||
|
||||
let license_id = license
|
||||
.ok_or_else(|| AppError::NotFound("Store not found".to_string()))?
|
||||
.ok_or_else(|| ApiError::NotFound("Store not found".to_string()))?
|
||||
.id;
|
||||
|
||||
// Check if store is enabled
|
||||
@@ -98,7 +98,7 @@ async fn get_store_items(
|
||||
.unwrap_or(false);
|
||||
|
||||
if !enabled {
|
||||
return Err(AppError::NotFound("Store is currently disabled".to_string()));
|
||||
return Err(ApiError::NotFound("Store is currently disabled".to_string()));
|
||||
}
|
||||
|
||||
type Row = (
|
||||
@@ -166,13 +166,13 @@ async fn create_purchase_order(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path(subdomain): Path<String>,
|
||||
Json(req): Json<CreatePurchaseRequest>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license = sqlx::query!("SELECT id FROM licenses WHERE subdomain = $1", subdomain)
|
||||
.fetch_optional(&state.db)
|
||||
.await?;
|
||||
|
||||
let license_id = license
|
||||
.ok_or_else(|| AppError::NotFound("Store not found".to_string()))?
|
||||
.ok_or_else(|| ApiError::NotFound("Store not found".to_string()))?
|
||||
.id;
|
||||
|
||||
// Get store config and check if enabled
|
||||
@@ -184,10 +184,10 @@ async fn create_purchase_order(
|
||||
)
|
||||
.fetch_optional(&state.db)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Store not configured".to_string()))?;
|
||||
.ok_or_else(|| ApiError::NotFound("Store not configured".to_string()))?;
|
||||
|
||||
if !store_config.enabled {
|
||||
return Err(AppError::BadRequest("Store is currently disabled".to_string()));
|
||||
return Err(ApiError::BadRequest("Store is currently disabled".to_string()));
|
||||
}
|
||||
|
||||
// Get item details
|
||||
@@ -198,7 +198,7 @@ async fn create_purchase_order(
|
||||
)
|
||||
.fetch_optional(&state.db)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Item not found or disabled".to_string()))?;
|
||||
.ok_or_else(|| ApiError::NotFound("Item not found or disabled".to_string()))?;
|
||||
|
||||
// Check purchase limit if set
|
||||
if let Some(limit) = sqlx::query_scalar!(
|
||||
@@ -219,17 +219,17 @@ async fn create_purchase_order(
|
||||
.unwrap_or(0);
|
||||
|
||||
if purchase_count >= limit as i64 {
|
||||
return Err(AppError::BadRequest("Purchase limit reached for this item".to_string()));
|
||||
return Err(ApiError::BadRequest("Purchase limit reached for this item".to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
// Create PayPal processor using store owner's credentials
|
||||
let client_id = store_config.paypal_client_id.ok_or_else(|| {
|
||||
AppError::Internal("Store PayPal credentials not configured".to_string())
|
||||
ApiError::Internal("Store PayPal credentials not configured".to_string())
|
||||
})?;
|
||||
|
||||
let client_secret = store_config.paypal_client_secret.ok_or_else(|| {
|
||||
AppError::Internal("Store PayPal credentials not configured".to_string())
|
||||
ApiError::Internal("Store PayPal credentials not configured".to_string())
|
||||
})?;
|
||||
|
||||
// TODO: Decrypt client_secret using encryption service
|
||||
@@ -282,7 +282,7 @@ async fn handle_purchase_webhook(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path(subdomain): Path<String>,
|
||||
Json(webhook): Json<serde_json::Value>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
tracing::info!("Store purchase webhook for {}: {:?}", subdomain, webhook);
|
||||
|
||||
let license = sqlx::query!("SELECT id FROM licenses WHERE subdomain = $1", subdomain)
|
||||
@@ -290,7 +290,7 @@ async fn handle_purchase_webhook(
|
||||
.await?;
|
||||
|
||||
let license_id = license
|
||||
.ok_or_else(|| AppError::NotFound("Store not found".to_string()))?
|
||||
.ok_or_else(|| ApiError::NotFound("Store not found".to_string()))?
|
||||
.id;
|
||||
|
||||
// TODO: Verify webhook signature
|
||||
@@ -320,11 +320,11 @@ async fn handle_payment_completed(
|
||||
state: &AppState,
|
||||
license_id: Uuid,
|
||||
webhook: serde_json::Value,
|
||||
) -> Result<(), AppError> {
|
||||
) -> Result<(), ApiError> {
|
||||
let order_id = webhook
|
||||
.pointer("/resource/supplementary_data/related_ids/order_id")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| AppError::Internal("Missing order_id in webhook".to_string()))?;
|
||||
.ok_or_else(|| ApiError::Internal("Missing order_id in webhook".to_string()))?;
|
||||
|
||||
// Update transaction status
|
||||
let transaction = sqlx::query!(
|
||||
@@ -367,7 +367,7 @@ async fn handle_payment_completed(
|
||||
let payload = serde_json::json!({ "command": command });
|
||||
nats.publish(subject, serde_json::to_vec(&payload)?.into())
|
||||
.await
|
||||
.map_err(|e| AppError::Internal(format!("NATS publish failed: {}", e)))?;
|
||||
.map_err(|e| ApiError::Internal(format!("NATS publish failed: {}", e)))?;
|
||||
}
|
||||
|
||||
// Mark as delivered
|
||||
@@ -391,11 +391,11 @@ async fn handle_payment_failed(
|
||||
state: &AppState,
|
||||
license_id: Uuid,
|
||||
webhook: serde_json::Value,
|
||||
) -> Result<(), AppError> {
|
||||
) -> Result<(), ApiError> {
|
||||
let order_id = webhook
|
||||
.pointer("/resource/supplementary_data/related_ids/order_id")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| AppError::Internal("Missing order_id in webhook".to_string()))?;
|
||||
.ok_or_else(|| ApiError::Internal("Missing order_id in webhook".to_string()))?;
|
||||
|
||||
sqlx::query!(
|
||||
"UPDATE store_transactions SET status = 'failed' WHERE paypal_order_id = $1 AND license_id = $2",
|
||||
|
||||
Reference in New Issue
Block a user