snapshot_session.go RawHistoryFolder
1package usecase
2
3import (
4 "context"
5 "fmt"
6 "time"
7
8 "github.com/bnema/dumber/internal/domain/entity"
9 "github.com/bnema/dumber/internal/domain/repository"
10 "github.com/bnema/dumber/internal/logging"
11)
12
13// SnapshotSessionUseCase handles saving session state snapshots.
14type SnapshotSessionUseCase struct {
15 stateRepo repository.SessionStateRepository
16}
17
18// NewSnapshotSessionUseCase creates a new SnapshotSessionUseCase.
19func NewSnapshotSessionUseCase(stateRepo repository.SessionStateRepository) *SnapshotSessionUseCase {
20 return &SnapshotSessionUseCase{stateRepo: stateRepo}
21}
22
23// SnapshotInput contains the parameters for creating a session snapshot.
24type SnapshotInput struct {
25 SessionID entity.SessionID
26 TabList *entity.TabList
27
28 // v2: window-scoped snapshot. A non-nil slice, including an empty one,
29 // requests the v2 path; leave nil when using the legacy TabList path.
30 Windows []entity.WindowTabListState
31 ActiveWindowIndex int
32}
33
34// Execute creates a snapshot of the current session state and saves it.
35// When Windows is non-nil, uses the v2 window-scoped path, including explicit
36// zero-window snapshots. Otherwise falls back to the legacy flat TabList path.
37func (uc *SnapshotSessionUseCase) Execute(ctx context.Context, input SnapshotInput) error {
38 log := logging.FromContext(ctx)
39
40 if input.SessionID == "" {
41 return fmt.Errorf("session id required")
42 }
43 if input.Windows != nil && input.TabList != nil {
44 return fmt.Errorf("windows and tab list are mutually exclusive")
45 }
46
47 var state *entity.SessionState
48
49 if input.Windows != nil {
50 state = entity.SnapshotFromWindowTabLists(input.SessionID, input.Windows, input.ActiveWindowIndex, time.Now())
51 log.Debug().
52 Str("session_id", string(input.SessionID)).
53 Int("window_count", len(state.Windows)).
54 Int("active_window", state.ActiveWindowIndex).
55 Int("pane_count", state.CountPanes()).
56 Msg("creating window-scoped session snapshot")
57 } else {
58 state = entity.SnapshotFromTabList(input.SessionID, input.TabList)
59 log.Debug().
60 Str("session_id", string(input.SessionID)).
61 Int("tab_count", len(state.Tabs)).
62 Int("pane_count", state.CountPanes()).
63 Msg("creating session snapshot")
64 }
65
66 if err := uc.stateRepo.SaveSnapshot(ctx, state); err != nil {
67 return fmt.Errorf("save session snapshot: %w", err)
68 }
69
70 return nil
71}