use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum CommunitySearchModeDto {
ByEntities { entity_ids: Vec<String> },
ByImpact,
ByLevel { level: u32 },
ByKeyword { keyword: String },
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct CommunityDetectionConfigDto {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub min_community_size: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_levels: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub resolution: Option<f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommunityReportDto {
pub id: String,
pub impact_score: f64,
#[serde(default)]
pub key_findings: Vec<String>,
pub summary: String,
pub title: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommunityReportSummaryDto {
pub impact_score: f64,
pub summary: String,
pub title: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommunityDto {
pub id: String,
pub level: u32,
pub member_count: u64,
#[serde(default)]
pub member_ids: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub report: Option<CommunityReportDto>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct CommunityDetectionStatsDto {
pub avg_community_size: f64,
pub communities_detected: u64,
pub edges_in_graph: u64,
pub max_community_size: u64,
pub processing_time_ms: u64,
pub reports_generated: u64,
pub singleton_terms: u64,
pub terms_in_communities: u64,
pub terms_processed: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MembershipDto {
pub community_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub community_title: Option<String>,
pub degree: f64,
pub level: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommunityMatchDto {
pub community_id: String,
pub level: u32,
pub member_count: u64,
pub relevance_score: f64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub report_summary: Option<CommunityReportSummaryDto>,
#[serde(default)]
pub sample_member_ids: Vec<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct CommunitySearchStatsDto {
pub communities_searched: u64,
pub matches_found: u64,
pub search_time_ms: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DetectCommunitiesRequest {
pub tenant_id: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub term_ids: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub config: Option<CommunityDetectionConfigDto>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct DetectCommunitiesResponse {
pub success: bool,
#[serde(default)]
pub stats: CommunityDetectionStatsDto,
#[serde(default)]
pub communities: Vec<CommunityDto>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GetMembershipsRequest {
pub term_id: String,
pub tenant_id: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct GetMembershipsResponse {
pub term_id: String,
#[serde(default)]
pub memberships: Vec<MembershipDto>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchCommunitiesRequest {
pub tenant_id: String,
pub search_mode: CommunitySearchModeDto,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_results: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub min_impact_score: Option<f64>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct SearchCommunitiesResponse {
#[serde(default)]
pub communities: Vec<CommunityMatchDto>,
#[serde(default)]
pub stats: CommunitySearchStatsDto,
}