Add PDF reports, file uploads, admin auth, and comprehensive tests

Features:
- PDF service for generating task reports with ReportLab-style formatting
- Storage service for file uploads (local and S3-compatible)
- Admin authentication middleware with JWT support
- Admin user model and repository

Infrastructure:
- Updated Docker configuration for admin panel builds
- Email service enhancements for task notifications
- Updated router with admin and file upload routes
- Environment configuration updates

Tests:
- Unit tests for handlers (auth, residence, task)
- Unit tests for models (user, residence, task)
- Unit tests for repositories (user, residence, task)
- Unit tests for services (residence, task)
- Integration test setup
- Test utilities for mocking database and services

Database:
- Admin user seed data
- Updated test data seeds

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-11-27 23:36:20 -06:00
parent 2817deee3c
commit 469f21a833
50 changed files with 6795 additions and 582 deletions

View File

@@ -55,7 +55,7 @@ func (s *DocumentService) GetDocument(documentID, userID uint) (*responses.Docum
}
// ListDocuments lists all documents accessible to a user
func (s *DocumentService) ListDocuments(userID uint) (*responses.DocumentListResponse, error) {
func (s *DocumentService) ListDocuments(userID uint) ([]responses.DocumentResponse, error) {
residences, err := s.residenceRepo.FindByUser(userID)
if err != nil {
return nil, err
@@ -67,7 +67,7 @@ func (s *DocumentService) ListDocuments(userID uint) (*responses.DocumentListRes
}
if len(residenceIDs) == 0 {
return &responses.DocumentListResponse{Count: 0, Results: []responses.DocumentResponse{}}, nil
return []responses.DocumentResponse{}, nil
}
documents, err := s.documentRepo.FindByUser(residenceIDs)
@@ -75,12 +75,11 @@ func (s *DocumentService) ListDocuments(userID uint) (*responses.DocumentListRes
return nil, err
}
resp := responses.NewDocumentListResponse(documents)
return &resp, nil
return responses.NewDocumentListResponse(documents), nil
}
// ListWarranties lists all warranty documents
func (s *DocumentService) ListWarranties(userID uint) (*responses.DocumentListResponse, error) {
func (s *DocumentService) ListWarranties(userID uint) ([]responses.DocumentResponse, error) {
residences, err := s.residenceRepo.FindByUser(userID)
if err != nil {
return nil, err
@@ -92,7 +91,7 @@ func (s *DocumentService) ListWarranties(userID uint) (*responses.DocumentListRe
}
if len(residenceIDs) == 0 {
return &responses.DocumentListResponse{Count: 0, Results: []responses.DocumentResponse{}}, nil
return []responses.DocumentResponse{}, nil
}
documents, err := s.documentRepo.FindWarranties(residenceIDs)
@@ -100,8 +99,7 @@ func (s *DocumentService) ListWarranties(userID uint) (*responses.DocumentListRe
return nil, err
}
resp := responses.NewDocumentListResponse(documents)
return &resp, nil
return responses.NewDocumentListResponse(documents), nil
}
// CreateDocument creates a new document