nxtgauge-ai-assistant/src/tickets/service.rs

66 lines
2 KiB
Rust

use std::sync::Arc;
use crate::{
db::{repository::store_ticket_audit, Database},
error::AppError,
providers::tickets::ticket_provider::{TicketCreatePayload, TicketProvider},
tickets::models::{CreateTicketRequest, CreateTicketResponse},
};
#[derive(Clone)]
pub struct TicketService {
provider: Arc<dyn TicketProvider>,
db: Database,
}
impl TicketService {
pub fn new(provider: Arc<dyn TicketProvider>, db: Database) -> Self {
Self { provider, db }
}
pub async fn create(
&self,
request: CreateTicketRequest,
) -> Result<CreateTicketResponse, AppError> {
validate_payload(&request)?;
let payload = TicketCreatePayload {
subject: request.subject.clone(),
description: request.description.clone(),
priority: request.priority.clone(),
category: request.category.clone(),
user_id: request.user_id.clone(),
conversation_id: request.conversation_id.clone(),
source: request.source.clone(),
tags: request.tags.clone(),
metadata: request.metadata.clone(),
};
let created = self.provider.create_ticket(payload).await?;
store_ticket_audit(&self.db, &request, &created.ticket_id).await?;
Ok(CreateTicketResponse {
ticket_id: created.ticket_id,
status: created.status,
provider: created.provider,
})
}
}
fn validate_payload(request: &CreateTicketRequest) -> Result<(), AppError> {
let required = [
("subject", request.subject.trim()),
("description", request.description.trim()),
("priority", request.priority.trim()),
("category", request.category.trim()),
("user_id", request.user_id.trim()),
];
if let Some((field, _)) = required.into_iter().find(|(_, value)| value.is_empty()) {
return Err(AppError::BadRequest(format!(
"missing required field: {field}"
)));
}
Ok(())
}