Files
jules/engine/user/user.go
T

116 lines
3.1 KiB
Go

package user
import (
"context"
"errors"
"fmt"
"time"
"github.com/d1nch8g/jules/chat"
"github.com/d1nch8g/jules/database"
"github.com/google/uuid"
)
type User struct {
*database.User
Chats []database.Chat
Facts []database.Fact
Contacts []database.Contact
IncomingNotifications []database.Notification
OutgoingNotifications []database.Notification
RecentActions []database.Action
}
func FromMessage(ctx context.Context, db database.Database, msg chat.Message, actionLimit int) (*User, error) {
user, err := ensureUserByMessage(ctx, db, msg)
if err != nil {
return nil, fmt.Errorf("ensure user by message: %w", err)
}
return enrich(ctx, db, user, actionLimit)
}
func FromNotification(ctx context.Context, db database.Database, notif database.Notification, actionLimit int) (*User, error) {
user, err := db.Users().Get(ctx, notif.UserID, database.UserLookupByID)
if err != nil {
return nil, fmt.Errorf("get user by id: %w", err)
}
return enrich(ctx, db, user, actionLimit)
}
func enrich(ctx context.Context, db database.Database, user *database.User, actionLimit int) (*User, error) {
var enriched User
enriched.User = user
var err error
enriched.Chats, err = db.Chats().List(ctx, user.ID)
if err != nil {
return nil, fmt.Errorf("list chats: %w", err)
}
enriched.Facts, err = db.Facts().List(ctx, user.ID)
if err != nil {
return nil, fmt.Errorf("list facts: %w", err)
}
enriched.Contacts, err = db.Contacts().List(ctx, user.ID)
if err != nil {
return nil, fmt.Errorf("list contacts: %w", err)
}
enriched.IncomingNotifications, err = db.Notifications().List(ctx, user.ID)
if err != nil {
return nil, fmt.Errorf("list incoming notifications: %w", err)
}
enriched.OutgoingNotifications, err = db.Notifications().ListOutgoing(ctx, user.ID)
if err != nil {
return nil, fmt.Errorf("list outgoing notifications: %w", err)
}
enriched.RecentActions, err = db.Actions().Recent(ctx, user.ID, actionLimit)
if err != nil {
return nil, fmt.Errorf("get recent actions: %w", err)
}
return &enriched, nil
}
func ensureUserByMessage(ctx context.Context, db database.Database, msg chat.Message) (*database.User, error) {
userID, err := db.Chats().GetUserID(ctx, msg.Chat, msg.ID)
if err != nil {
if errors.Is(err, database.ErrNotFound) {
return createUserAndAttachChat(ctx, db, msg)
}
return nil, fmt.Errorf("get user id by chat: %w", err)
}
user, err := db.Users().Get(ctx, userID, database.UserLookupByID)
if err != nil {
return nil, fmt.Errorf("get user by id: %w", err)
}
return user, nil
}
func createUserAndAttachChat(ctx context.Context, db database.Database, msg chat.Message) (*database.User, error) {
user := &database.User{
ID: uuid.New(),
PreferredChat: msg.Chat,
CountUpdatedAt: time.Now(),
BindCode: uuid.New(),
ContactCode: uuid.New(),
Role: "free",
}
if err := db.Users().Create(ctx, user); err != nil {
return nil, fmt.Errorf("create user: %w", err)
}
if err := db.Chats().Attach(ctx, user.ID, msg.Chat, msg.ID); err != nil {
return nil, fmt.Errorf("attach chat: %w", err)
}
return user, nil
}