## 2026-10-23 – Public Widget V2 (vor Deployment)

- Neuer GET `/v1/public/infosnow/widget-v2.php?widget=light-ride` und OpenAPI-Schema `InfosnowPublicWidgetV2Response`; Product Manifest stellt `infosnow_public_widget_v2` bereit.
- Ausschliesslich das bisher genehmigte LIGHT-RIDE-Objekt; keine weiteren Source-/Field-Rights, keine StatusRemarks-Freigabe. 400/404/429/503 fail-closed. Manuelles Deployment und Live-Readback stehen aus.

# API Changelog

## 2026-10-20 – Infosnow LIGHT RIDE Public Planned Schedule (vor Deployment)

- GET `/v1/public/infosnow/planned-schedule.php?widget=light-ride` ist als minimiertes, read-only Public-Datenprodukt implementiert; separater manueller Release und Live-Readback ausstehend.
- Nur genehmigtes LIGHT RIDE, source-native Planzeiten, kein bestätigter Ist-Status; fehlende oder veraltete Import-Observation → 503; unbekanntes Widget → 404.
- Quellzeitpunkt bleibt `null`, acht Stunden auf Basis beobachtetem Full Import; keine neuen Imports/History.
- Nicht-brechende additive V1-Route.



Dieses Changelog dokumentiert relevante Änderungen an der öffentlichen API-Dokumentation und an verfügbaren Public- oder Partner-Endpunkten.

API-Basis:

```txt
https://api.lenzerheide.swiss
```

Developer Portal:

```txt
https://docs.lenzerheide.swiss
```

## Versionierung

Die API wird über den Pfad versioniert:

```txt
/v1/...
```

Regeln:

- Neue Felder können innerhalb von `/v1` ergänzt werden.
- Bestehende Integrationen sollten unbekannte Felder ignorieren können.
- Breaking Changes werden nicht stillschweigend innerhalb von `/v1` eingeführt.
- Relevante Änderungen an Endpunkten, Feldern, Authentifizierung, Scopes oder Rate Limits werden hier dokumentiert.

## 2026-10-12 - Public/Partner API P1/P2-Vertragsabgleich

Status: Repository-Aenderung; separater Production-Deploy, HTTP-Readback und Edge-Abnahme ausstehend.

- Die bestehende V1-Fehlerantwort `{error:{code,message,details}}` wird in Partner-Swagger und Datenmodell korrekt dokumentiert; der Runtime-Envelope wird nicht umgestellt.
- Traffic ohne aktuelle, verwertbare Messzeilen oder ohne Beobachtungszeit wird sowohl in Public als auch Partner fail-closed mit HTTP `503` statt Status `free` beantwortet. Bestehende valide Messwerte und Kennzahlensemantik bleiben unveraendert.
- `max_age_minutes` ist in Public (1 bis 240) und Partner (1 bis 360), jeweils Standard 120, in Swagger/API-Referenz erfasst.
- Historische Liftperioden geben `coverageFrom=null` statt `""` aus, wenn die valide First-Seen-Provenienz fehlt. Der bestehende Historien-Scope Resorts 57 und 67 wird explizit dokumentiert.
- Die Standard-Rate-Limits werden mit Minuten- und Tageswerten, IP-/Key-Scope und dem Vorbehalt privater Runtime-Konfiguration korrekt beschrieben.
- Synthetische Regressionstests sichern die Abweichungen ab. Keine neuen Endpunkte, Quellen, Berechtigungen, Secrets, SQL-Migrationen, Imports oder Cronjobs.

## 2026-10-08 - Edge Extension Public API Developer Onboarding

Status: Repository-Vorbereitung; Production-Deploy und Edge-Abnahme separat.

### Geaendert

- Bestehende Public-Endpunkte in Developer Portal, Getting Started und API-Referenz vervollstaendigt.
- Microsoft-Edge-MV3-Guide in die Public-Docs-Allowlist aufgenommen.
- HTTP-Smoke-Definitionen fuer Destination Context, Lift Operating Hours und Lift Periods ergaenzt.
- Automatischer Konsistenztest fuer OpenAPI, Portal, API-Referenz, Smoke-Definitionen und Docs-Paket hinzugefuegt.

Keine neue Public-Freigabe, kein geaenderter API-Response-Vertrag, kein Secret, keine neue Quelle, keine SQL-Migration, kein Import und kein Cronjob. Neue Infosnow-Aktivitaetsgruppen, Events und Parking bleiben separat gegatet. Kein Breaking Change.

## 2026-10-05 - Infosnow Operational Current V1 StatusRemarks

Status: bereit fuer manuellen Production Deploy

