Fix backend API parity: document filters, task days param, i18n locales, contract tests
- Add document list filter support (residence, type, category, contractor, is_active, expiring_soon, search) to handler/service/repo - Add `days` query param parsing to ListTasks handler (matches ListTasksByResidence) - Add `error.invalid_token` i18n key to all 9 non-English locale files - Update contract test to include VerificationResponse mapping Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,18 @@ import (
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
)
|
||||
|
||||
// DocumentFilter contains optional filter parameters for listing documents.
|
||||
type DocumentFilter struct {
|
||||
ResidenceID *uint
|
||||
DocumentType string
|
||||
Category string
|
||||
ContractorID *uint
|
||||
IsActive *bool
|
||||
ExpiringSoon *int
|
||||
Tags string
|
||||
Search string
|
||||
}
|
||||
|
||||
// DocumentRepository handles database operations for documents
|
||||
type DocumentRepository struct {
|
||||
db *gorm.DB
|
||||
@@ -55,6 +67,45 @@ func (r *DocumentRepository) FindByUser(residenceIDs []uint) ([]models.Document,
|
||||
return documents, err
|
||||
}
|
||||
|
||||
// FindByUserFiltered finds documents accessible to a user with optional filters.
|
||||
func (r *DocumentRepository) FindByUserFiltered(residenceIDs []uint, filter *DocumentFilter) ([]models.Document, error) {
|
||||
query := r.db.Preload("CreatedBy").
|
||||
Preload("Residence").
|
||||
Preload("Images").
|
||||
Where("residence_id IN ? AND is_active = ?", residenceIDs, true)
|
||||
|
||||
if filter != nil {
|
||||
if filter.DocumentType != "" {
|
||||
query = query.Where("document_type = ?", filter.DocumentType)
|
||||
}
|
||||
if filter.Category != "" {
|
||||
query = query.Where("category = ?", filter.Category)
|
||||
}
|
||||
if filter.ContractorID != nil {
|
||||
query = query.Where("contractor_id = ?", *filter.ContractorID)
|
||||
}
|
||||
if filter.IsActive != nil {
|
||||
query = query.Where("is_active = ?", *filter.IsActive)
|
||||
}
|
||||
if filter.ExpiringSoon != nil {
|
||||
now := time.Now().UTC()
|
||||
threshold := now.AddDate(0, 0, *filter.ExpiringSoon)
|
||||
query = query.Where("expiry_date IS NOT NULL AND expiry_date > ? AND expiry_date <= ?", now, threshold)
|
||||
}
|
||||
if filter.Tags != "" {
|
||||
query = query.Where("tags LIKE ?", "%"+filter.Tags+"%")
|
||||
}
|
||||
if filter.Search != "" {
|
||||
searchPattern := "%" + filter.Search + "%"
|
||||
query = query.Where("(title ILIKE ? OR description ILIKE ?)", searchPattern, searchPattern)
|
||||
}
|
||||
}
|
||||
|
||||
var documents []models.Document
|
||||
err := query.Order("created_at DESC").Find(&documents).Error
|
||||
return documents, err
|
||||
}
|
||||
|
||||
// FindWarranties finds all warranty documents
|
||||
func (r *DocumentRepository) FindWarranties(residenceIDs []uint) ([]models.Document, error) {
|
||||
var documents []models.Document
|
||||
|
||||
Reference in New Issue
Block a user