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:
@@ -56,8 +56,8 @@ func (s *DocumentService) GetDocument(documentID, userID uint) (*responses.Docum
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// ListDocuments lists all documents accessible to a user
|
||||
func (s *DocumentService) ListDocuments(userID uint) ([]responses.DocumentResponse, error) {
|
||||
// ListDocuments lists all documents accessible to a user, with optional filters.
|
||||
func (s *DocumentService) ListDocuments(userID uint, filter *repositories.DocumentFilter) ([]responses.DocumentResponse, error) {
|
||||
// Get residence IDs (lightweight - no preloads)
|
||||
residenceIDs, err := s.residenceRepo.FindResidenceIDsByUser(userID)
|
||||
if err != nil {
|
||||
@@ -68,7 +68,22 @@ func (s *DocumentService) ListDocuments(userID uint) ([]responses.DocumentRespon
|
||||
return []responses.DocumentResponse{}, nil
|
||||
}
|
||||
|
||||
documents, err := s.documentRepo.FindByUser(residenceIDs)
|
||||
// If a specific residence filter is set, narrow to that single residence (if user has access)
|
||||
if filter != nil && filter.ResidenceID != nil {
|
||||
found := false
|
||||
for _, rid := range residenceIDs {
|
||||
if rid == *filter.ResidenceID {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return nil, apperrors.Forbidden("error.residence_access_denied")
|
||||
}
|
||||
residenceIDs = []uint{*filter.ResidenceID}
|
||||
}
|
||||
|
||||
documents, err := s.documentRepo.FindByUserFiltered(residenceIDs, filter)
|
||||
if err != nil {
|
||||
return nil, apperrors.Internal(err)
|
||||
}
|
||||
|
||||
@@ -103,7 +103,11 @@ func (s *TaskService) GetTask(taskID, userID uint) (*responses.TaskResponse, err
|
||||
|
||||
// ListTasks lists all tasks accessible to a user as a kanban board.
|
||||
// The `now` parameter should be the start of day in the user's timezone for accurate overdue detection.
|
||||
func (s *TaskService) ListTasks(userID uint, now time.Time) (*responses.KanbanBoardResponse, error) {
|
||||
func (s *TaskService) ListTasks(userID uint, daysThreshold int, now time.Time) (*responses.KanbanBoardResponse, error) {
|
||||
if daysThreshold <= 0 {
|
||||
daysThreshold = 30 // Default
|
||||
}
|
||||
|
||||
// Get all residence IDs accessible to user (lightweight - no preloads)
|
||||
residenceIDs, err := s.residenceRepo.FindResidenceIDsByUser(userID)
|
||||
if err != nil {
|
||||
@@ -114,13 +118,13 @@ func (s *TaskService) ListTasks(userID uint, now time.Time) (*responses.KanbanBo
|
||||
// Return empty kanban board
|
||||
return &responses.KanbanBoardResponse{
|
||||
Columns: []responses.KanbanColumnResponse{},
|
||||
DaysThreshold: 30,
|
||||
DaysThreshold: daysThreshold,
|
||||
ResidenceID: "all",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Get kanban data aggregated across all residences using user's timezone-aware time
|
||||
board, err := s.taskRepo.GetKanbanDataForMultipleResidences(residenceIDs, 30, now)
|
||||
board, err := s.taskRepo.GetKanbanDataForMultipleResidences(residenceIDs, daysThreshold, now)
|
||||
if err != nil {
|
||||
return nil, apperrors.Internal(err)
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ func TestTaskService_ListTasks(t *testing.T) {
|
||||
testutil.CreateTestTask(t, db, residence.ID, user.ID, "Task 2")
|
||||
testutil.CreateTestTask(t, db, residence.ID, user.ID, "Task 3")
|
||||
|
||||
resp, err := service.ListTasks(user.ID, time.Now().UTC())
|
||||
resp, err := service.ListTasks(user.ID, 30, time.Now().UTC())
|
||||
require.NoError(t, err)
|
||||
// ListTasks returns a KanbanBoardResponse with columns
|
||||
// Count total tasks across all columns
|
||||
|
||||
Reference in New Issue
Block a user