External Context-Snapshot · 0008 · 2026-05-13
FCSB · BH4SF Publication-Mapping TR1__Job__c RecordType: Publication
TL;DR — Field-Mapping zwischen dem FCSB-Salesforce-Object TR1__Job__c (Filter RecordTypeId = 012Wx000000C7ngIAC, DeveloperName Publication) und dem Drupal-Bundle sf_publication. 22 inbound-relevante Felder plus 1 outbound-Feld (hohr__Job_Application_URL__c). Industry-Picklist TR1__Sector1__c mit 25 DE-Labels (Agriculture→Landwirtschaft, …). Quelle: internes SOLCOM/Entero-Interface-Mapping-Excel IC_I220_BH4SF_Publication_Website (1).xlsx (untracked im Repo, .gitignore für docs/context/*.xlsx). Live-Describe gegen FCSB-Sandbox als Pre-Build-Gate Pflicht.
Object-Scope
| Aspekt | Wert | Quelle |
| SF-Object | TR1__Job__c | Excel-Mapping, Header |
| RecordType DeveloperName | Publication | Excel „FCSB:" Sektion |
| RecordTypeId (FCSB-Sandbox) | 012Wx000000C7ngIAC | Excel „FCSB:" Sektion |
| RecordTypeId (Production) | noch nicht dokumentiert | Excel „PROD:" Sektion vorhanden, aber Wert leer |
| SOQL-WHERE-Clause-Basis | WHERE RecordTypeId = '012Wx000000C7ngIAC' | abgeleitet |
Boundary: Das Object TR1__Job__c hat mehrere RecordTypes (mindestens Request, Publication). Nur Publications sind im Scope dieses Mappings und damit der Drupal-Spiegelung. Records mit anderen RecordTypes werden vom SOQL-Filter ausgeschlossen.
Drift-Warnungen
⚠
Field-Name-Drift im Briefing nicht reproduzierbar. Das ursprüngliche Grilling-Briefing zur Story P2503-108 behauptete, die FCSB-Sandbox liefere hohr__Publishing_start_date__c / _end_date__c (ohne _time) im Widerspruch zum Mapping. Im Excel selbst steht jedoch in der Zelle „Beispiel-Payload" ein realer Platform-Event-Payload SC_Publication_Changed_Out__e mit den Keys hohr_Publishing_start_date_time__c und hohr_Publishing_end_date_time__c (MIT _time) — d.h. Excel-Mapping und Live-Sample sind konsistent. Pre-Build-Gate trotzdem Pflicht: SOQL-Describe /services/data/v59.0/sobjects/TR1__Job__c/describe gegen FCSB-Sandbox laufen lassen und alle 22 Field-Namen verifizieren, bevor field.storage.*-Configs gebaut werden.
⚠
Picklist-Value-Drift SC_PublicationStatus__c. Das Mapping-Excel listet diese Picklist auf, gibt aber den konkreten Match-Wert nicht explizit an. Im Story-Grilling wurde festgelegt: Drupal-Node-Status published, wenn SC_PublicationStatus__c == "Online" AND publish_start <= now < publish_end. Authoritativ: "Online" (Sandbox-Wert). Sollte irgendwo „Published" auftauchen, ist das veraltete Doku-Drift — Implementation greift "Online".
★
Platform-Event-Key-Naming. Das Live-Sample im Excel zeigt einen Payload des Streaming-Events SC_Publication_Changed_Out__e mit Single-Underscore-Keys (hohr_Publishing_start_date_time__c statt hohr__Publishing_start_date_time__c). Für REST-Pull über /services/data/v59.0/query sind die Double-Underscore-API-Names (hohr__Publishing_start_date_time__c) korrekt — das Single-Underscore ist eine Eigenheit der Platform-Event-Serialisierung, nicht des REST-Schemas. Bei REST-Pull-SOQL verwende immer hohr__.
Field-Mapping (22 Inbound + 1 Outbound)
required
optional
skip
drift / open
Identitäts-Felder
| UI-Label (DE) | SF API Name | Pflicht | Typ | Bemerkung |
| RecordType |
RecordTypeId |
req |
Text(18) |
Filter, nicht gemappt. 012Wx000000C7ngIAC = Publication (Sandbox). |
| SF-Id |
Id |
req |
Text(18) |
Internal Salesforce-Id der Publication. Map-Key für migrate_map_sf_publication. Für Outbound-PATCH (Updates) reicht Id allein. |
| Übergeordnete Stelle |
hohr__Parent_Job__c |
opt |
Lookup → TR1__Job__c (Request) |
Request-Id für die Minggo-URL-Konstruktion (F-330). Hat den RecordType Request, nicht Publication. |
| Job Number |
hohr__Parent_Job__r.SC_AutoNumber__c |
opt |
Auto-Number (string) |
Relationale Joins über das Parent-Job-Lookup. Excel-Remark: „reicht die SF-Id, Job-Number wird irrelevant sobald RMS abgeschaltet wird." |
| VIS Request Nr. |
hohr__Parent_Job__r.SC_ExternalRequestNo__c |
opt |
Text (5-stellige Nummer) |
VIS-Request-No des Parent-Job. Im SOQL via Relation-Path zu joinen. |
Content-Felder
| UI-Label (DE) | SF API Name | Pflicht | Typ | Bemerkung |
| Stellenbezeichnung |
TR1__Job_Title__c |
no |
Text(255) |
Excel-Remark: „maybe subject to change (currently in discussion)" — kann umbenannt werden. |
| Die Aufgaben der Stelle |
hohr__Long_description__c |
opt |
Rich Text Area(32768) |
Force.com-HTML, Sanitize-Pipeline via SalesforceRichTextSanitizer. |
| Rahmenbedingungen |
hohr__Internal_description__c |
opt |
Rich Text Area(32000) |
Force.com-HTML, sanitize. |
| Must-haves in Erfahrung und Ausbildung |
hohr__Requirements_description__c |
opt |
Rich Text Area(25000) |
Force.com-HTML, sanitize. |
| Nice to have |
TR1__Experience_Requirements__c |
opt |
Rich Text Area(16000) |
Force.com-HTML, sanitize. |
| Auslastung |
SC_Utilisation__c |
opt |
Text(30) |
Beispiel-Live-Wert: „80". |
| Wunschstart |
TR1__Estimated_Start_Date__c |
opt |
Date |
Datum-Mapping via format_date-Process-Plugin. |
| Spätester Start |
SC_LatestStart__c |
no |
Date |
Excel-Remark: „Field new with US W-001034". |
| Dauer |
SC_Duration__c |
opt |
Number (oder Text) |
Excel-Remark: „Achtung: Feld ist in BH4SF länger als in RMS." — bei Field-Storage-Schema-Definition prüfen. |
| Einsatzort |
TR1__City__c |
opt |
Text(60) |
Beispiel-Live-Wert: „Köln". |
| Branche |
TR1__Sector1__c |
opt |
Picklist |
Industry-Lookup via Custom Process Plugin → Vocabulary sf_industry. 25 Werte, siehe Industry-Picklist-Sektion. |
Publishing-Channel-Flags
| UI-Label (DE) | SF API Name | Pflicht | Typ | Bemerkung |
| Publishing Channel Gulp |
SC_Publishing_Channel_Gulp__c |
opt |
Checkbox |
Markiert SOLCOM-interne Routing-Channel. Nicht für Anzeige im PPP relevant (Outbound-Channels). Felder werden geladen, aber als Drupal-Boolean-Field gespeichert für mögliche spätere Filter / Reporting. |
| Publishing Channel Freelance |
SC_Publishing_Channel_Freelance__c |
opt |
Checkbox |
siehe oben |
| Publishing Channel Freelancermap |
SC_Publishing_Channel_Freelancermap__c |
opt |
Checkbox |
siehe oben |
Publishing-Window drift: live-describe required
| UI-Label (DE) | SF API Name | Pflicht | Typ | Bemerkung |
| Startdatum Veröffentlichung |
hohr__Publishing_start_date_time__c |
opt |
Datetime |
Live-Sample-Wert (Excel): "2026-02-02T00:00:00.000Z". Pre-Build-Describe trotz konsistentem Sample Pflicht. |
| Ablaufdatum Veröffentlichung |
hohr__Publishing_end_date_time__c |
opt |
Datetime |
Live-Sample-Wert (Excel): "2026-02-09T15:18:59.000Z". Pre-Build-Describe Pflicht. |
Lifecycle-Status picklist value drift
| UI-Label (DE) | SF API Name | Pflicht | Typ | Bemerkung |
| Status der Veröffentlichung |
SC_PublicationStatus__c |
opt |
Picklist |
Match-Wert für Drupal-Status published: "Online" (authoritativ). Drupal-Node ist published gdw. SC_PublicationStatus__c == "Online" AND publish_start <= now < publish_end. Implementation via static_map-Process-Plugin: "Online" → 1, default → 0. Excel-Remark vom Mapping-Author: „Würde für mich mehr Sinn machen wenn auf der Website gesetzt wird" — wurde im Grilling abgelehnt (SF bleibt Lifecycle-Source-of-Truth). |
Outbound-Feld (Drupal → SF)
| UI-Label (DE) | SF API Name | Pflicht | Typ | Bemerkung |
| Job Application URL |
hohr__Job_Application_URL__c |
opt |
URL(255) |
Outbound-only. Excel-Remark: „URL of the published Publication. Must be set and removed by Website." Bei Drupal-Publish: kanonische PPP-URL setzen. Bei Drupal-Unpublish: Feld leeren (PATCH mit null). Implementation via hook_node_update mit Status-Transition-Guard → Queue → SfPublicationOutboundWorker → REST-PATCH. |
Owner-Felder
| UI-Label (DE) | SF API Name | Pflicht | Typ | Bemerkung |
| Inhaber SOLCOM-Id |
Owner.SC_SolcomExternalId__c |
skip |
Text |
Excel-Remark: „Wird nicht benötigt für Website." Nicht mappen. |
| Inhaber Mail |
Owner.Email |
opt |
Text(80) |
Relationale Lookup via Owner-Relation. Mapping in Drupal als String-Feld (kein User-Entity-Reference, weil PPP-Bewerber:innen nicht denselben User-Pool wie SOLCOM-Mitarbeiter:innen haben). |
Audit-Felder
| UI-Label (DE) | SF API Name | Pflicht | Typ | Bemerkung |
| Zuletzt geändert am/um |
LastModifiedDate |
opt |
Datetime |
SF-Standard-Feld. Im Per-Run-Vollscan nicht als Delta-Filter genutzt (sonst false-positive-Deletes im Sweep), aber als Drupal-Field nützlich für Sortierung/Anzeige. |
| Zuletzt geändert durch (SOLCOM-Id) |
LastModifiedBy.SC_SolcomExternalId__c |
skip |
Text |
Audit-only, nicht für PPP-Anzeige relevant. Skip. |
Industry-Picklist TR1__Sector1__c (25 Werte)
Transformation-Rule No. 01 aus dem Mapping-Excel. Vocabulary in Drupal: sf_industry. Pre-Seed via hook_install; jeder Term hat Name (DE-Label) und field_sf_value (SF-API-Value).
| # | SF-Value (Source / EN) | DE-Label (Drupal Term-Name) |
| 01 | Agriculture | Landwirtschaft |
| 02 | Automotive | Automobilindustrie |
| 03 | Banking | Bankwesen |
| 04 | Chemicals | Chemie |
| 05 | Construction | Bauwesen |
| 06 | Consumer goods | Konsumgüter |
| 07 | Education and training | Bildung und Ausbildung |
| 08 | Electrical engineering | Elektrotechnik |
| 09 | Energy supply | Energieversorgung |
| 10 | Financial services | Finanzdienstleistungen |
| 11 | Industry | Industrie |
| 12 | Information technology | Informationstechnologie |
| 13 | Insurance | Versicherung |
| 14 | Mechanical and plant engineering | Maschinen- und Anlagenbau |
| 15 | Media | Medien |
| 16 | Medicine and healthcare | Medizin und Gesundheitswesen |
| 17 | Other | Sonstige |
| 18 | Pharmaceuticals | Pharmazie |
| 19 | Public sector clients | Öffentliche Auftraggeber |
| 20 | Real estate | Immobilien |
| 21 | Services | Dienstleistungen |
| 22 | Telecommunications | Telekommunikation |
| 23 | Tourism | Tourismus |
| 24 | Trade | Handel |
| 25 | Transport and logistics | Transport und Logistik |
Live-Sample-Felder (im Mapping-Excel-Payload, nicht im Hauptmapping)
Der Excel-Payload-Auszug eines SC_Publication_Changed_Out__e-Platform-Events enthält zusätzliche Felder, die im Mapping-Hauptteil nicht aufgeführt sind. Sie existieren in der FCSB-Sandbox und könnten relevant sein — Entscheidung über Aufnahme ins Drupal-Schema im PRD-Open-Item Nr. 2 (Live-Describe).
| SF API Name | Live-Sample-Wert | Vermutete Bedeutung |
SC_ExternalPublicationNo__c | "101823" | Externe Publikations-Nummer (eigener ID-Bereich) |
SC_VISRequestNo__c | "68465" | VIS-Request-No direkt am Job (statt nur via Parent-Relation) |
SC_BH4SFRequestNo__c | "1004545" | BH4SF-eigene Request-Nummer |
SC_JobType__c | "freiberuflich" | Beschäftigungs-Typ (relevant für PPP-Filter?) |
OwnerEmail__c | "volker.kolberg@entero.de" | Custom-Override des Owner.Email-Standard-Lookups |
OwnerShortName__c | "vkolberg" | Owner-Short-Name |
LastModifiedByUserShortName__c | "" | Audit-Field |
Id__c | "a1WAU000002PkUj2AK" | Doppelter Id-Custom-Field — sehr ungewöhnlich, Live-Describe nötig zur Klärung |
Hinweis: Id__c mit Custom-Suffix neben dem Standard-Id ist unkonventionell. Möglicherweise eine FCSB-spezifische Eigenheit der Platform-Event-Serialisierung. Für REST-Pull-SOQL ist Id (ohne Suffix) der Map-Key.
SOQL-Anker-Query (Inbound)
Basis-Form für die Migration. Felder gemäß Mapping; konkrete Field-Liste wird nach Live-Describe finalisiert. Query muss RecordType-Filter enthalten, sonst kommen Request-Records mit.
SELECT Id,
hohr__Parent_Job__c,
hohr__Parent_Job__r.SC_AutoNumber__c,
hohr__Parent_Job__r.SC_ExternalRequestNo__c,
TR1__Job_Title__c,
hohr__Long_description__c,
hohr__Internal_description__c,
hohr__Requirements_description__c,
TR1__Experience_Requirements__c,
SC_Utilisation__c,
TR1__Estimated_Start_Date__c,
SC_LatestStart__c,
SC_Duration__c,
TR1__City__c,
Owner.Email,
TR1__Sector1__c,
SC_Publishing_Channel_Gulp__c,
SC_Publishing_Channel_Freelance__c,
SC_Publishing_Channel_Freelancermap__c,
hohr__Publishing_start_date_time__c,
hohr__Publishing_end_date_time__c,
SC_PublicationStatus__c,
LastModifiedDate
FROM TR1__Job__c
WHERE RecordTypeId = '012Wx000000C7ngIAC'
Ohne LIMIT / OFFSET — SF-API liefert ein nextRecordsUrl-Feld im JSON-Response für Paging. Custom Data-Fetcher SalesforceSoqlFetcher liest dieses Feld aus dem Body und ruft Folge-Pages auf.
Vollscan begründet: Per-Run-Sweep (PRD-Decision Q4) erfordert, dass alle aktiven Publications im Run erscheinen, sonst würde der EventSubscriber sie false-positive-deleten. Daher kein WHERE LastModifiedDate > LastRunDate-Filter.
Quellen & Cross-Links
- Original-Quelle:
IC_I220_BH4SF_Publication_Website (1).xlsx — internes SOLCOM/Entero-Interface-Mapping-Dokument. Liegt untracked im Working-Tree unter docs/context/ (.gitignore-Regel docs/context/*.xlsx — Personenbezug in Rohdaten-Spalten).
- PRD: PRD Salesforce-Publication-Sync (BH4SF) — referenziert dieses Mapping in der Implementation-Decisions-Sektion.
- Story: F-290 Salesforce / Bullhorn Integration (REST-Pull) — Jira P2503-108.
- Personio-Präzedenz: PRD Personio-Vacancy-Integration — inline ADR-0013 setzt den Migrate-Pattern-Standard (Custom-QueueWorker rejected, migrate_plus als Inbound-Standard für externe Quellen).
- IT-Landschaft: 0001 IT-Landscape — Kante E11 zeigt „Existing Drupal Webhook" SF-Job-Posting → Projektpartnerportal (architektonische Erwartung).
- Outbound-Abgrenzung: F-330 Minggoformular — Bewerbungs-Submit ist NICHT in F-290 enthalten.
Capture-Datum: 2026-05-13. Letzter Sync: 2026-05-13. Supersedes: (keine Vorgängerversion). Re-Sync-Trigger: Live-Describe-Output aus FCSB-Sandbox liefert Feld-Drift oder neue Felder; oder Field-Set-Erweiterung in SF-Setup (z.B. neues SC_*-Feld). Dann via solcom-docs-ingestion ein 0008b-… oder Update mit last-synced-Bump anlegen.