102 lines
2.7 KiB
Go
102 lines
2.7 KiB
Go
package ai
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"path"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
|
|
"github.com/ultisuite/ulti-backend/internal/nextcloud"
|
|
)
|
|
|
|
type ChatStore struct {
|
|
nc *nextcloud.Client
|
|
db *pgxpool.Pool
|
|
}
|
|
|
|
func NewChatStore(nc *nextcloud.Client, db *pgxpool.Pool) *ChatStore {
|
|
return &ChatStore{nc: nc, db: db}
|
|
}
|
|
|
|
func (s *ChatStore) Sync(ctx context.Context, userEmail string, record ChatRecord) error {
|
|
if s == nil || s.nc == nil {
|
|
return fmt.Errorf("nextcloud unavailable")
|
|
}
|
|
policy, _ := LoadAssistantPolicy(ctx, s.db)
|
|
basePath := policy.ChatNCPath
|
|
if strings.TrimSpace(basePath) == "" {
|
|
basePath = nextcloud.DefaultChatNCBasePath
|
|
}
|
|
if strings.TrimSpace(record.ID) == "" {
|
|
return fmt.Errorf("chat id required")
|
|
}
|
|
if record.UpdatedAt.IsZero() {
|
|
record.UpdatedAt = time.Now().UTC()
|
|
}
|
|
if record.CreatedAt.IsZero() {
|
|
record.CreatedAt = record.UpdatedAt
|
|
}
|
|
if strings.TrimSpace(record.Source) == "" {
|
|
record.Source = "openwebui"
|
|
}
|
|
|
|
userID := nextcloud.UserIDFromClaims(userEmail, "")
|
|
sidecarPath := nextcloud.ChatSidecarPath(basePath, record.ID)
|
|
dir := path.Dir(sidecarPath)
|
|
if dir != "/" && dir != "." {
|
|
_ = s.nc.CreateFolder(ctx, userID, dir)
|
|
}
|
|
|
|
payload, err := json.MarshalIndent(record, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return s.nc.Upload(ctx, userID, sidecarPath, strings.NewReader(string(payload)), "application/json")
|
|
}
|
|
|
|
func (s *ChatStore) Get(ctx context.Context, userEmail, chatID string) (ChatRecord, error) {
|
|
if s == nil || s.nc == nil {
|
|
return ChatRecord{}, fmt.Errorf("nextcloud unavailable")
|
|
}
|
|
policy, _ := LoadAssistantPolicy(ctx, s.db)
|
|
basePath := policy.ChatNCPath
|
|
if strings.TrimSpace(basePath) == "" {
|
|
basePath = nextcloud.DefaultChatNCBasePath
|
|
}
|
|
userID := nextcloud.UserIDFromClaims(userEmail, "")
|
|
sidecarPath := nextcloud.ChatSidecarPath(basePath, chatID)
|
|
body, _, err := s.nc.Download(ctx, userID, sidecarPath)
|
|
if err != nil {
|
|
return ChatRecord{}, err
|
|
}
|
|
defer body.Close()
|
|
raw, err := io.ReadAll(io.LimitReader(body, 8<<20))
|
|
if err != nil {
|
|
return ChatRecord{}, err
|
|
}
|
|
var record ChatRecord
|
|
if err := json.Unmarshal(raw, &record); err != nil {
|
|
return ChatRecord{}, err
|
|
}
|
|
return record, nil
|
|
}
|
|
|
|
func (s *ChatStore) Delete(ctx context.Context, userEmail, chatID string) error {
|
|
if s == nil || s.nc == nil {
|
|
return fmt.Errorf("nextcloud unavailable")
|
|
}
|
|
policy, _ := LoadAssistantPolicy(ctx, s.db)
|
|
basePath := policy.ChatNCPath
|
|
if strings.TrimSpace(basePath) == "" {
|
|
basePath = nextcloud.DefaultChatNCBasePath
|
|
}
|
|
userID := nextcloud.UserIDFromClaims(userEmail, "")
|
|
sidecarPath := nextcloud.ChatSidecarPath(basePath, chatID)
|
|
return s.nc.Delete(ctx, userID, sidecarPath)
|
|
}
|