feat(m2): settings history, close day, holiday/vacation/sick marking

This commit is contained in:
2026-04-30 16:37:56 +02:00
parent 3aa068efd2
commit 4a0e0c8318
7 changed files with 607 additions and 2 deletions

View File

@@ -0,0 +1,78 @@
package handler
import (
"errors"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/wotra/wotra/internal/service"
)
// SettingsHandler serves /api/settings routes.
type SettingsHandler struct {
svc *service.SettingsService
}
func NewSettingsHandler(svc *service.SettingsService) *SettingsHandler {
return &SettingsHandler{svc: svc}
}
func (h *SettingsHandler) Routes(r chi.Router) {
r.Get("/settings", h.Current)
r.Put("/settings", h.Upsert)
r.Get("/settings/history", h.History)
}
// Current GET /api/settings
func (h *SettingsHandler) Current(w http.ResponseWriter, r *http.Request) {
set, err := h.svc.Current(r.Context())
if err != nil {
writeError(w, http.StatusInternalServerError, err.Error())
return
}
writeJSON(w, http.StatusOK, set)
}
// Upsert PUT /api/settings
func (h *SettingsHandler) Upsert(w http.ResponseWriter, r *http.Request) {
var body struct {
EffectiveFrom string `json:"effective_from"`
HoursPerWeek float64 `json:"hours_per_week"`
WorkdaysMask int `json:"workdays_mask"`
Timezone string `json:"timezone"`
}
if err := decodeJSON(r, &body); err != nil {
writeError(w, http.StatusBadRequest, "invalid JSON")
return
}
set, err := h.svc.Upsert(r.Context(), service.UpsertSettingsInput{
EffectiveFrom: body.EffectiveFrom,
HoursPerWeek: body.HoursPerWeek,
WorkdaysMask: body.WorkdaysMask,
Timezone: body.Timezone,
})
if err != nil {
switch {
case errors.Is(err, service.ErrInvalidHours), errors.Is(err, service.ErrInvalidWorkdaysMask):
writeError(w, http.StatusUnprocessableEntity, err.Error())
default:
writeError(w, http.StatusInternalServerError, err.Error())
}
return
}
writeJSON(w, http.StatusOK, set)
}
// History GET /api/settings/history
func (h *SettingsHandler) History(w http.ResponseWriter, r *http.Request) {
history, err := h.svc.History(r.Context())
if err != nil {
writeError(w, http.StatusInternalServerError, err.Error())
return
}
if history == nil {
writeJSON(w, http.StatusOK, []struct{}{})
return
}
writeJSON(w, http.StatusOK, history)
}