func cleanPath(path string) string {
	path = strings.Replace(path, ".", "_", -1)  
	path = strings.Replace(path, "/", ".", -1)  
	cleaned := strings.Map(func(r rune) rune {
		if unicode.IsSpace(r) || r == '-' {
			return -1
		}
		return r
	}, path)
	return cleaned
}
cleanPath removes all whitespace and hyphens from ltree paths
package document
import (
	"encoding/json"
	"fmt"
	"path/filepath"
	"strings"
	"time"
	"unicode"
	"github.com/jmoiron/sqlx"
	"github.com/lib/pq"
	"github.com/pborman/uuid"
	"github.com/pkg/errors"
)
const (
	TypeMarkdown = iota + 1
	TypePDF
	TypeUnsupported
	codeDuplicateInsert = pq.ErrorCode("23505")
	reservedFolderName = "_rootfolder_"
)
var (
	ErrDuplicateIndex = errors.New("index already exists")
	ErrDuplicateDocument = errors.New("document already exists")
)
type Type struct {
	ID      int       `json:"id" db:"document_type_id"`
	Name    string    `json:"name" db:"name"`
	Created time.Time `json:"created" db:"created"`
	Updated time.Time `json:"updated" db:"updated"`
}
type SearchResult struct {
	DocumentID   uuid.UUID `json:"id" db:"document_id"`
	SentenceID   uuid.UUID `json:"sentenceID" db:"sentence_id"`
	AnnoyID      int       `json:"annoyID" db:"annoy_id"`
	DocumentName string    `json:"name" db:"name"`
	Path         string    `json:"path" db:"path"`
	DownloadURL  string    `json:"downloadURL" db:"download_url"`
	Text         string    `json:"text" db:"sentence_text"`
	Rank         float32   `json:"rel" db:"rel"`
}
type Folder struct {
	FolderID uuid.UUID `json:"id" db:"folder_id"`
	Name     string    `json:"name" db:"name"`
	Path     string    `json:"path" db:"path"`
	Created  time.Time `json:"created" db:"created"`
	Updated  time.Time `json:"updated" db:"updated"`
}
type Document struct {
	ID               uuid.UUID `json:"id" db:"document_id"`
	FolderID         uuid.UUID `json:"folderID" db:"folder_id"`
	TypeID           int       `json:"typeID" db:"document_type_id"`
	ObjectStorageURL string    `json:"objectStorageURL" db:"object_storage_url"`
	DownloadURL      string    `json:"downloadURL" db:"download_url"`
	Path             string    `json:"path" db:"path"`
	Name             string    `json:"name" db:"name"`
	Body             string    `json:"body" db:"body"`
	Created          time.Time `json:"created" db:"created"`
	Updated          time.Time `json:"updated" db:"updated"`
}
type Sentence struct {
	ID         uuid.UUID       `db:"sentence_id"`
	DocumentID uuid.UUID       `db:"document_id"`
	StoreID    uuid.UUID       `db:"store_id"`
	AnnoyID    int             `db:"annoy_id"`
	Embedding  json.RawMessage `db:"embedding"`
	Body       string          `db:"body"`
	Context    string          `db:"context"`
	Created    time.Time       `json:"created" db:"created"`
	Updated    time.Time       `json:"updated" db:"updated"`
}
func (s *Sentence) GetEmbeddings() ([]float32, error) {
	var embeddings []float32
	if err := json.Unmarshal(s.Embedding, &embeddings); err != nil {
		return nil, errors.Wrap(err, "unmarshalling embedding")
	}
	return embeddings, nil
}
type Service struct {
	DB *sqlx.DB
}
func NewService(db *sqlx.DB) *Service {
	s := Service{
		DB: db,
	}
	return &s
}
func (s *Service) GetIndexContent() ([]Sentence, error) {
	var r []Sentence
	if err := s.DB.Select(&r, getIndexContent); err != nil {
		return nil, errors.Wrap(err, "get index content query")
	}
	return r, nil
}