### Geaendert

Der bestehende interne Vertrag `GET /v1/internal/infosnow/operational-current.php` erhaelt additiv das optionale Row-Feld `statusRemarks` mit den allowlisteten Sprachschluesseln `de` und `en`. Die Werte stammen direkt aus Infosnow Type-1 `StatusRemarks`, bewahren Zeilenumbrueche und sind pro Sprache auf 4000 Bytes begrenzt. Allgemeine Beschreibungen, Kontakte, weitere Sprachen und unbekannte Freitextfelder bleiben ausgeschlossen.

Bestehende Consumer und bereits geschriebene Last-Good-Snapshots ohne das Feld bleiben kompatibel. Es gibt keine neue Source-Abfrage, keine SQL-Migration, keinen neuen Cronjob und keine neue private Konfiguration.

### Keine API Breaking Changes

Die Aenderung ist additiv innerhalb von `/v1` und betrifft ausschliesslich den geschuetzten Internal-Endpoint.

## 2026-09-28 - Cross-country Wax Tip V1

Status: bereit fuer manuellen Production Deploy

### Neu

```txt
GET /v1/public/cross-country/wax.php
```

Der additive Public-Endpunkt leitet aus den verbleibenden MeteoSwiss-Hourly-Werten des aktuellen lokalen Tages einen transparenten Lufttemperaturkorridor fuer Gleitwachs ab. Die empfohlene Abdeckung wird nach aussen auf ganze Grad gerundet.

V1 gibt **keine** Marke, Farbe oder Produktfamilie vor und verwendet keine erfundene Schneetemperatur oder Schneeart. Steigwachs und Klister sind explizit ausserhalb des Scopes. Bei weniger als zwei nutzbaren verbleibenden Stundenwerten wird `available=false` geliefert.

### OpenAPI

```txt
Public API 1.8.0
```

### Betrieb

Keine SQL-Migration, kein neuer Cronjob, keine neue private Konfiguration und keine neuen Secrets. Consumer sollen den Endpunkt nur fuer winterliche Langlaufprodukte sichtbar machen.

### Keine API Breaking Changes

Der Endpunkt ist additiv innerhalb von `/v1`.

## 2026-09-28 - Public Weather Hourly

Status: bereit fuer manuellen Production Deploy

### Neu

```txt
GET /v1/public/weather/hourly.php
```

Der neue additive Public-Endpunkt gibt einen reduzierten zukuenftigen MeteoSwiss-Stundenverlauf fuer Lenzerheide/Lai aus. Allowlistete Horizonte sind 6, 12, 18 und 24 Stunden; Standard ist 12. Pro Stunde werden nur `validAt`, Temperatur, Niederschlag, Niederschlagswahrscheinlichkeit und Boeen ausgegeben. Rohpayloads, interne Quality-Metadaten und Supabase-Strukturen bleiben ausgeschlossen.

### OpenAPI

```txt
Public API 1.7.0
```

### Betrieb

Keine SQL-Migration, kein neuer Cronjob, keine neue private Konfiguration und keine neuen Secrets. Neue Consumer muessen zuerst den Data Layer deployen und den Public-Endpunkt pruefen.

### Keine API Breaking Changes

Der Endpunkt ist additiv innerhalb von `/v1`.

## 2026-08-18 - Weather API auf MeteoSwiss-Semantik ausgerichtet

Status: bereit für manuellen Production Deploy

### Betroffene Endpunkte

```txt
GET /v1/public/weather/current.php
GET /v1/public/weather/forecast.php
GET /v1/partner/weather/summary.php
```

### Geändert

```txt
apps/data-layer/lib/weather.php
apps/data-layer/lib/weather-forecast.php
api/openapi-public.json
api/openapi-partner.json
docs/api-reference.md
docs/data-model.md
docs/WEATHER_DATA_PRODUCT.md
tests/weather-public-contract.php
scripts/check.sh
```

### Inhalt

Die Public- und Partner-Weather-Verträge wurden gegen die produktive MeteoSwiss OGD Local-Forecast-Source-of-Truth geprüft und semantisch korrigiert.

