Files
gochat/internal/repository/note_repo.go
T

96 lines
3.2 KiB
Go

package repository
// NoteRepo provides database operations for the Note model.
// Reference: Chatwoot app/models/note.rb — scope :latest, -> { order(created_at: :desc) }
import (
"context"
"github.com/gochat/gochat/internal/model"
"gorm.io/gorm"
)
// NoteRepo handles CRUD for contact notes.
type NoteRepo struct {
db *gorm.DB
}
// NewNoteRepo creates a new NoteRepo instance.
func NewNoteRepo(db *gorm.DB) *NoteRepo {
return &NoteRepo{db: db}
}
// FindByContact returns all notes for a contact, ordered by latest first.
// Compatible with ContactService which calls this with ctx parameter.
// Reference: Chatwoot `@contact.notes.latest.includes(:user)`
func (r *NoteRepo) FindByContact(ctx context.Context, accountID, contactID uint) ([]model.Note, error) {
var notes []model.Note
err := r.db.WithContext(ctx).Where("account_id = ? AND contact_id = ?", accountID, contactID).
Order("created_at DESC").
Preload("User").
Find(&notes).Error
return notes, err
}
// Create creates a new note. Compatible with ContactService which passes ctx.
func (r *NoteRepo) Create(ctx context.Context, note *model.Note) error {
return r.db.WithContext(ctx).Create(note).Error
}
// ListByContact returns all notes for a contact, ordered by latest first.
// Reference: Chatwoot `@contact.notes.latest.includes(:user)`
func (r *NoteRepo) ListByContact(accountID, contactID uint) ([]model.Note, error) {
var notes []model.Note
err := r.db.Where("account_id = ? AND contact_id = ?", accountID, contactID).
Order("created_at DESC").
Preload("User").
Find(&notes).Error
return notes, err
}
// GetByID returns a single note by ID within the account scope.
func (r *NoteRepo) GetByID(accountID, contactID, noteID uint) (*model.Note, error) {
return r.GetByIDContext(context.Background(), accountID, contactID, noteID)
}
func (r *NoteRepo) GetByIDContext(ctx context.Context, accountID, contactID, noteID uint) (*model.Note, error) {
var note model.Note
err := r.db.WithContext(ctx).Where("account_id = ? AND contact_id = ? AND id = ?", accountID, contactID, noteID).
Preload("User").
First(&note).Error
if err != nil {
return nil, err
}
return &note, nil
}
// CreateNote creates a new note for a contact (NoteService uses this).
// BeforeCreate hook ensures account_id is set from contact if missing.
func (r *NoteRepo) CreateNote(note *model.Note) (*model.Note, error) {
if err := r.db.Create(note).Error; err != nil {
return nil, err
}
// Reload to get User association
r.db.Preload("User").First(note, note.ID)
return note, nil
}
// Update updates an existing note.
func (r *NoteRepo) Update(note *model.Note) (*model.Note, error) {
if err := r.db.Save(note).Error; err != nil {
return nil, err
}
r.db.Preload("User").First(note, note.ID)
return note, nil
}
// Delete hard-deletes a note, matching Chatwoot `@note.destroy!` for notes.
func (r *NoteRepo) Delete(accountID, contactID, noteID uint) error {
return r.DeleteContext(context.Background(), accountID, contactID, noteID)
}
func (r *NoteRepo) DeleteContext(ctx context.Context, accountID, contactID, noteID uint) error {
return r.db.WithContext(ctx).Where("account_id = ? AND contact_id = ? AND id = ?", accountID, contactID, noteID).
Unscoped().Delete(&model.Note{}).Error
}