Merge pull request #21 from KristianJBorgwarth/feat/note_save_tags

feat(tag_service): moved tag handling to ITagService
This commit is contained in:
Kristian 2026-04-12 15:37:24 +02:00 committed by GitHub
commit 1e065509f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 71 additions and 35 deletions

View file

@ -9,6 +9,7 @@ import (
"github.com/KristianJBorgwarth/dendrite.daemon/core/handlers/vault" "github.com/KristianJBorgwarth/dendrite.daemon/core/handlers/vault"
"github.com/KristianJBorgwarth/dendrite.daemon/core/logging" "github.com/KristianJBorgwarth/dendrite.daemon/core/logging"
"github.com/KristianJBorgwarth/dendrite.daemon/core/server" "github.com/KristianJBorgwarth/dendrite.daemon/core/server"
"github.com/KristianJBorgwarth/dendrite.daemon/core/services"
"github.com/KristianJBorgwarth/dendrite.daemon/persistence/repositories" "github.com/KristianJBorgwarth/dendrite.daemon/persistence/repositories"
_ "modernc.org/sqlite" _ "modernc.org/sqlite"
) )
@ -21,9 +22,10 @@ func main() {
linkRepo := repositories.NewLinkRepository() linkRepo := repositories.NewLinkRepository()
tagRepo := repositories.NewTagRepository() tagRepo := repositories.NewTagRepository()
noteRepo := repositories.NewNoteRepository() noteRepo := repositories.NewNoteRepository()
tagService := services.NewTagService(tagRepo)
server.RegisterHandler("vault/init", vault.NewInitializeHandler()) server.RegisterHandler("vault/init", vault.NewInitializeHandler())
server.RegisterHandler("note/create", note.NewCreateNoteHandler(uow, tagRepo, noteRepo)) server.RegisterHandler("note/create", note.NewCreateNoteHandler(uow, tagService, noteRepo))
server.RegisterHandler("note/save", note.NewSaveNoteHandler(uow, linkRepo, tagRepo, noteRepo)) server.RegisterHandler("note/save", note.NewSaveNoteHandler(uow, linkRepo, tagRepo, noteRepo))
server.RegisterHandler("completion/link", completion.NewCompleteLinkHandler()) server.RegisterHandler("completion/link", completion.NewCompleteLinkHandler())

View file

@ -7,7 +7,7 @@ import (
filehandling "github.com/KristianJBorgwarth/dendrite.daemon/core/file_handling" filehandling "github.com/KristianJBorgwarth/dendrite.daemon/core/file_handling"
"github.com/KristianJBorgwarth/dendrite.daemon/core/models" "github.com/KristianJBorgwarth/dendrite.daemon/core/models"
"github.com/KristianJBorgwarth/dendrite.daemon/core/utils" "github.com/KristianJBorgwarth/dendrite.daemon/core/services"
"github.com/KristianJBorgwarth/dendrite.daemon/persistence/repositories" "github.com/KristianJBorgwarth/dendrite.daemon/persistence/repositories"
"github.com/KristianJBorgwarth/dendrite.daemon/persistence/store" "github.com/KristianJBorgwarth/dendrite.daemon/persistence/store"
) )
@ -19,14 +19,14 @@ type createNoteCommand struct {
} }
type CreateNoteHandler struct { type CreateNoteHandler struct {
uow *repositories.UnitOfWork uow *repositories.UnitOfWork
tagRepo repositories.ITagRepository tagService services.ITagService
noteRepo repositories.NoteRepository noteRepo repositories.NoteRepository
} }
func NewCreateNoteHandler( func NewCreateNoteHandler(
uow *repositories.UnitOfWork, uow *repositories.UnitOfWork,
tagRepo repositories.ITagRepository, tagRepo services.ITagService,
noteRepo repositories.NoteRepository, noteRepo repositories.NoteRepository,
) *CreateNoteHandler { ) *CreateNoteHandler {
return &CreateNoteHandler{uow, tagRepo, noteRepo} return &CreateNoteHandler{uow, tagRepo, noteRepo}
@ -53,38 +53,18 @@ func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (an
defer h.uow.Rollback() defer h.uow.Rollback()
dbTags, err := h.tagRepo.GetByNames(ctx, dbCtx, template.FrontMatter.Tags) tagModels, err := h.tagService.CreateTags(ctx, dbCtx, template.FrontMatter.Tags)
if err != nil { if err != nil {
return nil, err return nil, err
} }
newTags := utils.Filter(template.FrontMatter.Tags, func(name string) bool {
for _, t := range dbTags {
if t.Name() == name {
return false
}
}
return true
})
tagModels, err := models.CreateTags(newTags)
if err != nil {
return nil, err
}
if err = h.tagRepo.Insert(ctx, dbCtx, tagModels); err != nil {
return nil, err
}
tagModels = append(tagModels, dbTags...)
note := models.CreateNote(notePath, cmd.Title, template.Slug) note := models.CreateNote(notePath, cmd.Title, template.Slug)
if err = h.noteRepo.Insert(ctx, dbCtx, note); err != nil { if err = h.noteRepo.Insert(ctx, dbCtx, note); err != nil {
return nil, err return nil, err
} }
if err = h.tagRepo.InsertNoteTags(ctx, dbCtx, note.ID(), utils.Select(tagModels, func(t *models.Tag) string { return t.ID() })); err != nil { if err = h.tagService.CreateNoteTags(ctx, dbCtx, note.ID(), tagModels); err != nil {
return nil, err return nil, err
} }

View file

@ -14,17 +14,14 @@ func NewTag(id, name string) *Tag {
} }
} }
func CreateTags(tags []string) ([]*Tag, error) { func CreateTags(tags []string) ([]*Tag) {
tagModels := make([]*Tag, len(tags)) tagModels := make([]*Tag, len(tags))
for i, tag := range tags { for i, tag := range tags {
id, err := uuid.NewV7() id, _ := uuid.NewV7()
if err != nil {
panic(err)
}
tagModels[i] = NewTag(id.String(), tag) tagModels[i] = NewTag(id.String(), tag)
} }
return tagModels, nil return tagModels
} }
func (t *Tag) ID() string { func (t *Tag) ID() string {

View file

@ -1 +1,57 @@
package services package services
import (
"context"
"github.com/KristianJBorgwarth/dendrite.daemon/core/models"
"github.com/KristianJBorgwarth/dendrite.daemon/core/utils"
"github.com/KristianJBorgwarth/dendrite.daemon/persistence"
"github.com/KristianJBorgwarth/dendrite.daemon/persistence/repositories"
)
type ITagService interface {
CreateTags(ctx context.Context, dbCtx persistence.IDbContext, names []string) ([]*models.Tag, error)
CreateNoteTags(ctx context.Context, dbCtx persistence.IDbContext, noteID string, tags []*models.Tag) error
}
type tagService struct {
tagRepo repositories.ITagRepository
}
func NewTagService(tagRepo repositories.ITagRepository) *tagService {
return &tagService{tagRepo}
}
func (s *tagService) CreateTags(ctx context.Context, dbCtx persistence.IDbContext, names []string) ([]*models.Tag, error) {
existingTags, err := s.tagRepo.GetByNames(ctx, dbCtx, names)
if err != nil {
return nil, err
}
newTags := utils.Filter(names, func(name string) bool {
for _, tag := range existingTags {
if tag.Name() == name {
return false
}
}
return true
})
newTagModels := models.CreateTags(newTags)
if err = s.tagRepo.Insert(ctx, dbCtx, newTagModels); err != nil {
return nil, err
}
tags := append(existingTags, newTagModels...)
return tags, nil
}
func(s *tagService) CreateNoteTags(ctx context.Context, dbCtx persistence.IDbContext, noteID string, tags []*models.Tag) error {
tagIds := utils.Select(tags, func(t *models.Tag) string {
return t.ID()
});
return s.tagRepo.InsertNoteTags(ctx, dbCtx, noteID, tagIds)
}

BIN
dendrite

Binary file not shown.

View file

@ -7,6 +7,7 @@ import (
"testing" "testing"
"github.com/KristianJBorgwarth/dendrite.daemon/core/handlers/note" "github.com/KristianJBorgwarth/dendrite.daemon/core/handlers/note"
"github.com/KristianJBorgwarth/dendrite.daemon/core/services"
"github.com/KristianJBorgwarth/dendrite.daemon/persistence/repositories" "github.com/KristianJBorgwarth/dendrite.daemon/persistence/repositories"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -15,7 +16,7 @@ import (
func newCreateNoteHandler() *note.CreateNoteHandler { func newCreateNoteHandler() *note.CreateNoteHandler {
return note.NewCreateNoteHandler( return note.NewCreateNoteHandler(
repositories.NewUnitOfWork(), repositories.NewUnitOfWork(),
repositories.NewTagRepository(), services.NewTagService(repositories.NewTagRepository()),
repositories.NewNoteRepository(), repositories.NewNoteRepository(),
) )
} }