Fix BASE_URL config loading, add tasks/projects; robust .env path resolution

- Config: try ENV_FILE, .env, ../.env for loading; trim trailing slash from BaseURL
- Log BASE_URL at server startup for verification
- .env.example: document BASE_URL
- Tasks, projects, tags, migrations and related API/handlers

Made-with: Cursor
This commit is contained in:
Michilis
2026-03-09 18:57:51 +00:00
parent 75105b8b46
commit bd24545b7b
61 changed files with 6595 additions and 90 deletions

View File

@@ -0,0 +1,94 @@
package handlers
import (
"net/http"
"github.com/calendarapi/internal/middleware"
"github.com/calendarapi/internal/models"
"github.com/calendarapi/internal/service"
"github.com/calendarapi/internal/utils"
"github.com/go-chi/chi/v5"
)
type TaskReminderHandler struct {
reminderSvc *service.TaskReminderService
}
func NewTaskReminderHandler(reminderSvc *service.TaskReminderService) *TaskReminderHandler {
return &TaskReminderHandler{reminderSvc: reminderSvc}
}
func (h *TaskReminderHandler) List(w http.ResponseWriter, r *http.Request) {
userID, _ := middleware.GetUserID(r.Context())
taskID, err := utils.ValidateUUID(chi.URLParam(r, "id"))
if err != nil {
utils.WriteError(w, err)
return
}
reminders, err := h.reminderSvc.List(r.Context(), userID, taskID)
if err != nil {
utils.WriteError(w, err)
return
}
utils.WriteList(w, reminders, models.PageInfo{Limit: len(reminders)})
}
func (h *TaskReminderHandler) Add(w http.ResponseWriter, r *http.Request) {
userID, _ := middleware.GetUserID(r.Context())
taskID, err := utils.ValidateUUID(chi.URLParam(r, "id"))
if err != nil {
utils.WriteError(w, err)
return
}
var req struct {
Type string `json:"type"`
Config map[string]interface{} `json:"config"`
ScheduledAt string `json:"scheduled_at"`
}
if err := utils.DecodeJSON(r, &req); err != nil {
utils.WriteError(w, err)
return
}
t, err := utils.ParseTime(req.ScheduledAt)
if err != nil {
utils.WriteError(w, models.NewValidationError("invalid scheduled_at"))
return
}
reminder, err := h.reminderSvc.Create(r.Context(), userID, taskID, service.CreateTaskReminderRequest{
Type: req.Type,
Config: req.Config,
ScheduledAt: t,
})
if err != nil {
utils.WriteError(w, err)
return
}
utils.WriteJSON(w, http.StatusOK, map[string]interface{}{"reminder": reminder})
}
func (h *TaskReminderHandler) Delete(w http.ResponseWriter, r *http.Request) {
userID, _ := middleware.GetUserID(r.Context())
taskID, err := utils.ValidateUUID(chi.URLParam(r, "id"))
if err != nil {
utils.WriteError(w, err)
return
}
reminderID, err := utils.ValidateUUID(chi.URLParam(r, "reminderId"))
if err != nil {
utils.WriteError(w, err)
return
}
if err := h.reminderSvc.Delete(r.Context(), userID, taskID, reminderID); err != nil {
utils.WriteError(w, err)
return
}
utils.WriteOK(w)
}