session.go

  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}