use crate::common::{NotetakerId, RecordingId};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Notetaker {
pub id: NotetakerId,
pub grant_id: String,
pub active: bool,
pub provider_settings: ProviderSettings,
pub transcription_settings: Option<TranscriptionSettings>,
pub summary_settings: Option<SummarySettings>,
pub webhook_url: Option<String>,
pub created_at: i64,
pub updated_at: i64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "provider", rename_all = "lowercase")]
pub enum ProviderSettings {
#[serde(rename = "google-meet")]
GoogleMeet {
auto_join: bool,
quality: RecordingQuality,
},
#[serde(rename = "microsoft-teams")]
MicrosoftTeams {
auto_join: bool,
quality: RecordingQuality,
},
Zoom {
auto_join: bool,
quality: RecordingQuality,
cloud_recording: bool,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum RecordingQuality {
Standard,
Hd,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TranscriptionSettings {
pub enabled: bool,
pub language: Option<String>,
pub speaker_identification: bool,
pub profanity_filter: Option<bool>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SummarySettings {
pub enabled: bool,
pub extract_action_items: bool,
pub extract_topics: bool,
pub extract_decisions: bool,
pub summary_length: SummaryLength,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum SummaryLength {
Brief,
Medium,
Detailed,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Recording {
pub id: RecordingId,
pub notetaker_id: NotetakerId,
pub title: String,
pub start_time: i64,
pub end_time: Option<i64>,
pub duration: Option<i64>,
pub status: RecordingStatus,
pub recording_url: Option<String>,
pub transcription: Option<Transcription>,
pub summary: Option<Summary>,
pub participants: Vec<MeetingParticipant>,
pub created_at: i64,
pub updated_at: i64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum RecordingStatus {
Recording,
Processing,
Completed,
Failed,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Transcription {
pub text: String,
pub segments: Vec<TranscriptSegment>,
pub language: String,
pub confidence: f64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TranscriptSegment {
pub text: String,
pub speaker: Option<String>,
pub start_time: f64,
pub end_time: f64,
pub confidence: f64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Summary {
pub summary: String,
pub action_items: Vec<ActionItem>,
pub topics: Vec<String>,
pub decisions: Vec<String>,
pub next_steps: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ActionItem {
pub description: String,
pub assignee: Option<String>,
pub due_date: Option<i64>,
pub priority: Option<Priority>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Priority {
High,
Medium,
Low,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct MeetingParticipant {
pub name: String,
pub email: Option<String>,
pub joined_at: i64,
pub left_at: Option<i64>,
pub speaking_time: Option<i64>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CreateNotetakerRequest {
pub provider_settings: ProviderSettings,
#[serde(skip_serializing_if = "Option::is_none")]
pub transcription_settings: Option<TranscriptionSettings>,
#[serde(skip_serializing_if = "Option::is_none")]
pub summary_settings: Option<SummarySettings>,
#[serde(skip_serializing_if = "Option::is_none")]
pub webhook_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub active: Option<bool>,
}
impl CreateNotetakerRequest {
pub fn builder(provider_settings: ProviderSettings) -> CreateNotetakerRequestBuilder {
CreateNotetakerRequestBuilder::new(provider_settings)
}
}
#[derive(Debug)]
pub struct CreateNotetakerRequestBuilder {
request: CreateNotetakerRequest,
}
impl CreateNotetakerRequestBuilder {
pub fn new(provider_settings: ProviderSettings) -> Self {
Self {
request: CreateNotetakerRequest {
provider_settings,
transcription_settings: None,
summary_settings: None,
webhook_url: None,
active: None,
},
}
}
pub fn transcription_settings(mut self, settings: TranscriptionSettings) -> Self {
self.request.transcription_settings = Some(settings);
self
}
pub fn summary_settings(mut self, settings: SummarySettings) -> Self {
self.request.summary_settings = Some(settings);
self
}
pub fn webhook_url(mut self, url: impl Into<String>) -> Self {
self.request.webhook_url = Some(url.into());
self
}
pub fn active(mut self, active: bool) -> Self {
self.request.active = Some(active);
self
}
pub fn build(self) -> CreateNotetakerRequest {
self.request
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct UpdateNotetakerRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub provider_settings: Option<ProviderSettings>,
#[serde(skip_serializing_if = "Option::is_none")]
pub transcription_settings: Option<TranscriptionSettings>,
#[serde(skip_serializing_if = "Option::is_none")]
pub summary_settings: Option<SummarySettings>,
#[serde(skip_serializing_if = "Option::is_none")]
pub webhook_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub active: Option<bool>,
}
impl UpdateNotetakerRequest {
pub fn builder() -> UpdateNotetakerRequestBuilder {
UpdateNotetakerRequestBuilder::default()
}
}
#[derive(Debug, Default)]
pub struct UpdateNotetakerRequestBuilder {
request: UpdateNotetakerRequest,
}
impl UpdateNotetakerRequestBuilder {
pub fn provider_settings(mut self, settings: ProviderSettings) -> Self {
self.request.provider_settings = Some(settings);
self
}
pub fn transcription_settings(mut self, settings: TranscriptionSettings) -> Self {
self.request.transcription_settings = Some(settings);
self
}
pub fn summary_settings(mut self, settings: SummarySettings) -> Self {
self.request.summary_settings = Some(settings);
self
}
pub fn webhook_url(mut self, url: impl Into<String>) -> Self {
self.request.webhook_url = Some(url.into());
self
}
pub fn active(mut self, active: bool) -> Self {
self.request.active = Some(active);
self
}
pub fn build(self) -> UpdateNotetakerRequest {
self.request
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_notetaker_id_creation() {
let id = NotetakerId::new("notetaker_123");
assert_eq!(id.as_str(), "notetaker_123");
}
#[test]
fn test_recording_id_creation() {
let id = RecordingId::new("rec_456");
assert_eq!(id.as_str(), "rec_456");
}
#[test]
fn test_create_notetaker_request_builder() {
let provider = ProviderSettings::GoogleMeet {
auto_join: true,
quality: RecordingQuality::Hd,
};
let transcription = TranscriptionSettings {
enabled: true,
language: Some("en-US".to_string()),
speaker_identification: true,
profanity_filter: Some(false),
};
let request = CreateNotetakerRequest::builder(provider)
.transcription_settings(transcription)
.active(true)
.build();
assert!(request.active.unwrap());
assert!(request.transcription_settings.is_some());
}
#[test]
fn test_update_notetaker_request_builder() {
let request = UpdateNotetakerRequest::builder()
.active(false)
.webhook_url("https://example.com/webhook")
.build();
assert_eq!(request.active, Some(false));
assert_eq!(
request.webhook_url,
Some("https://example.com/webhook".to_string())
);
}
#[test]
fn test_recording_status_serialization() {
let status = RecordingStatus::Processing;
let json = serde_json::to_string(&status).unwrap();
assert_eq!(json, "\"processing\"");
}
#[test]
fn test_summary_length_serialization() {
let length = SummaryLength::Brief;
let json = serde_json::to_string(&length).unwrap();
assert_eq!(json, "\"brief\"");
}
}