Skip to content

Commit 9c7912e

Browse files
committed
feat: implement demo fixtures creation for chat conversations
1 parent 67b72f2 commit 9c7912e

1 file changed

Lines changed: 117 additions & 0 deletions

File tree

  • crates/restsend-backend/src/app

crates/restsend-backend/src/app/mod.rs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ use crate::infra::presence::{DbPresenceStore, MemoryPresenceStore, PresenceHub,
2121
use crate::infra::task_pool::TaskPool;
2222
use crate::infra::webhook::WebhookSender;
2323
use crate::infra::websocket::WsHub;
24+
use crate::model::{Content, Conversation};
25+
use crate::openapi::OpenApiChatMessageForm;
2426
use crate::services::{
2527
AuthService, ChatService, ConversationService, RelationService, TopicService, UserService,
2628
};
@@ -96,6 +98,12 @@ pub async fn build_router(
9698
chat_service,
9799
};
98100

101+
if config.demo {
102+
if let Err(e) = create_demo_fixtures(&state).await {
103+
tracing::warn!(error = %e, "demo fixtures creation failed");
104+
}
105+
}
106+
99107
start_webhook_worker(state.clone());
100108
state
101109
.presence_hub
@@ -605,6 +613,115 @@ async fn create_demo_accounts(db: &sea_orm::DatabaseConnection) -> Result<(), se
605613
Ok(())
606614
}
607615

616+
fn make_content(text: &str) -> Content {
617+
Content {
618+
content_type: "chat".to_string(),
619+
text: text.to_string(),
620+
..Content::default()
621+
}
622+
}
623+
624+
async fn create_demo_fixtures(state: &AppState) -> Result<(), sea_orm::DbErr> {
625+
let now = chrono::Utc::now().to_rfc3339();
626+
let dm_pairs: Vec<(&str, &str, Vec<(&str, &str)>)> = vec![
627+
(
628+
"alice",
629+
"bob",
630+
vec![
631+
("alice", "Hey Bob, how's it going?"),
632+
("bob", "Hi Alice! Doing great, thanks!"),
633+
("alice", "Want to grab lunch later?"),
634+
("bob", "Sure, sounds good!"),
635+
],
636+
),
637+
(
638+
"alice",
639+
"guido",
640+
vec![
641+
("alice", "Guido, have you seen the latest updates?"),
642+
("guido", "Yes, the new chat features look fantastic!"),
643+
("alice", "I know right? The real-time sync is amazing."),
644+
],
645+
),
646+
(
647+
"bob",
648+
"jinti",
649+
vec![
650+
("bob", "Jinti, ready for the demo?"),
651+
("jinti", "Almost ready! Just finishing up the last piece."),
652+
("bob", "Great, let me know when you're done!"),
653+
],
654+
),
655+
(
656+
"guido",
657+
"jinti",
658+
vec![
659+
("guido", "Let's collaborate on the new project"),
660+
("jinti", "Sounds great, let's do it!"),
661+
],
662+
),
663+
];
664+
665+
for (user_a, user_b, messages) in &dm_pairs {
666+
let topic_id = if user_a <= user_b {
667+
format!("{}:{}", user_a, user_b)
668+
} else {
669+
format!("{}:{}", user_b, user_a)
670+
};
671+
672+
let mut last_seq = 0i64;
673+
let mut last_msg_sender = "";
674+
let mut last_msg_text = "";
675+
676+
for (sender, text) in messages {
677+
let form = OpenApiChatMessageForm {
678+
r#type: "chat".to_string(),
679+
content: Some(make_content(text)),
680+
message: text.to_string(),
681+
chat_id: String::new(),
682+
created_at: Some(now.clone()),
683+
..OpenApiChatMessageForm::default()
684+
};
685+
match state.chat_service.send_to_user(sender, if *sender == *user_a { *user_b } else { *user_a }, &form).await {
686+
Ok(resp) => {
687+
last_seq = resp.seq;
688+
last_msg_sender = sender;
689+
last_msg_text = text;
690+
}
691+
Err(e) => {
692+
tracing::warn!(error = %e, "fixture message failed: {sender} -> {user_a}:{user_b}");
693+
}
694+
}
695+
}
696+
697+
// create conversation for both users
698+
for &owner in &[*user_a, *user_b] {
699+
let attendee = if owner == *user_a { *user_b } else { *user_a };
700+
let conv = Conversation {
701+
owner_id: owner.to_string(),
702+
topic_id: topic_id.clone(),
703+
attendee: attendee.to_string(),
704+
last_seq,
705+
last_message: Some(make_content(last_msg_text)),
706+
last_message_at: now.clone(),
707+
last_message_seq: Some(last_seq),
708+
last_sender_id: last_msg_sender.to_string(),
709+
name: attendee.to_string(),
710+
kind: "dm".to_string(),
711+
members: 2,
712+
source: "demo".to_string(),
713+
updated_at: now.clone(),
714+
..Conversation::default()
715+
};
716+
if let Err(e) = state.conversation_service.create_or_update(conv).await {
717+
tracing::warn!(error = %e, owner = %owner, topic = %topic_id, "fixture conversation failed");
718+
}
719+
}
720+
}
721+
722+
Ok(())
723+
}
724+
608725
pub fn init_tracing(config: &AppConfig) -> Option<WorkerGuard> {
609726
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
610727
let log_path = std::path::Path::new(&config.log_file);

0 commit comments

Comments
 (0)