1package session
2
3import (
4 "context"
5
6 "github.com/google/uuid"
7 "github.com/kujtimiihoxha/termai/internal/db"
8 "github.com/kujtimiihoxha/termai/internal/pubsub"
9)
10
11type Session struct {
12 ID string
13 Title string
14 MessageCount int64
15 PromptTokens int64
16 CompletionTokens int64
17 Cost float64
18 CreatedAt int64
19 UpdatedAt int64
20}
21
22type Service interface {
23 pubsub.Suscriber[Session]
24 Create(title string) (Session, error)
25 Get(id string) (Session, error)
26 List() ([]Session, error)
27 Save(session Session) (Session, error)
28 Delete(id string) error
29}
30
31type service struct {
32 *pubsub.Broker[Session]
33 q db.Querier
34 ctx context.Context
35}
36
37func (s *service) Create(title string) (Session, error) {
38 dbSession, err := s.q.CreateSession(s.ctx, db.CreateSessionParams{
39 ID: uuid.New().String(),
40 Title: title,
41 })
42 if err != nil {
43 return Session{}, err
44 }
45 session := s.fromDBItem(dbSession)
46 s.Publish(pubsub.CreatedEvent, session)
47 return session, nil
48}
49
50func (s *service) Delete(id string) error {
51 session, err := s.Get(id)
52 if err != nil {
53 return err
54 }
55 err = s.q.DeleteSession(s.ctx, session.ID)
56 if err != nil {
57 return err
58 }
59 s.Publish(pubsub.DeletedEvent, session)
60 return nil
61}
62
63func (s *service) Get(id string) (Session, error) {
64 dbSession, err := s.q.GetSessionByID(s.ctx, id)
65 if err != nil {
66 return Session{}, err
67 }
68 return s.fromDBItem(dbSession), nil
69}
70
71func (s *service) Save(session Session) (Session, error) {
72 dbSession, err := s.q.UpdateSession(s.ctx, db.UpdateSessionParams{
73 ID: session.ID,
74 Title: session.Title,
75 PromptTokens: session.PromptTokens,
76 CompletionTokens: session.CompletionTokens,
77 Cost: session.Cost,
78 })
79 if err != nil {
80 return Session{}, err
81 }
82 session = s.fromDBItem(dbSession)
83 s.Publish(pubsub.UpdatedEvent, session)
84 return session, nil
85}
86
87func (s *service) List() ([]Session, error) {
88 dbSessions, err := s.q.ListSessions(s.ctx)
89 if err != nil {
90 return nil, err
91 }
92 sessions := make([]Session, len(dbSessions))
93 for i, dbSession := range dbSessions {
94 sessions[i] = s.fromDBItem(dbSession)
95 }
96 return sessions, nil
97}
98
99func (s service) fromDBItem(item db.Session) Session {
100 return Session{
101 ID: item.ID,
102 Title: item.Title,
103 MessageCount: item.MessageCount,
104 PromptTokens: item.PromptTokens,
105 CompletionTokens: item.CompletionTokens,
106 Cost: item.Cost,
107 CreatedAt: item.CreatedAt,
108 UpdatedAt: item.UpdatedAt,
109 }
110}
111
112func NewService(ctx context.Context, q db.Querier) Service {
113 broker := pubsub.NewBroker[Session]()
114 return &service{
115 broker,
116 q,
117 ctx,
118 }
119}