diff --git a/internal/server/server.go b/internal/server/server.go index e5485d4..ac9b114 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -89,6 +89,8 @@ func New(opts Options) (*Server, error) { s.mux.HandleFunc("/", s.handleDashboard) s.mux.HandleFunc("/setup", s.handleSetup) s.mux.HandleFunc("/guide", s.handleGuide) + s.mux.HandleFunc("/impress", s.handleImpress) + s.mux.HandleFunc("/privacy", s.handlePrivacy) // Health routes s.mux.HandleFunc("/healthz", s.handleHealthz) @@ -187,6 +189,14 @@ func (s *Server) handleGuide(w http.ResponseWriter, r *http.Request) { s.renderPage(w, r, "guide", "guide.html") } +func (s *Server) handleImpress(w http.ResponseWriter, r *http.Request) { + s.renderPage(w, r, "impress", "impress.html") +} + +func (s *Server) handlePrivacy(w http.ResponseWriter, r *http.Request) { + s.renderPage(w, r, "privacy", "privacy.html") +} + func (s *Server) handleHealthz(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"status": "ok"}) diff --git a/web/embed.go b/web/embed.go index 7b79d25..5d70336 100644 --- a/web/embed.go +++ b/web/embed.go @@ -2,5 +2,5 @@ package web import "embed" -//go:embed all:templates all:js all:css all:i18n +//go:embed all:templates all:js all:css all:i18n favicon.svg var FS embed.FS diff --git a/web/i18n/de.json b/web/i18n/de.json index dbce5e9..8cc183c 100644 --- a/web/i18n/de.json +++ b/web/i18n/de.json @@ -7,6 +7,8 @@ "dashboard": "Dashboard", "setup": "Einrichtung", "guide": "Anleitung", + "impress": "Impressum", + "privacy": "Datenschutz", "language": "Sprache" }, "setup": { @@ -309,9 +311,54 @@ "tip4": "Nutzen Sie den Gaming-Schalter an Tagen, an denen Sie Ger\u00e4te unter Volllast betreiben." } }, + "impress": { + "title": "Impressum", + "responsible": "Verantwortlich", + "country": "Deutschland", + "contact": "Kontakt", + "email": "E-Mail", + "disclaimer": { + "title": "Haftungsausschluss", + "text": "HeatGuard ist ein privates Projekt und wird ohne Gew\u00e4hr bereitgestellt. Es stellt keine professionelle Beratung dar. Hitzerisikobewertungen sind Sch\u00e4tzungen basierend auf Nutzerdaten und Wettervorhersagen \u2014 befolgen Sie bei Hitzeereignissen immer die offiziellen Hinweise." + } + }, + "privacy": { + "title": "Datenschutzerkl\u00e4rung", + "intro": "HeatGuard ist darauf ausgelegt, die Datenerfassung zu minimieren. Diese Erkl\u00e4rung beschreibt, welche Daten verarbeitet und wohin sie gesendet werden.", + "localStorage": { + "title": "Lokale Datenspeicherung", + "text": "Alle Nutzerdaten (Profile, R\u00e4ume, Ger\u00e4te, Bewohner, Klimaanlagen, Vorhersage-Cache) werden ausschlie\u00dflich in der IndexedDB Ihres Browsers gespeichert. Auf dem Server werden keine Nutzerdaten gespeichert. Das L\u00f6schen Ihrer Browserdaten l\u00f6scht alle HeatGuard-Daten." + }, + "cookie": { + "title": "Cookie", + "text": "HeatGuard setzt ein einziges Cookie (heatguard_lang), um Ihre Spracheinstellung zu speichern. Es l\u00e4uft nach einem Jahr ab und enth\u00e4lt nur den Sprachcode (en oder de). Weitere Cookies werden nicht verwendet." + }, + "weather": { + "title": "Wettervorhersage-API", + "text": "Beim Abruf einer Vorhersage werden Ihre Standortkoordinaten (Breiten-/L\u00e4ngengrad) an Open-Meteo (open-meteo.com) oder OpenWeatherMap (openweathermap.org) gesendet, je nach Konfiguration. Diese Dienste haben eigene Datenschutzrichtlinien." + }, + "warnings": { + "title": "Wetterwarnungen (DWD)", + "text": "Wetterwarnungen werden vom Deutschen Wetterdienst (DWD) \u00fcber dessen \u00f6ffentliche WFS-Schnittstelle abgerufen. Ihre Standortkoordinaten werden als Teil der Anfrage \u00fcbermittelt." + }, + "llm": { + "title": "KI-Zusammenfassung (Optional)", + "text": "Wenn Sie einen KI-Anbieter konfigurieren, wird eine Zusammenfassung Ihrer Raumdaten und Wettervorhersage an den gew\u00e4hlten Anbieter (Anthropic, OpenAI, Google Gemini oder Ollama) gesendet. Ihr API-Schl\u00fcssel wird direkt aus Ihrem Browser gesendet. \u00dcber den Hitzeanalyse-Kontext hinaus werden keine pers\u00f6nlichen Daten \u00fcbermittelt." + }, + "bettervent": { + "title": "Ger\u00e4tedatenbank (bettervent.me)", + "text": "Bei der Suche nach Klimager\u00e4ten wird Ihre Suchanfrage \u00fcber den HeatGuard-Server an bettervent.me weitergeleitet. In diesen Anfragen sind keine pers\u00f6nlichen Daten enthalten." + }, + "noTracking": { + "title": "Keine Analyse oder Tracking", + "text": "HeatGuard verwendet keine Analyse-Tools, Tracking-Skripte, Fingerprinting oder sonstige Drittanbieter-Skripte. Es werden keine Daten an Werbetreibende oder Datenh\u00e4ndler weitergegeben." + } + }, "footer": { "source": "Quellcode", "license": "GPL-3.0-Lizenz", + "impress": "Impressum", + "privacy": "Datenschutz", "betterventCredit": "W\u00e4rmepumpendaten bereitgestellt von" }, "common": { diff --git a/web/i18n/en.json b/web/i18n/en.json index 3c15088..9903f7a 100644 --- a/web/i18n/en.json +++ b/web/i18n/en.json @@ -7,6 +7,8 @@ "dashboard": "Dashboard", "setup": "Setup", "guide": "Guide", + "impress": "Impress", + "privacy": "Privacy", "language": "Language" }, "setup": { @@ -309,9 +311,54 @@ "tip4": "Use the gaming toggle on days when you'll be running devices at full load." } }, + "impress": { + "title": "Legal Notice", + "responsible": "Responsible Person", + "country": "Germany", + "contact": "Contact", + "email": "Email", + "disclaimer": { + "title": "Disclaimer", + "text": "HeatGuard is a personal project provided as-is, without warranty. It does not constitute professional advice. Heat risk assessments are estimates based on user-provided data and weather forecasts — always follow official guidance during heat events." + } + }, + "privacy": { + "title": "Privacy Policy", + "intro": "HeatGuard is designed to minimize data collection. This policy describes what data is processed and where it is sent.", + "localStorage": { + "title": "Local Data Storage", + "text": "All user data (profiles, rooms, devices, occupants, AC units, forecast cache) is stored exclusively in your browser's IndexedDB. No user data is stored on the server. Clearing your browser data will delete all HeatGuard data." + }, + "cookie": { + "title": "Cookie", + "text": "HeatGuard sets a single cookie (heatguard_lang) to remember your language preference. It expires after one year and contains only the language code (en or de). No other cookies are used." + }, + "weather": { + "title": "Weather Forecast API", + "text": "When you fetch a forecast, your location coordinates (latitude/longitude) are sent to either Open-Meteo (open-meteo.com) or OpenWeatherMap (openweathermap.org), depending on your configuration. These services have their own privacy policies." + }, + "warnings": { + "title": "Weather Warnings (DWD)", + "text": "Weather warnings are fetched from the German Weather Service (DWD) via their public WFS endpoint. Your location coordinates are sent as part of the request." + }, + "llm": { + "title": "AI Summary (Optional)", + "text": "If you configure an AI provider, a summary of your room data and weather forecast is sent to the selected provider (Anthropic, OpenAI, Google Gemini, or Ollama). Your API key is sent directly from your browser. No personal data beyond the heat analysis context is included." + }, + "bettervent": { + "title": "Device Database (bettervent.me)", + "text": "When you search for AC units, your search query is proxied through the HeatGuard server to bettervent.me. No personal data is included in these requests." + }, + "noTracking": { + "title": "No Analytics or Tracking", + "text": "HeatGuard does not use analytics, tracking scripts, fingerprinting, or any third-party scripts. No data is shared with advertisers or data brokers." + } + }, "footer": { "source": "Source Code", "license": "GPL-3.0 License", + "impress": "Legal Notice", + "privacy": "Privacy", "betterventCredit": "Heat pump data powered by" }, "common": { diff --git a/web/templates/impress.html b/web/templates/impress.html new file mode 100644 index 0000000..a74d269 --- /dev/null +++ b/web/templates/impress.html @@ -0,0 +1,25 @@ +{{define "content"}} +
Christian Nachtigall
+Karwendelstr. 21
+82061 Neuried
+{{t "impress.country"}}
+{{t "impress.email"}}: christian@nachtigall.dev
+{{t "impress.disclaimer.text"}}
+{{t "privacy.intro"}}
+ +{{t "privacy.localStorage.text"}}
+{{t "privacy.cookie.text"}}
+{{t "privacy.weather.text"}}
+{{t "privacy.warnings.text"}}
+{{t "privacy.llm.text"}}
+{{t "privacy.bettervent.text"}}
+{{t "privacy.noTracking.text"}}
+