116 lines
3.1 KiB
Go
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
|
|
}
|