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

@@ -68,6 +68,7 @@ func SetupRouter(deps *Dependencies) *gin.Engine {
// Initialize services
authService := services.NewAuthService(userRepo, cfg)
userService := services.NewUserService(userRepo)
residenceService := services.NewResidenceService(residenceRepo, userRepo, cfg)
taskService := services.NewTaskService(taskRepo, residenceRepo)
contractorService := services.NewContractorService(contractorRepo, residenceRepo)
@@ -80,12 +81,14 @@ func SetupRouter(deps *Dependencies) *gin.Engine {
// Initialize handlers
authHandler := handlers.NewAuthHandler(authService, deps.EmailService, deps.Cache)
userHandler := handlers.NewUserHandler(userService)
residenceHandler := handlers.NewResidenceHandler(residenceService)
taskHandler := handlers.NewTaskHandler(taskService)
contractorHandler := handlers.NewContractorHandler(contractorService)
documentHandler := handlers.NewDocumentHandler(documentService)
notificationHandler := handlers.NewNotificationHandler(notificationService)
subscriptionHandler := handlers.NewSubscriptionHandler(subscriptionService)
staticDataHandler := handlers.NewStaticDataHandler(residenceService, taskService, contractorService)
// API group
api := r.Group("/api")
@@ -94,7 +97,7 @@ func SetupRouter(deps *Dependencies) *gin.Engine {
setupPublicAuthRoutes(api, authHandler)
// Public data routes (no auth required)
setupPublicDataRoutes(api, residenceHandler, taskHandler, contractorHandler)
setupPublicDataRoutes(api, residenceHandler, taskHandler, contractorHandler, staticDataHandler)
// Protected routes (auth required)
protected := api.Group("")
@@ -107,7 +110,7 @@ func SetupRouter(deps *Dependencies) *gin.Engine {
setupDocumentRoutes(protected, documentHandler)
setupNotificationRoutes(protected, notificationHandler)
setupSubscriptionRoutes(protected, subscriptionHandler)
setupUserRoutes(protected)
setupUserRoutes(protected, userHandler)
}
}
@@ -162,12 +165,12 @@ func setupProtectedAuthRoutes(api *gin.RouterGroup, authHandler *handlers.AuthHa
}
// setupPublicDataRoutes configures public data routes (lookups, static data)
func setupPublicDataRoutes(api *gin.RouterGroup, residenceHandler *handlers.ResidenceHandler, taskHandler *handlers.TaskHandler, contractorHandler *handlers.ContractorHandler) {
func setupPublicDataRoutes(api *gin.RouterGroup, residenceHandler *handlers.ResidenceHandler, taskHandler *handlers.TaskHandler, contractorHandler *handlers.ContractorHandler, staticDataHandler *handlers.StaticDataHandler) {
// Static data routes (public, cached)
staticData := api.Group("/static_data")
{
staticData.GET("/", placeholderHandler("get-static-data"))
staticData.POST("/refresh/", placeholderHandler("refresh-static-data"))
staticData.GET("/", staticDataHandler.GetStaticData)
staticData.POST("/refresh/", staticDataHandler.RefreshStaticData)
}
// Lookup routes (public)
@@ -194,7 +197,7 @@ func setupResidenceRoutes(api *gin.RouterGroup, residenceHandler *handlers.Resid
residences.DELETE("/:id/", residenceHandler.DeleteResidence)
residences.POST("/:id/generate-share-code/", residenceHandler.GenerateShareCode)
residences.POST("/:id/generate-tasks-report/", placeholderHandler("generate-tasks-report"))
residences.POST("/:id/generate-tasks-report/", residenceHandler.GenerateTasksReport)
residences.GET("/:id/users/", residenceHandler.GetResidenceUsers)
residences.DELETE("/:id/users/:user_id/", residenceHandler.RemoveResidenceUser)
}
@@ -296,22 +299,11 @@ func setupSubscriptionRoutes(api *gin.RouterGroup, subscriptionHandler *handlers
}
// setupUserRoutes configures user routes
func setupUserRoutes(api *gin.RouterGroup) {
func setupUserRoutes(api *gin.RouterGroup, userHandler *handlers.UserHandler) {
users := api.Group("/users")
{
users.GET("/", placeholderHandler("list-users"))
users.GET("/:id/", placeholderHandler("get-user"))
users.GET("/profiles/", placeholderHandler("list-profiles"))
}
}
// placeholderHandler returns a handler that indicates an endpoint is not yet implemented
func placeholderHandler(name string) gin.HandlerFunc {
return func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{
"error": "Endpoint not yet implemented",
"endpoint": name,
"message": "This endpoint is planned for future phases",
})
users.GET("/", userHandler.ListUsers)
users.GET("/:id/", userHandler.GetUser)
users.GET("/profiles/", userHandler.ListProfiles)
}
}