api: Bildupload v1 unter Formular v2 (Pflichtfelder, Kennung des Wortlauts, Bestätigung mit Token), Legacy-Bildupload abgeschaltet, API-Doku (Bildkennzeichnung Block C)

- StorePressReleaseImageRequest: copyright, rights_confirmed, confirm_text_version Pflicht; 422 mit aktueller Kennung; 16 MiB
- PressReleaseImageController über den gemeinsamen Uploader, Löschen über den Remover; Resource mit Portalkennzeichnung, Kundenangabe, Herkunft, Bestätigung und warnings[]
- POST /service/pressreleases/{id}/images antwortet 410 mit Hinweis auf v1 (E-B4)
- API-Seite und Sprachdateien: Felder und Rechtehinweis mit aktiver Textkennung; Paritätsdokument ergänzt

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-09-22 09:35:52 +00:00
parent 40953d6c65
commit 65ac72ce05
9 changed files with 411 additions and 30 deletions

View file

@ -34,7 +34,7 @@
| `GET /service/pressreleases.json` | **Öffentlicher Index**: nur `status=published`, portalweit (NICHT auf den User beschränkt!), Filter `query[languages][]`, `query[categories][]`, `query[offset]`, `query[limit]`, sortiert `created_at DESC`. Response: **JSON-Array von Show-URLs** (Strings), keine Objekte. |
| `GET /service/pressreleases/{id}.json` | Nur `published` (sonst 404; inaktive Firma → 404). Zählt Hits (session-dedupliziert). Response: flaches Objekt `{id, title, text, teaser_end, language, category_id, view_url, company: {viewUrl, name}}`. |
| `GET /service/pressreleases/{id}/images.json` | Nur bei `published` PM. Response: **Array von Bild-Show-URLs**. |
| `POST /service/pressreleases/{id}/images.json` | Nur Eigentümer (sonst 403 „You are not the creator …"). Multipart, Felder verschachtelt `press_release_image[image]` (+ title/description/copyright). Response: `201` + `Location`, Body `{}`. |
| `POST /service/pressreleases/{id}/images.json` | Nur Eigentümer (sonst 403 „You are not the creator …"). Multipart, Felder verschachtelt `press_release_image[image]` (+ title/description/copyright). Response: `201` + `Location`, Body `{}`. **Seit Bildkennzeichnung E-B4 (22.09.2026) mit `IMAGE_RIGHTS_V2=true` abgeschaltet: `410` mit Hinweis auf v1** — der Alt-Vertrag kennt weder Bildnachweis noch Rechtebestätigung und wurde nie genutzt. |
| `GET /service/pressreleases/{id}/images/{imgId}.json` | Response: `{id, title, description, copyright, image_file_url}`. |
| `GET /service/users/me/companies.json` | Eigene Firmen; `limit`/`offset` direkt ODER `query[limit]`/`query[offset]`. Response: **Array von Show-URLs**. |
| `POST /service/users/me/companies.json` | Firma anlegen (`201` + `Location`, Body `{}`). |
@ -113,6 +113,7 @@ Scope nach Log-Auswertung (§3a): **die 5 connektar-Endpoints**, verhaltensgleic
- [x] `POST /service/users/me/companies/{id}/contacts` — Felder `contact[salutation_id|title|first_name|last_name|responsibility|phone|fax|email]`; Zugriff nur eigene Firma (403-Wortlaut s. §1); Response wie oben.
- [x] `POST /service/pressreleases` — Felder `press_release[company_id|contacts_list[]|category_id|language|title|text|backlink_url|…]`; Statusverhalten s. S2; KI-Deklarations-Default none (erledigt 10.07.); Response `201` + `Location` + `{}`.
- [x] `POST /service/pressreleases/{id}/images` — Multipart `press_release_image[image|title|description|copyright]`; Eigentümer-Check (403 „You are not the creator of this press release"); ai_declaration-Default original (erledigt 10.07.); Response `201` + `Location` + `{}`.
- **22.09.2026:** hinter `IMAGE_RIGHTS_V2` abgeschaltet (410, Bildkennzeichnung E-B4). Der Default „original“ war eine erfundene Erklärung (Decision-Update S5).
- [x] `GET /service/pressreleases/{id}` — nur `published` (sonst 404 — connektars Polling-Kontrolle!), Hit-Zählung, flaches Alt-Objekt `{id,title,text,teaser_end,language,category_id,view_url,company:{viewUrl,name}}`.
- [x] Alt-Fehlerformat überall: `{"global_errors":[…],"field_errors":{…}}` (422) bzw. `{"global_errors":[…]}`.
- [x] Pest-Paritäts-Tests (`LegacyServiceParityTest`) — je Endpoint gegen den §1-Vertrag (inkl. connektar-Flow end-to-end: Firma → Kontakt → PM → Bild → GET).