package callmemory import ( "context" "testing" ) func TestDirectStorySchedulingAfterDrainWithManagedMemory(t *testing.T) { f := setup(t) f.s.ConfigureManagedSync(func(context.Context) error { return nil }) m, _, _ := f.call(t) f.exec(t, `UPDATE call_session SET memory_mode='OFF',budget_snapshot='{"protocol":"DIRECT-CHAT-1","story_extraction_allowed":true}', ended_at=now(),call_state='ENDED',manifest_status='DISCARDED',local_audio_off=true,sdk_stopped=true, transcript_state='DRAINING',transcript_revision=1,drain_started_at=now(),last_text_at=now() WHERE id=$1::uuid`, m.SessionID) f.exec(t, `INSERT INTO call_utterance(session_id,utterance_id,source_revision,speaker,text_content,interrupted,source_at) VALUES($1::uuid,'elder-story',0,'USER','年轻时我们在河边小学教书,后来学校搬走了。',false,now())`, m.SessionID) count := func(want int) { t.Helper() var got int if err := f.p.QueryRow(context.Background(), `SELECT count(*) FROM outbox_event WHERE aggregate_id=$1::uuid AND event_type='call.story_extraction_requested'`, m.SessionID).Scan(&got); err != nil { t.Fatal(err) } if got != want { t.Fatalf("story jobs=%d want=%d", got, want) } } if err := f.s.Maintain(context.Background()); err != nil { t.Fatal(err) } count(0) f.exec(t, `UPDATE call_session SET drain_started_at=now()-interval '1 minute',last_text_at=now()-interval '1 minute' WHERE id=$1::uuid`, m.SessionID) if err := f.s.Maintain(context.Background()); err != nil { t.Fatal(err) } count(1) if err := f.s.Maintain(context.Background()); err != nil { t.Fatal(err) } count(1) f.exec(t, `UPDATE call_session SET transcript_revision=2,transcript_state='DRAINING',drain_started_at=now(),last_text_at=now() WHERE id=$1::uuid`, m.SessionID) if err := f.s.Maintain(context.Background()); err != nil { t.Fatal(err) } count(1) f.exec(t, `UPDATE call_session SET drain_started_at=now()-interval '1 minute',last_text_at=now()-interval '1 minute' WHERE id=$1::uuid`, m.SessionID) if err := f.s.Maintain(context.Background()); err != nil { t.Fatal(err) } count(2) // Frozen consent prevents historical calls from being backfilled merely // because a family grants story extraction after the call. f.exec(t, `UPDATE call_session SET transcript_revision=3,budget_snapshot=budget_snapshot-'story_extraction_allowed' WHERE id=$1::uuid`, m.SessionID) if err := f.s.Maintain(context.Background()); err != nil { t.Fatal(err) } count(2) }