mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 19:01:08 +02:00
mana-search-go → mana-search mana-notify-go → mana-notify mana-crawler-go → mana-crawler mana-api-gateway-go → mana-api-gateway Legacy NestJS versions are deleted, suffix no longer needed. Updated all references in docker-compose, CLAUDE.md, package.json, Forgejo workflows, and service package.json files. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
95 lines
3.5 KiB
Go
95 lines
3.5 KiB
Go
package handler
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
"github.com/manacore/mana-notify/internal/auth"
|
|
"github.com/manacore/mana-notify/internal/db"
|
|
)
|
|
|
|
type PreferencesHandler struct {
|
|
db *db.DB
|
|
}
|
|
|
|
func NewPreferencesHandler(database *db.DB) *PreferencesHandler {
|
|
return &PreferencesHandler{db: database}
|
|
}
|
|
|
|
// Get handles GET /api/v1/preferences
|
|
func (h *PreferencesHandler) Get(w http.ResponseWriter, r *http.Request) {
|
|
user := auth.GetUser(r)
|
|
if user == nil {
|
|
writeError(w, http.StatusUnauthorized, "unauthorized")
|
|
return
|
|
}
|
|
|
|
var p db.Preference
|
|
err := h.db.Pool.QueryRow(r.Context(),
|
|
`SELECT id, user_id, email_enabled, push_enabled, quiet_hours_enabled, quiet_hours_start, quiet_hours_end, timezone, category_preferences, created_at, updated_at
|
|
FROM notify.preferences WHERE user_id = $1`, user.UserID,
|
|
).Scan(&p.ID, &p.UserID, &p.EmailEnabled, &p.PushEnabled, &p.QuietHoursEnabled,
|
|
&p.QuietHoursStart, &p.QuietHoursEnd, &p.Timezone, &p.CategoryPreferences, &p.CreatedAt, &p.UpdatedAt)
|
|
|
|
if err != nil {
|
|
// Return defaults
|
|
writeJSON(w, http.StatusOK, map[string]any{
|
|
"preferences": map[string]any{
|
|
"emailEnabled": false,
|
|
"pushEnabled": true,
|
|
"quietHoursEnabled": false,
|
|
"timezone": "Europe/Berlin",
|
|
},
|
|
})
|
|
return
|
|
}
|
|
|
|
writeJSON(w, http.StatusOK, map[string]any{"preferences": p})
|
|
}
|
|
|
|
// Update handles PUT /api/v1/preferences
|
|
func (h *PreferencesHandler) Update(w http.ResponseWriter, r *http.Request) {
|
|
user := auth.GetUser(r)
|
|
if user == nil {
|
|
writeError(w, http.StatusUnauthorized, "unauthorized")
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
EmailEnabled *bool `json:"emailEnabled,omitempty"`
|
|
PushEnabled *bool `json:"pushEnabled,omitempty"`
|
|
QuietHoursEnabled *bool `json:"quietHoursEnabled,omitempty"`
|
|
QuietHoursStart *string `json:"quietHoursStart,omitempty"`
|
|
QuietHoursEnd *string `json:"quietHoursEnd,omitempty"`
|
|
Timezone *string `json:"timezone,omitempty"`
|
|
CategoryPreferences map[string]any `json:"categoryPreferences,omitempty"`
|
|
}
|
|
if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, 1<<20)).Decode(&req); err != nil {
|
|
writeError(w, http.StatusBadRequest, "invalid request body")
|
|
return
|
|
}
|
|
|
|
catJSON, _ := json.Marshal(req.CategoryPreferences)
|
|
|
|
_, err := h.db.Pool.Exec(r.Context(),
|
|
`INSERT INTO notify.preferences (user_id, email_enabled, push_enabled, quiet_hours_enabled, quiet_hours_start, quiet_hours_end, timezone, category_preferences)
|
|
VALUES ($1, COALESCE($2, false), COALESCE($3, true), COALESCE($4, false), $5, $6, COALESCE($7, 'Europe/Berlin'), $8)
|
|
ON CONFLICT (user_id) DO UPDATE SET
|
|
email_enabled = COALESCE($2, notify.preferences.email_enabled),
|
|
push_enabled = COALESCE($3, notify.preferences.push_enabled),
|
|
quiet_hours_enabled = COALESCE($4, notify.preferences.quiet_hours_enabled),
|
|
quiet_hours_start = COALESCE($5, notify.preferences.quiet_hours_start),
|
|
quiet_hours_end = COALESCE($6, notify.preferences.quiet_hours_end),
|
|
timezone = COALESCE($7, notify.preferences.timezone),
|
|
category_preferences = COALESCE($8, notify.preferences.category_preferences),
|
|
updated_at = NOW()`,
|
|
user.UserID, req.EmailEnabled, req.PushEnabled, req.QuietHoursEnabled,
|
|
req.QuietHoursStart, req.QuietHoursEnd, req.Timezone, catJSON,
|
|
)
|
|
if err != nil {
|
|
writeError(w, http.StatusInternalServerError, "failed to update preferences")
|
|
return
|
|
}
|
|
|
|
writeJSON(w, http.StatusOK, map[string]any{"updated": true})
|
|
}
|