v0.21.0 73bf644

delete_session.go RawHistoryFolder

1package usecase
2
3import (
4	"context"
5	"errors"
6
7	"github.com/bnema/dumber/internal/domain/entity"
8	"github.com/bnema/dumber/internal/domain/repository"
9	"github.com/bnema/dumber/internal/logging"
10)
11
12// DeleteSessionUseCase errors.
13var (
14	ErrCannotDeleteCurrentSession = errors.New("cannot delete current session")
15	ErrCannotDeleteActiveSession  = errors.New("cannot delete active session")
16)
17
18// DeleteSessionUseCase handles session deletion with proper validation.
19type DeleteSessionUseCase struct {
20	stateRepo   repository.SessionStateRepository
21	sessionRepo repository.SessionRepository
22	lockDir     string
23}
24
25// NewDeleteSessionUseCase creates a new DeleteSessionUseCase.
26func NewDeleteSessionUseCase(
27	stateRepo repository.SessionStateRepository,
28	sessionRepo repository.SessionRepository,
29	lockDir string,
30) *DeleteSessionUseCase {
31	return &DeleteSessionUseCase{
32		stateRepo:   stateRepo,
33		sessionRepo: sessionRepo,
34		lockDir:     lockDir,
35	}
36}
37
38// DeleteSessionInput contains the parameters for session deletion.
39type DeleteSessionInput struct {
40	SessionID        entity.SessionID
41	CurrentSessionID entity.SessionID
42}
43
44// Execute deletes a session and its state snapshot.
45// It validates that the session is not current or active before deletion.
46func (uc *DeleteSessionUseCase) Execute(ctx context.Context, input DeleteSessionInput) error {
47	log := logging.FromContext(ctx)
48
49	// Validate not deleting current session
50	if input.SessionID == input.CurrentSessionID && input.CurrentSessionID != "" {
51		return ErrCannotDeleteCurrentSession
52	}
53
54	// Check session exists
55	session, err := uc.sessionRepo.FindByID(ctx, input.SessionID)
56	if err != nil {
57		return err
58	}
59	if session == nil {
60		return ErrSessionNotFound
61	}
62
63	// Check not active (EndedAt is nil OR has lock file)
64	if session.IsActive() || isSessionLocked(uc.lockDir, input.SessionID) {
65		return ErrCannotDeleteActiveSession
66	}
67
68	log.Info().Str("session_id", string(input.SessionID)).Msg("deleting session")
69
70	// Delete snapshot (ignore "not found" - session may not have a snapshot)
71	if uc.stateRepo != nil {
72		if err := uc.stateRepo.DeleteSnapshot(ctx, input.SessionID); err != nil {
73			log.Debug().Err(err).Msg("failed to delete session snapshot (may not exist)")
74		}
75	}
76
77	// Delete session record
78	return uc.sessionRepo.Delete(ctx, input.SessionID)
79}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close