use actix_web::{web, HttpResponse, Result}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use sqlx::{FromRow, PgPool}; use uuid::Uuid; #[derive(Debug, Deserialize)] pub struct CreateOrganizationRequest { pub name: String, pub slug: String, } #[derive(Debug, Serialize)] pub struct ApiResponse { pub data: T, pub success: bool, } // Helper functions /// Create a new organization in database pub async fn create_organization_db( db_pool: &PgPool, name: &str, slug: &str, ) -> Result { let org = sqlx::query_as!( Organization, r#" INSERT INTO organizations (org_id, name, slug, created_at) VALUES ($1, $2, $3, $4) RETURNING org_id, name, slug, created_at "#, Uuid::new_v4(), name, slug, Utc::now() ) .fetch_one(db_pool) .await?; Ok(org) } /// Get organization by ID from database pub async fn get_organization_by_id_db( db_pool: &PgPool, org_id: Uuid, ) -> Result, sqlx::Error> { let org = sqlx::query_as!( Organization, r#" SELECT org_id, name, slug, created_at FROM organizations WHERE org_id = $1 "#, org_id ) .fetch_optional(db_pool) .await?; Ok(org) } #[post("/organizations/create")] pub async fn create_organization( state: web::Data, payload: web::Json, ) -> Result { let org = create_organization_db(&state.db_pool, &payload.name, &payload.slug) .await .map_err(|e| { actix_web::error::ErrorInternalServerError(format!( "Failed to create organization: {}", e )) })?; let response = ApiResponse { data: org, success: true, }; Ok(HttpResponse::Ok().json(response)) } #[get("/organizations/{org_id}")] pub async fn get_organization( state: web::Data, path: web::Path, ) -> Result { let org_id = path.into_inner(); let org = get_organization_by_id_db(&state.db_pool, org_id) .await .map_err(|e| { actix_web::error::ErrorInternalServerError(format!("Database error: {}", e)) })?; match org { Some(org) => { let response = ApiResponse { data: org, success: true, }; Ok(HttpResponse::Ok().json(response)) } None => Ok(HttpResponse::NotFound().json(ApiResponse { data: "Organization not found", success: false, })), } } #[get("/organizations")] pub async fn list_organizations( state: web::Data, query: web::Query, ) -> Result { let orgs = get_organizations_db(&state.db_pool, query.page, query.page_size) .await .map_err(|e| { actix_web::error::ErrorInternalServerError(format!("Database error: {}", e)) })?; let response = ApiResponse { data: orgs, success: true, }; Ok(HttpResponse::Ok().json(response)) } #[put("/organizations/{org_id}")] pub async fn update_organization( state: web::Data, path: web::Path, payload: web::Json, ) -> Result { let org_id = path.into_inner(); // Implementation for update operation // Use spawn_blocking for CPU-intensive operations if needed let updated_org = web::block(move || { // Blocking database operation would go here // For async, use direct SQLx calls Ok::<_, actix_web::Error>(Organization { org_id, name: payload.name.clone(), slug: payload.slug.clone(), created_at: Utc::now(), }) }) .await? .map_err(|e: actix_web::Error| e)?; let response = ApiResponse { data: updated_org, success: true, }; Ok(HttpResponse::Ok().json(response)) }