Add task templates API and admin management

- Add TaskTemplate model with category and frequency support
- Add task template repository with CRUD and search operations
- Add task template service layer
- Add public API endpoints for templates (no auth required):
  - GET /api/tasks/templates/ - list all templates
  - GET /api/tasks/templates/grouped/ - templates grouped by category
  - GET /api/tasks/templates/search/?q= - search templates
  - GET /api/tasks/templates/by-category/:id/ - templates by category
  - GET /api/tasks/templates/:id/ - single template
- Add admin panel for task template management (CRUD)
- Add admin API endpoints for templates
- Add seed file with predefined task templates
- Add i18n translations for template errors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-05 09:07:53 -06:00
parent e824c90877
commit bbf3999c79
17 changed files with 1634 additions and 4 deletions

View File

@@ -0,0 +1,69 @@
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
}
// Count returns the total count of active templates
func (s *TaskTemplateService) Count() (int64, error) {
return s.templateRepo.Count()
}