Add document saved

This commit is contained in:
Aditya Siregar
2025-08-29 16:10:05 +07:00
parent 592fa97be7
commit 2bdce63852
33 changed files with 2862 additions and 132 deletions
+218
View File
@@ -0,0 +1,218 @@
package repository
import (
"context"
"eslogad-be/internal/entities"
"github.com/google/uuid"
"gorm.io/gorm"
)
// DocumentSessionRepository handles document session operations
type DocumentSessionRepository struct {
db *gorm.DB
}
func NewDocumentSessionRepository(db *gorm.DB) *DocumentSessionRepository {
return &DocumentSessionRepository{db: db}
}
func (r *DocumentSessionRepository) Create(ctx context.Context, session *entities.DocumentSession) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Create(session).Error
}
func (r *DocumentSessionRepository) GetByKey(ctx context.Context, documentKey string) (*entities.DocumentSession, error) {
db := DBFromContext(ctx, r.db)
var session entities.DocumentSession
err := db.WithContext(ctx).
Preload("User").
Where("document_key = ?", documentKey).
First(&session).Error
if err != nil {
return nil, err
}
return &session, nil
}
func (r *DocumentSessionRepository) GetActiveByDocument(ctx context.Context, documentID uuid.UUID) (*entities.DocumentSession, error) {
db := DBFromContext(ctx, r.db)
var session entities.DocumentSession
err := db.WithContext(ctx).
Preload("User").
Where("document_id = ? AND status != 4", documentID). // Status 4 = closed
Order("created_at DESC").
First(&session).Error
if err != nil {
return nil, err
}
return &session, nil
}
func (r *DocumentSessionRepository) Update(ctx context.Context, session *entities.DocumentSession) error {
db := DBFromContext(ctx, r.db)
// Only update specific fields to avoid association issues
updates := map[string]interface{}{
"status": session.Status,
"is_locked": session.IsLocked,
"locked_by": session.LockedBy,
"locked_at": session.LockedAt,
"last_saved_at": session.LastSavedAt,
"version": session.Version,
"updated_at": session.UpdatedAt,
}
return db.WithContext(ctx).Model(&entities.DocumentSession{}).Where("id = ?", session.ID).Updates(updates).Error
}
func (r *DocumentSessionRepository) ListByDocument(ctx context.Context, documentID uuid.UUID) ([]entities.DocumentSession, error) {
db := DBFromContext(ctx, r.db)
var sessions []entities.DocumentSession
err := db.WithContext(ctx).
Preload("User").
Where("document_id = ?", documentID).
Order("created_at DESC").
Find(&sessions).Error
return sessions, err
}
// DocumentVersionRepository handles document version operations
type DocumentVersionRepository struct {
db *gorm.DB
}
func NewDocumentVersionRepository(db *gorm.DB) *DocumentVersionRepository {
return &DocumentVersionRepository{db: db}
}
func (r *DocumentVersionRepository) Create(ctx context.Context, version *entities.DocumentVersion) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Create(version).Error
}
func (r *DocumentVersionRepository) GetByID(ctx context.Context, id uuid.UUID) (*entities.DocumentVersion, error) {
db := DBFromContext(ctx, r.db)
var version entities.DocumentVersion
err := db.WithContext(ctx).
Preload("User").
Where("id = ?", id).
First(&version).Error
if err != nil {
return nil, err
}
return &version, nil
}
func (r *DocumentVersionRepository) GetActiveVersion(ctx context.Context, documentID uuid.UUID) (*entities.DocumentVersion, error) {
db := DBFromContext(ctx, r.db)
var version entities.DocumentVersion
err := db.WithContext(ctx).
Preload("User").
Where("document_id = ? AND is_active = ?", documentID, true).
First(&version).Error
if err != nil {
return nil, err
}
return &version, nil
}
func (r *DocumentVersionRepository) ListByDocument(ctx context.Context, documentID uuid.UUID) ([]entities.DocumentVersion, error) {
db := DBFromContext(ctx, r.db)
var versions []entities.DocumentVersion
err := db.WithContext(ctx).
Preload("User").
Where("document_id = ?", documentID).
Order("version DESC").
Find(&versions).Error
return versions, err
}
func (r *DocumentVersionRepository) DeactivateAllVersions(ctx context.Context, documentID uuid.UUID) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).
Model(&entities.DocumentVersion{}).
Where("document_id = ?", documentID).
Update("is_active", false).Error
}
// DocumentMetadataRepository handles document metadata operations
type DocumentMetadataRepository struct {
db *gorm.DB
}
func NewDocumentMetadataRepository(db *gorm.DB) *DocumentMetadataRepository {
return &DocumentMetadataRepository{db: db}
}
func (r *DocumentMetadataRepository) Create(ctx context.Context, metadata *entities.DocumentMetadata) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Create(metadata).Error
}
func (r *DocumentMetadataRepository) GetByDocumentID(ctx context.Context, documentID uuid.UUID) (*entities.DocumentMetadata, error) {
db := DBFromContext(ctx, r.db)
var metadata entities.DocumentMetadata
err := db.WithContext(ctx).
Where("document_id = ?", documentID).
First(&metadata).Error
if err != nil {
return nil, err
}
return &metadata, nil
}
func (r *DocumentMetadataRepository) Update(ctx context.Context, metadata *entities.DocumentMetadata) error {
db := DBFromContext(ctx, r.db)
// Only update specific fields to avoid association issues
updates := map[string]interface{}{
"document_type": metadata.DocumentType,
"reference_id": metadata.ReferenceID,
"file_name": metadata.FileName,
"file_type": metadata.FileType,
"file_size": metadata.FileSize,
"mime_type": metadata.MimeType,
"updated_at": metadata.UpdatedAt,
}
return db.WithContext(ctx).Model(&entities.DocumentMetadata{}).Where("id = ?", metadata.ID).Updates(updates).Error
}
func (r *DocumentMetadataRepository) Delete(ctx context.Context, documentID uuid.UUID) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).
Where("document_id = ?", documentID).
Delete(&entities.DocumentMetadata{}).Error
}
// DocumentErrorRepository handles document error logging
type DocumentErrorRepository struct {
db *gorm.DB
}
func NewDocumentErrorRepository(db *gorm.DB) *DocumentErrorRepository {
return &DocumentErrorRepository{db: db}
}
func (r *DocumentErrorRepository) Create(ctx context.Context, docError *entities.DocumentError) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Create(docError).Error
}
func (r *DocumentErrorRepository) ListByDocument(ctx context.Context, documentID uuid.UUID) ([]entities.DocumentError, error) {
db := DBFromContext(ctx, r.db)
var errors []entities.DocumentError
err := db.WithContext(ctx).
Preload("Session").
Where("document_id = ?", documentID).
Order("created_at DESC").
Find(&errors).Error
return errors, err
}
func (r *DocumentErrorRepository) ListBySession(ctx context.Context, sessionID uuid.UUID) ([]entities.DocumentError, error) {
db := DBFromContext(ctx, r.db)
var errors []entities.DocumentError
err := db.WithContext(ctx).
Where("session_id = ?", sessionID).
Order("created_at DESC").
Find(&errors).Error
return errors, err
}
@@ -51,6 +51,26 @@ func (r *LetterOutgoingRepository) SoftDelete(ctx context.Context, id uuid.UUID)
return db.WithContext(ctx).Model(&entities.LetterOutgoing{}).Where("id = ? AND deleted_at IS NULL", id).Update("deleted_at", now).Error
}
func (r *LetterOutgoingRepository) GetWithRelations(ctx context.Context, id uuid.UUID, relations []string) (*entities.LetterOutgoing, error) {
db := DBFromContext(ctx, r.db)
query := db.WithContext(ctx).Where("id = ? AND deleted_at IS NULL", id)
// Preload all specified relations
for _, relation := range relations {
query = query.Preload(relation)
}
var e entities.LetterOutgoing
if err := query.First(&e).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, gorm.ErrRecordNotFound
}
return nil, err
}
return &e, nil
}
type ListOutgoingLettersFilter struct {
Status *string
Query *string
@@ -167,7 +187,12 @@ func (r *LetterOutgoingRecipientRepository) CreateBulk(ctx context.Context, list
func (r *LetterOutgoingRecipientRepository) ListByLetter(ctx context.Context, letterID uuid.UUID) ([]entities.LetterOutgoingRecipient, error) {
db := DBFromContext(ctx, r.db)
var list []entities.LetterOutgoingRecipient
if err := db.WithContext(ctx).Where("letter_id = ?", letterID).Order("is_primary DESC, created_at ASC").Find(&list).Error; err != nil {
if err := db.WithContext(ctx).
Preload("User").
Preload("Department").
Where("letter_id = ?", letterID).
Order("is_primary DESC, created_at ASC").
Find(&list).Error; err != nil {
return nil, err
}
return list, nil
+37 -5
View File
@@ -40,26 +40,33 @@ func (r *LetterIncomingRepository) SoftDelete(ctx context.Context, id uuid.UUID)
}
type ListIncomingLettersFilter struct {
Status *string
Query *string
Status *string
Query *string
DepartmentID *uuid.UUID
}
func (r *LetterIncomingRepository) List(ctx context.Context, filter ListIncomingLettersFilter, limit, offset int) ([]entities.LetterIncoming, int64, error) {
db := DBFromContext(ctx, r.db)
query := db.WithContext(ctx).Model(&entities.LetterIncoming{}).Where("deleted_at IS NULL")
if filter.DepartmentID != nil {
query = query.Joins("JOIN letter_incoming_recipients ON letter_incoming_recipients.letter_id = letters_incoming.id").
Where("letter_incoming_recipients.recipient_department_id = ?", *filter.DepartmentID)
}
if filter.Status != nil {
query = query.Where("status = ?", *filter.Status)
query = query.Where("letters_incoming.status = ?", *filter.Status)
}
if filter.Query != nil {
q := "%" + *filter.Query + "%"
query = query.Where("subject ILIKE ? OR reference_number ILIKE ?", q, q)
query = query.Where("letters_incoming.subject ILIKE ? OR letters_incoming.reference_number ILIKE ?", q, q)
}
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
var list []entities.LetterIncoming
if err := query.Order("created_at DESC").Limit(limit).Offset(offset).Find(&list).Error; err != nil {
if err := query.Order("letters_incoming.created_at DESC").Limit(limit).Offset(offset).Find(&list).Error; err != nil {
return nil, 0, err
}
return list, total, nil
@@ -289,3 +296,28 @@ func (r *LetterIncomingRecipientRepository) CreateBulk(ctx context.Context, recs
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Create(&recs).Error
}
func (r *LetterIncomingRecipientRepository) GetLetterIDsByDepartment(ctx context.Context, departmentID uuid.UUID) ([]uuid.UUID, error) {
db := DBFromContext(ctx, r.db)
var letterIDs []uuid.UUID
if err := db.WithContext(ctx).
Model(&entities.LetterIncomingRecipient{}).
Where("recipient_department_id = ?", departmentID).
Distinct("letter_id").
Pluck("letter_id", &letterIDs).Error; err != nil {
return nil, err
}
return letterIDs, nil
}
func (r *LetterIncomingRecipientRepository) HasDepartmentAccess(ctx context.Context, letterID uuid.UUID, departmentID uuid.UUID) (bool, error) {
db := DBFromContext(ctx, r.db)
var count int64
if err := db.WithContext(ctx).
Model(&entities.LetterIncomingRecipient{}).
Where("letter_id = ? AND recipient_department_id = ?", letterID, departmentID).
Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}