- Der Pfad `current.php` bleibt für `/v1` kompatibel, wird fachlich aber als Wetter-Tageswert dokumentiert und nicht als Echtzeit-Stationsmessung.
- Neu werden additiv `dataType`, `isForecast`, `source`, `sourceProduct`, `sourceCreatedAt` und `capturedAt` ausgegeben.
- `observedAt` bleibt aus Rückwärtskompatibilität bestehen, ist bei Weather aber als Legacy-Alias für `capturedAt` dokumentiert und nicht als Messzeit zu interpretieren.
- `location_key=lenzerheide` ist der aktuell einzige dokumentierte und produktiv verifizierte Weather-Standort.
- Im MeteoSwiss Daily Forecast nicht gelieferte Legacy-Felder wie Bergtemperaturen, `sunshineHours`, `windGustsKmh`, Schnee oder Nullgradgrenze bleiben `null` und werden nicht künstlich ergänzt.
- Zusätzliche Hourly-Werte bleiben ein separates internes Data Product und werden nicht verdeckt in Public-/Partner-Daily-Verträge gemischt.

### OpenAPI

```txt
Public API  1.5.0
Partner API 1.3.0
```

Die bisherigen Partner-Weather-Beispiele mit nicht existierenden Feldern wie `temperatureCelsius` oder `windKmh` wurden durch den tatsächlichen Response Contract ersetzt.

### Governance

Die Änderung verbessert Provenance und Nachvollziehbarkeit, ohne neue Datenbereiche freizugeben. Weather enthält keine Personendaten. Public und Partner erhalten weiterhin nur kuratierte Data-Layer-Felder und keinen direkten Source- oder Supabase-Zugriff.

### Keine API Breaking Changes

Bestehende Felder und Endpunkte wurden nicht entfernt. Neue Felder sind additiv. `observedAt` bleibt verfügbar, ist aber als Legacy-Feld markiert.

## 2026-08-18 - Developer Portal gegen `main` geprüft

Status: bereit für manuellen Production Deploy

### Geändert

```txt
docs/getting-started.md
docs/api-reference.md
docs/data-model.md
docs/use-cases.md
docs/api-governance.md
docs/api-changelog.md
```

### Inhalt

Die öffentliche Dokumentation wurde gegen die aktuell auf `main` vorhandenen Public- und Partner-Endpunkte geprüft.

- Public API dokumentiert weiterhin API Root, Status, Traffic, Weather Current, Weather Forecast und Lift Status.
- Partner API dokumentiert weiterhin Traffic Summary und Weather Summary.
- Die Standort-Dokumentation wurde korrigiert: `lenzerheide` bleibt der dokumentierte Standard. Weitere Schlüssel werden erst nach fachlicher Freigabe und produktiver Verifikation als unterstützt ausgewiesen.
- Beispiele und Datumsangaben wurden aktualisiert.
- Use Cases wurden um Weather Forecast und Lift Status ergänzt.
- Security- und Governance-Hinweise wurden geschärft: Least Privilege, serverseitige Partner-Integration, deny-by-default für neue Datenbereiche sowie klare Aktualitätshinweise bei Near-Live-Daten.
- Die überarbeiteten Markdown-Seiten verwenden normale deutsche Umlaute statt ASCII-Ersatzschreibweisen.

### OpenAPI

`api/openapi-public.json` und `api/openapi-partner.json` wurden gegen die vorhandenen Endpunktstrukturen geprüft. Für diesen Dokumentations-Refresh ist kein Contract- oder Versionswechsel nötig.

### Governance

Es werden keine internen Endpunkte, Supabase-Strukturen, Secrets oder produktiven Konfigurationen publiziert. Die bestehende öffentliche Docs-Allowlist bleibt unverändert.

### Keine API Breaking Changes

Die produktiven `/v1` Endpunkte und Response Contracts werden durch diese Dokumentationsänderungen nicht verändert.

## 2026-08-10 - Public API Dokumentation synchronisiert

Status: aktiv

### Geändert

```txt
api/openapi-public.json
docs/api-reference.md
docs/api-changelog.md
docs/index.html
docs/api-test-plan.md
scripts/test-api-endpoints.php
scripts/package-deployment.sh
```

### Inhalt

Die öffentliche API-Dokumentation wurde mit dem aktuellen Code synchronisiert.

- Public Weather Current dokumentiert den Response Contract mit Wetterbewertung und reduzierten Wetterwerten.
- Public Weather Forecast ist in Swagger, Referenz, Developer Portal und Smoke Tests enthalten.
- Public Lift Status beschreibt den saisonübergreifenden Anlagenkatalog und die Live-Statuslogik der aktuellen Saison.
- Verbindlich sind `openapi-public.json` und `openapi-partner.json`.
- Der Pfad `openapi.json` bleibt aus Kompatibilitätsgründen erreichbar, wird beim Packaging aber direkt aus `openapi-public.json` erzeugt und ist keine eigenständige Source of Truth.

### Governance

Die Trennung der Public- und Partner-Spezifikationen reduziert widersprüchliche API-Contracts. Public Responses bleiben minimiert und ohne personenbezogene Daten. Secrets oder produktive Zugangsdaten sind nicht Bestandteil der Dokumentation.

