@@ -21,6 +21,8 @@ use crate::infra::presence::{DbPresenceStore, MemoryPresenceStore, PresenceHub,
2121use crate :: infra:: task_pool:: TaskPool ;
2222use crate :: infra:: webhook:: WebhookSender ;
2323use crate :: infra:: websocket:: WsHub ;
24+ use crate :: model:: { Content , Conversation } ;
25+ use crate :: openapi:: OpenApiChatMessageForm ;
2426use 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+
608725pub 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