Files
honeyDueAPI/internal/services/task_template_service.go
Trey t 793e50ce52 Add regional task templates API with climate zone lookup
Adds a new endpoint GET /api/tasks/templates/by-region/?zip= that resolves
ZIP codes to IECC climate regions and returns relevant home maintenance
task templates. Includes climate region model, region lookup service with
tests, seed data for all 8 climate zones with 50+ templates, and OpenAPI spec.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 15:15:30 -06:00

90 lines
2.8 KiB
Go

package services
import (
"github.com/treytartt/casera-api/internal/dto/responses"
"github.com/treytartt/casera-api/internal/repositories"
)
// TaskTemplateService handles business logic for task templates
type TaskTemplateService struct {
templateRepo *repositories.TaskTemplateRepository
}
// NewTaskTemplateService creates a new task template service
func NewTaskTemplateService(templateRepo *repositories.TaskTemplateRepository) *TaskTemplateService {
return &TaskTemplateService{
templateRepo: templateRepo,
}
}
// GetAll returns all active task templates
func (s *TaskTemplateService) GetAll() ([]responses.TaskTemplateResponse, error) {
templates, err := s.templateRepo.GetAll()
if err != nil {
return nil, err
}
return responses.NewTaskTemplateListResponse(templates), nil
}
// GetGrouped returns all templates grouped by category
func (s *TaskTemplateService) GetGrouped() (responses.TaskTemplatesGroupedResponse, error) {
templates, err := s.templateRepo.GetAll()
if err != nil {
return responses.TaskTemplatesGroupedResponse{}, err
}
return responses.NewTaskTemplatesGroupedResponse(templates), nil
}
// Search searches templates by query string
func (s *TaskTemplateService) Search(query string) ([]responses.TaskTemplateResponse, error) {
templates, err := s.templateRepo.Search(query)
if err != nil {
return nil, err
}
return responses.NewTaskTemplateListResponse(templates), nil
}
// GetByCategory returns templates for a specific category
func (s *TaskTemplateService) GetByCategory(categoryID uint) ([]responses.TaskTemplateResponse, error) {
templates, err := s.templateRepo.GetByCategory(categoryID)
if err != nil {
return nil, err
}
return responses.NewTaskTemplateListResponse(templates), nil
}
// GetByID returns a single template by ID
func (s *TaskTemplateService) GetByID(id uint) (*responses.TaskTemplateResponse, error) {
template, err := s.templateRepo.GetByID(id)
if err != nil {
return nil, err
}
resp := responses.NewTaskTemplateResponse(template)
return &resp, nil
}
// GetByRegion returns templates for a specific climate region.
// Accepts either a state abbreviation or ZIP code (state takes priority).
// ZIP codes are resolved to a state via the ZipToState lookup.
func (s *TaskTemplateService) GetByRegion(state, zip string) ([]responses.TaskTemplateResponse, error) {
// Resolve ZIP to state if no state provided
if state == "" && zip != "" {
state = ZipToState(zip)
}
regionID := GetClimateRegionIDByState(state)
if regionID == 0 {
return []responses.TaskTemplateResponse{}, nil
}
templates, err := s.templateRepo.GetByRegion(regionID)
if err != nil {
return nil, err
}
return responses.NewTaskTemplateListResponse(templates), nil
}
// Count returns the total count of active templates
func (s *TaskTemplateService) Count() (int64, error) {
return s.templateRepo.Count()
}