api: Ziel-Portal einer Einreichung explizit auflösen statt vom Konto erben

Legacy-API-Kunden mit Keys beider Altportale — vor allem connektar — senden
jede Meldung an presseecho.de UND businessportal24.de. Weil die Firma ihr
Portal vom User und die Meldung es von der Firma erbte, landeten beide Kopien
im selben Portal, die zweite mit Slug-Suffix "-2". Verifiziert wurde das über
die Token-Hashes gegen die Legacy-Datenbanken.

Das Portal wird jetzt in fester Reihenfolge aufgelöst: expliziter
portal-Parameter, sonst die aufgerufene Domain, sonst das Portal des
Firmenprofils, zuletzt Portal::Both — genau der Default, den beide Spalten
ohnehin tragen. Die Auflösung ist damit nicht-nullbar; vorher konnte sie null
liefern, was als SQL-Fehler und damit als 500er beim Alt-Client gelandet wäre.
Ein Update über die v1-API verschiebt eine bestehende Meldung ausschließlich
über den expliziten Parameter, nie über die aufgerufene Domain.

press-releases:fix-api-portal-duplicates repariert die Altdaten: Es findet
Paare (gleicher User, Titel, Sprache und Portal, beide per API eingereicht,
kurz nacheinander) und verschiebt die zweite Kopie samt ihrer exklusiven Firma
ins jeweils andere Portal, mit neu vergebenem Slug. Web-Doppel-Submits ohne
Status-Log source=api und Legacy-Sync-Daten mit gesetzter legacy_id werden
geschont. Auf Live ausgeführt und verifiziert.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-09-01 11:06:58 +00:00
parent 0c8e94a6ff
commit 982de2aba2
15 changed files with 720 additions and 13 deletions

View file

@ -280,7 +280,8 @@ return [
'th_description' => 'Beschreibung',
'required_yes' => 'ja',
'field_company_id' => 'ID eines eigenen Firmenprofils — bestimmt Newsroom und Portal.',
'field_portal' => 'Ziel-Portal (presseecho oder businessportal24). Ohne Angabe entscheidet die aufgerufene Domain, sonst das Portal des Firmenprofils; ein gesetzter Wert hat Vorrang.',
'field_company_id' => 'ID eines eigenen Firmenprofils — bestimmt den Newsroom.',
'field_category_id' => 'Rubrik (siehe GET /categories).',
'field_language' => 'Sprachcode, zwei Zeichen: de oder en.',
'field_title' => 'Überschrift, max. 255 Zeichen.',

View file

@ -279,7 +279,8 @@ return [
'th_description' => 'Description',
'required_yes' => 'yes',
'field_company_id' => 'ID of one of your company profiles — determines newsroom and portal.',
'field_portal' => 'Target portal (presseecho or businessportal24). If omitted, the requested domain decides, otherwise the company profile\'s portal; an explicit value takes precedence.',
'field_company_id' => 'ID of one of your company profiles — determines the newsroom.',
'field_category_id' => 'Category (see GET /categories).',
'field_language' => 'Language code, two characters: de or en.',
'field_title' => 'Headline, max. 255 characters.',