Implement remaining handlers and fix admin login

- Fix admin login bcrypt hash in database migrations
- Add static data handler (GET /api/static_data/, POST /api/static_data/refresh/)
- Add user handler (list users, get user, list profiles in shared residences)
- Add generate tasks report endpoint for residences
- Remove all placeholder handlers from router
- Add seeding documentation to README

New files:
- internal/handlers/static_data_handler.go
- internal/handlers/user_handler.go
- internal/services/user_service.go
- internal/dto/responses/user.go

🤖 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-26 23:11:49 -06:00
parent fff5d8c206
commit 9ec1bddd99
11 changed files with 604 additions and 22 deletions

View File

@@ -0,0 +1,89 @@
package handlers
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/treytartt/mycrib-api/internal/services"
)
// StaticDataHandler handles static/lookup data endpoints
type StaticDataHandler struct {
residenceService *services.ResidenceService
taskService *services.TaskService
contractorService *services.ContractorService
}
// NewStaticDataHandler creates a new static data handler
func NewStaticDataHandler(
residenceService *services.ResidenceService,
taskService *services.TaskService,
contractorService *services.ContractorService,
) *StaticDataHandler {
return &StaticDataHandler{
residenceService: residenceService,
taskService: taskService,
contractorService: contractorService,
}
}
// GetStaticData handles GET /api/static_data/
// Returns all lookup/reference data in a single response
func (h *StaticDataHandler) GetStaticData(c *gin.Context) {
// Get all lookup data
residenceTypes, err := h.residenceService.GetResidenceTypes()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch residence types"})
return
}
taskCategories, err := h.taskService.GetCategories()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch task categories"})
return
}
taskPriorities, err := h.taskService.GetPriorities()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch task priorities"})
return
}
taskFrequencies, err := h.taskService.GetFrequencies()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch task frequencies"})
return
}
taskStatuses, err := h.taskService.GetStatuses()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch task statuses"})
return
}
contractorSpecialties, err := h.contractorService.GetSpecialties()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch contractor specialties"})
return
}
c.JSON(http.StatusOK, gin.H{
"residence_types": residenceTypes,
"task_categories": taskCategories,
"task_priorities": taskPriorities,
"task_frequencies": taskFrequencies,
"task_statuses": taskStatuses,
"contractor_specialties": contractorSpecialties,
})
}
// RefreshStaticData handles POST /api/static_data/refresh/
// This is a no-op since data is fetched fresh each time
// Kept for API compatibility with mobile clients
func (h *StaticDataHandler) RefreshStaticData(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Static data refreshed",
"status": "success",
})
}