### Keine API Breaking Changes

Die produktiven `/v1` Endpunkte wurden nicht verändert.

## 2026-08-09 - Public Weather Forecast API

Status: aktiv

### Neu

```txt
GET /v1/public/weather/forecast.php
```

Der Public-Endpunkt liefert bis zu sieben Wettertage aus den harmonisierten Wetterdaten des Data Layers.

Optionale Parameter:

```txt
days=1..7
location_key=lenzerheide
```

Pro Tag werden ausschliesslich freigegebene Wetterfelder ausgegeben, darunter Datum, Forecast-Kennzeichen, Wetter-Icon, Temperaturbereiche für Tal und Berg, Sonnenstunden, Niederschlag, Windböen sowie Aktualitätszeitpunkte.

### Auswirkung

Gästeanwendungen und Widgets können eine standardisierte Wetterprognose über die Lenzerheide Public API beziehen, ohne direkt auf die Rohquelle oder Supabase zuzugreifen.

### Keine API Breaking Changes

Der neue Endpunkt ist additiv innerhalb von `/v1`.

## 2026-08-07 - Public Lift Type IDs

Status: aktiv

### Geändert

```txt
GET /v1/public/lifts/current.php
```

Jede Anlage liefert additiv `typeId`. Der Wert stammt aus der importierten Infosnow-`TypID`/`TypeID`. Fehlt eine Typ-ID, wird `null` ausgegeben.

### Keine API Breaking Changes

Das Feld ist additiv innerhalb von `/v1`.

## 2026-08-07 - Public Lift Status API

Status: aktiv

### Neu

```txt
GET /v1/public/lifts/current.php
```

Der Public-Endpunkt liefert einen reduzierten Near-Live-Betriebsstatus der Infosnow-Anlagen für Lenzerheide. Es wird automatisch die lokale Sommer- oder Wintersaison in `Europe/Zurich` verwendet.

Normalisierte Statuswerte:

```txt
open
preparing
closed
unknown
```

Infosnow-Status `2` wird als `preparing` ausgegeben. Werte, deren Beobachtungszeitpunkt mehr als fünf Minuten zurückliegt, erhalten `status=unknown` sowie `freshness=stale`.

### Auswirkung

Öffentliche Widgets und Gästeanwendungen können Bergbahnstatus beziehen, ohne direkt auf Infosnow, Supabase oder Internal-API-Zugänge zuzugreifen.

### Keine API Breaking Changes

Bestehende Endpunkte und Datenverträge wurden nicht verändert.

## 2026-07-09 - Developer Portal Struktur

Status: aktiv

### Geändert

```txt
docs/index.html
docs/getting-started.md
docs/data-model.md
docs/use-cases.md
docs/api-governance.md
```

### Inhalt

`docs.lenzerheide.swiss` wurde als kleines Developer Portal aufgebaut.

Struktur:

```txt
Getting Started
API Katalog
Use Cases
Authentication / Scopes
Data Model
Errors / Rate Limits
Usage Guide
Changelog
Swagger / OpenAPI
```

### Keine API Breaking Changes

Es wurden keine produktiven API-Endpunkte entfernt oder geändert.

## 2026-07-09 - Swagger Trennung Public / Partner

### Geändert

```txt
api/openapi-public.json
api/openapi-partner.json
docs/index.html
docs/api-reference.md
```

### Inhalt

Swagger ist nach API-Bereich getrennt:

```txt
Partner API · API-Key
Public API · ohne API-Key
```

### Keine API Breaking Changes

Es wurden keine produktiven API-Endpunkte entfernt oder geändert.

## 2026-07-08 - Public und Partner API V1 Basis

### Verfügbare Public-Endpunkte zum damaligen Stand

```txt
GET /
GET /v1/status.php
GET /v1/public/traffic/status.php
GET /v1/public/weather/current.php
```

### Verfügbare Partner-Endpunkte

```txt
GET /v1/partner/traffic/summary.php
GET /v1/partner/weather/summary.php
```

### Authentifizierung

Partner-Endpunkte benötigen einen API-Key.

```txt
X-API-Key: YOUR_API_KEY
```

oder:

```txt
Authorization: Bearer YOUR_API_KEY
```

### Scopes

```txt
traffic:read
weather:read
```

## Changelog-Regeln

Ein Changelog-Eintrag soll enthalten:

```txt
Datum
betroffene Endpunkte oder Dokumente
Status
relevante Änderung
Auswirkung für Partner:innen
Breaking Changes ja/nein
```
