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:
@@ -1,5 +1,5 @@
|
||||
use axum::{
|
||||
extract::{Request, State},
|
||||
extract::{Path, Request, State},
|
||||
http::StatusCode,
|
||||
middleware::{self, Next},
|
||||
response::{IntoResponse, Response},
|
||||
@@ -11,7 +11,7 @@ use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
models::error::AppError,
|
||||
models::error::ApiError,
|
||||
services::host_provisioning::{HostProvisioningService, ProvisionedLicense},
|
||||
AppState,
|
||||
};
|
||||
@@ -29,16 +29,16 @@ async fn host_auth_middleware(
|
||||
State(state): State<Arc<AppState>>,
|
||||
mut req: Request,
|
||||
next: Next,
|
||||
) -> Result<Response, AppError> {
|
||||
) -> Result<Response, ApiError> {
|
||||
// Extract API key from Authorization header (Bearer token)
|
||||
let auth_header = req
|
||||
.headers()
|
||||
.get("Authorization")
|
||||
.and_then(|h| h.to_str().ok())
|
||||
.ok_or_else(|| AppError::Unauthorized("Missing Authorization header".to_string()))?;
|
||||
.ok_or_else(|| ApiError::Unauthorized("Missing Authorization header".to_string()))?;
|
||||
|
||||
if !auth_header.starts_with("Bearer ") {
|
||||
return Err(AppError::Unauthorized("Invalid Authorization format. Use: Bearer <api_key>".to_string()));
|
||||
return Err(ApiError::Unauthorized("Invalid Authorization format. Use: Bearer <api_key>".to_string()));
|
||||
}
|
||||
|
||||
let api_key = &auth_header[7..]; // Skip "Bearer "
|
||||
@@ -48,7 +48,7 @@ async fn host_auth_middleware(
|
||||
let host_id = service
|
||||
.authenticate_host(api_key)
|
||||
.await
|
||||
.map_err(|_| AppError::Unauthorized("Invalid or inactive API key".to_string()))?;
|
||||
.map_err(|_| ApiError::Unauthorized("Invalid or inactive API key".to_string()))?;
|
||||
|
||||
// Store host_id in request extensions for handlers to access
|
||||
req.extensions_mut().insert(HostContext { host_id });
|
||||
@@ -87,7 +87,7 @@ async fn provision_license(
|
||||
State(state): State<Arc<AppState>>,
|
||||
axum::extract::Extension(ctx): axum::extract::Extension<HostContext>,
|
||||
Json(req): Json<ProvisionRequest>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let service = HostProvisioningService::new(state.db.clone());
|
||||
|
||||
// Use hostname if provided, otherwise use server_id
|
||||
@@ -125,13 +125,13 @@ struct HostLicenseInfo {
|
||||
async fn list_host_licenses(
|
||||
State(state): State<Arc<AppState>>,
|
||||
axum::extract::Extension(ctx): axum::extract::Extension<HostContext>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let licenses = sqlx::query!(
|
||||
"SELECT
|
||||
l.license_key,
|
||||
l.server_name,
|
||||
l.subdomain,
|
||||
l.active,
|
||||
(l.status = 'active') as \"active!\",
|
||||
hl.customer_email,
|
||||
hl.last_seen_at,
|
||||
hl.provisioned_at
|
||||
@@ -187,10 +187,10 @@ async fn get_billing_report(
|
||||
State(state): State<Arc<AppState>>,
|
||||
axum::extract::Extension(ctx): axum::extract::Extension<HostContext>,
|
||||
Path(month): axum::extract::Path<String>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
// Parse month (format: YYYY-MM)
|
||||
let billing_month = chrono::NaiveDate::parse_from_str(&format!("{}-01", month), "%Y-%m-%d")
|
||||
.map_err(|_| AppError::BadRequest("Invalid month format. Use YYYY-MM (e.g., 2026-02)".to_string()))?;
|
||||
.map_err(|_| ApiError::BadRequest("Invalid month format. Use YYYY-MM (e.g., 2026-02)".to_string()))?;
|
||||
|
||||
// Get billing record
|
||||
let record = sqlx::query!(
|
||||
@@ -223,7 +223,7 @@ async fn get_billing_report(
|
||||
"SELECT
|
||||
l.license_key,
|
||||
l.server_name,
|
||||
l.active,
|
||||
(l.status = 'active') as \"active!\",
|
||||
hl.customer_email,
|
||||
hl.last_seen_at
|
||||
FROM host_licenses hl
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -11,7 +11,7 @@ use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
middleware::jwt::Claims,
|
||||
models::error::AppError,
|
||||
models::error::ApiError,
|
||||
services::subscription_processor::{SubscriptionProcessor, SubscriptionDetails},
|
||||
AppState,
|
||||
};
|
||||
@@ -59,10 +59,10 @@ async fn create_subscription(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
Json(req): Json<CreateSubscriptionRequest>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
// Get license_id from JWT claims
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
// Check if subscription already exists
|
||||
@@ -74,16 +74,16 @@ async fn create_subscription(
|
||||
.await?;
|
||||
|
||||
if existing.is_some() {
|
||||
return Err(AppError::BadRequest(
|
||||
return Err(ApiError::BadRequest(
|
||||
"You already have an active webstore subscription".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
// Get PayPal credentials from env
|
||||
let client_id = std::env::var("PAYPAL_CLIENT_ID")
|
||||
.map_err(|_| AppError::Internal("PayPal credentials not configured".to_string()))?;
|
||||
.map_err(|_| ApiError::Internal("PayPal credentials not configured".to_string()))?;
|
||||
let client_secret = std::env::var("PAYPAL_CLIENT_SECRET")
|
||||
.map_err(|_| AppError::Internal("PayPal credentials not configured".to_string()))?;
|
||||
.map_err(|_| ApiError::Internal("PayPal credentials not configured".to_string()))?;
|
||||
let sandbox_mode = std::env::var("PAYPAL_SANDBOX")
|
||||
.unwrap_or_else(|_| "true".to_string())
|
||||
.parse()
|
||||
@@ -114,9 +114,9 @@ struct SubscriptionStatusResponse {
|
||||
async fn get_subscription_status(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
let subscription = sqlx::query!(
|
||||
@@ -179,9 +179,9 @@ async fn cancel_subscription(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
Json(req): Json<CancelSubscriptionRequest>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
let subscription = sqlx::query!(
|
||||
@@ -195,13 +195,13 @@ async fn cancel_subscription(
|
||||
.await?;
|
||||
|
||||
let subscription = subscription.ok_or_else(|| {
|
||||
AppError::NotFound("No active subscription found".to_string())
|
||||
ApiError::NotFound("No active subscription found".to_string())
|
||||
})?;
|
||||
|
||||
let client_id = std::env::var("PAYPAL_CLIENT_ID")
|
||||
.map_err(|_| AppError::Internal("PayPal credentials not configured".to_string()))?;
|
||||
.map_err(|_| ApiError::Internal("PayPal credentials not configured".to_string()))?;
|
||||
let client_secret = std::env::var("PAYPAL_CLIENT_SECRET")
|
||||
.map_err(|_| AppError::Internal("PayPal credentials not configured".to_string()))?;
|
||||
.map_err(|_| ApiError::Internal("PayPal credentials not configured".to_string()))?;
|
||||
let sandbox_mode = std::env::var("PAYPAL_SANDBOX")
|
||||
.unwrap_or_else(|_| "true".to_string())
|
||||
.parse()
|
||||
@@ -233,7 +233,7 @@ async fn cancel_subscription(
|
||||
async fn handle_subscription_webhook(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Json(event): Json<serde_json::Value>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
// TODO: Verify webhook signature using PayPal webhook ID
|
||||
// For now, just log and process
|
||||
|
||||
@@ -270,18 +270,18 @@ async fn handle_subscription_webhook(
|
||||
struct StoreConfig {
|
||||
store_name: String,
|
||||
description: Option<String>,
|
||||
currency: String,
|
||||
currency: Option<String>,
|
||||
paypal_client_id: Option<String>,
|
||||
sandbox_mode: bool,
|
||||
enabled: bool,
|
||||
sandbox_mode: Option<bool>,
|
||||
enabled: Option<bool>,
|
||||
}
|
||||
|
||||
async fn get_store_config(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
let config = sqlx::query_as!(
|
||||
@@ -313,9 +313,9 @@ async fn update_store_config(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
Json(config): Json<StoreConfig>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
// Upsert store config
|
||||
@@ -362,9 +362,9 @@ struct StoreCategory {
|
||||
async fn list_categories(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
let categories = sqlx::query_as!(
|
||||
@@ -394,9 +394,9 @@ async fn create_category(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
Json(req): Json<CreateCategoryRequest>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
let id = sqlx::query_scalar!(
|
||||
@@ -421,9 +421,9 @@ async fn update_category(
|
||||
claims: Claims,
|
||||
Path(id): Path<Uuid>,
|
||||
Json(req): Json<CreateCategoryRequest>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
let result = sqlx::query!(
|
||||
@@ -442,7 +442,7 @@ async fn update_category(
|
||||
.await?;
|
||||
|
||||
if result.rows_affected() == 0 {
|
||||
return Err(AppError::NotFound("Category not found".to_string()));
|
||||
return Err(ApiError::NotFound("Category not found".to_string()));
|
||||
}
|
||||
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
@@ -452,9 +452,9 @@ async fn delete_category(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
Path(id): Path<Uuid>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
let result = sqlx::query!(
|
||||
@@ -466,7 +466,7 @@ async fn delete_category(
|
||||
.await?;
|
||||
|
||||
if result.rows_affected() == 0 {
|
||||
return Err(AppError::NotFound("Category not found".to_string()));
|
||||
return Err(ApiError::NotFound("Category not found".to_string()));
|
||||
}
|
||||
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
@@ -493,9 +493,9 @@ struct StoreItem {
|
||||
async fn list_items(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
let items = sqlx::query_as!(
|
||||
@@ -529,9 +529,9 @@ async fn create_item(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
Json(req): Json<CreateItemRequest>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
let id = sqlx::query_scalar!(
|
||||
@@ -560,9 +560,9 @@ async fn update_item(
|
||||
claims: Claims,
|
||||
Path(id): Path<Uuid>,
|
||||
Json(req): Json<CreateItemRequest>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
let result = sqlx::query!(
|
||||
@@ -585,7 +585,7 @@ async fn update_item(
|
||||
.await?;
|
||||
|
||||
if result.rows_affected() == 0 {
|
||||
return Err(AppError::NotFound("Item not found".to_string()));
|
||||
return Err(ApiError::NotFound("Item not found".to_string()));
|
||||
}
|
||||
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
@@ -595,9 +595,9 @@ async fn delete_item(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
Path(id): Path<Uuid>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
let result = sqlx::query!(
|
||||
@@ -609,7 +609,7 @@ async fn delete_item(
|
||||
.await?;
|
||||
|
||||
if result.rows_affected() == 0 {
|
||||
return Err(AppError::NotFound("Item not found".to_string()));
|
||||
return Err(ApiError::NotFound("Item not found".to_string()));
|
||||
}
|
||||
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
@@ -638,9 +638,9 @@ struct StoreTransaction {
|
||||
async fn list_transactions(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let license_id = claims.license_id.ok_or_else(|| {
|
||||
AppError::Unauthorized("No license associated with this account".to_string())
|
||||
ApiError::Unauthorized("No license associated with this account".to_string())
|
||||
})?;
|
||||
|
||||
let transactions = sqlx::query_as!(
|
||||
|
||||
@@ -52,7 +52,7 @@ impl HostProvisioningService {
|
||||
|
||||
// Create license
|
||||
let license_id = sqlx::query_scalar!(
|
||||
"INSERT INTO licenses (license_key, owner_id, server_name, subdomain)
|
||||
"INSERT INTO licenses (license_key, owner_user_id, server_name, subdomain)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id",
|
||||
license_key,
|
||||
@@ -79,9 +79,9 @@ impl HostProvisioningService {
|
||||
|
||||
// Store companion token
|
||||
sqlx::query!(
|
||||
"INSERT INTO server_connections (license_id, connection_type, auth_token)
|
||||
"INSERT INTO server_connections (license_id, connection_type, companion_agent_token)
|
||||
VALUES ($1, 'bare_metal', $2)
|
||||
ON CONFLICT (license_id) DO UPDATE SET auth_token = $2",
|
||||
ON CONFLICT (license_id) DO UPDATE SET companion_agent_token = $2",
|
||||
license_id,
|
||||
companion_token
|
||||
)
|
||||
@@ -150,7 +150,7 @@ impl HostProvisioningService {
|
||||
let count = sqlx::query_scalar!(
|
||||
"SELECT COUNT(*) FROM host_licenses hl
|
||||
INNER JOIN licenses l ON l.id = hl.license_id
|
||||
WHERE hl.host_id = $1 AND l.active = true",
|
||||
WHERE hl.host_id = $1 AND l.status = 'active'",
|
||||
host_id
|
||||
)
|
||||
.fetch_one(&self.db)
|
||||
|
||||
@@ -6,6 +6,7 @@ use uuid::Uuid;
|
||||
use super::amp_adapter::AmpAdapter;
|
||||
use super::encryption;
|
||||
use super::nats_bridge::NatsBridge;
|
||||
use super::panel_adapter::PanelAdapter;
|
||||
use super::pterodactyl_adapter::PterodactylAdapter;
|
||||
|
||||
/// Default timeout for module installation operations (60 seconds).
|
||||
|
||||
Reference in New Issue
Block a user