14 new optional residence fields (heating, cooling, water heater, roof, pool, sprinkler, septic, fireplace, garage, basement, attic, exterior, flooring, landscaping) with JSONB conditions on templates. Suggestion engine scores templates against home profile: string match +0.25, bool +0.3, property type +0.15, universal base 0.3. Graceful degradation from minimal to full profile info. GET /api/tasks/suggestions/?residence_id=X returns ranked templates. 54 template conditions across 44 templates in seed data. 8 suggestion service tests.
51 lines
1.3 KiB
Go
51 lines
1.3 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
|
|
"github.com/treytartt/honeydue-api/internal/apperrors"
|
|
"github.com/treytartt/honeydue-api/internal/middleware"
|
|
"github.com/treytartt/honeydue-api/internal/services"
|
|
)
|
|
|
|
// SuggestionHandler handles task suggestion endpoints
|
|
type SuggestionHandler struct {
|
|
suggestionService *services.SuggestionService
|
|
}
|
|
|
|
// NewSuggestionHandler creates a new suggestion handler
|
|
func NewSuggestionHandler(suggestionService *services.SuggestionService) *SuggestionHandler {
|
|
return &SuggestionHandler{
|
|
suggestionService: suggestionService,
|
|
}
|
|
}
|
|
|
|
// GetSuggestions handles GET /api/tasks/suggestions/?residence_id=X
|
|
// Returns task template suggestions scored against the residence's home profile
|
|
func (h *SuggestionHandler) GetSuggestions(c echo.Context) error {
|
|
user, err := middleware.MustGetAuthUser(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
residenceIDStr := c.QueryParam("residence_id")
|
|
if residenceIDStr == "" {
|
|
return apperrors.BadRequest("error.residence_id_required")
|
|
}
|
|
|
|
residenceID, err := strconv.ParseUint(residenceIDStr, 10, 32)
|
|
if err != nil {
|
|
return apperrors.BadRequest("error.invalid_id")
|
|
}
|
|
|
|
resp, err := h.suggestionService.GetSuggestions(uint(residenceID), user.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return c.JSON(http.StatusOK, resp)
|
|
}
|