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

@@ -52,12 +52,20 @@ type ResidenceResponse struct {
UpdatedAt time.Time `json:"updated_at"`
}
// ResidenceListResponse represents the paginated list of residences
type ResidenceListResponse struct {
Count int `json:"count"`
Next *string `json:"next"`
Previous *string `json:"previous"`
Results []ResidenceResponse `json:"results"`
// TotalSummary represents summary statistics for all residences
type TotalSummary struct {
TotalResidences int `json:"total_residences"`
TotalTasks int `json:"total_tasks"`
TotalPending int `json:"total_pending"`
TotalOverdue int `json:"total_overdue"`
TasksDueNextWeek int `json:"tasks_due_next_week"`
TasksDueNextMonth int `json:"tasks_due_next_month"`
}
// MyResidencesResponse represents the response for my-residences endpoint
type MyResidencesResponse struct {
Residences []ResidenceResponse `json:"residences"`
Summary TotalSummary `json:"summary"`
}
// ShareCodeResponse represents a share code in the API response
@@ -160,19 +168,13 @@ func NewResidenceResponse(residence *models.Residence) ResidenceResponse {
return resp
}
// NewResidenceListResponse creates a paginated list response
func NewResidenceListResponse(residences []models.Residence) ResidenceListResponse {
// NewResidenceListResponse creates a list of residence responses
func NewResidenceListResponse(residences []models.Residence) []ResidenceResponse {
results := make([]ResidenceResponse, len(residences))
for i, r := range residences {
results[i] = NewResidenceResponse(&r)
}
return ResidenceListResponse{
Count: len(residences),
Next: nil, // Pagination not implemented yet
Previous: nil,
Results: results,
}
return results
}
// NewShareCodeResponse creates a ShareCodeResponse from a ResidenceShareCode model