solcom / P2503-105 · PR-Review · 2026-05-13 · fixed-point: origin/develop

P2503-105 — Publishing Workflows Konfiguration

NK
Nico Köhle
2 Commits · PR #164160
feature/P2503-105 develop
+799 / −3816 files
Findings: standards=3 hard + 2 judgement · spec=4 hard + 4 scope-creep
Worst: publish-Transition erlaubt unpublished → published ohne Review — bricht das Hard-Review-Gate (PRD-Kernanforderung).

Risk map

safe worth a look needs attention

Standards

web/modules/custom/solcom_editorial/solcom_editorial.module:26 Hard Violation
HardService-Locator \Drupal::service() statt Dependency Injection

Aufruf von \Drupal::service('entity_field.manager') direkt im Hook. Der Skill drupal-module-development nennt das explizit als Anti-Pattern. Für Hooks gilt: zumindest EntityFieldManagerInterface per Service-Container-Closure laden oder via Helper-Service kapseln.

Quelle: .claude/skills/drupal-module-development/SKILL.md § Dependency Injection
web/modules/custom/solcom_editorial/solcom_editorial.info.yml:4 Hard Violation
Hardcore_version_requirement: ^11 statt ^10 || ^11

Skill schreibt für Custom-Module die portable Variante vor, um Modul-Migrationen während Drupal-Majors abzufedern.

Quelle: .claude/skills/drupal-module-development/SKILL.md § .info.yml-Schema
config/sync/user.role.content_manager.yml:16 Judgement Call
JudgementLeerer _core.default_config_hash: ''

Alle anderen Rollen im Repo haben einen berechneten Hash (z. B. content_editor.yml: g-zSnaBXJnH7VoimReFb6KcLjIgHCU-hisiShtZ9hjQ). Ein leerer String deutet auf manuelles YAML statt drush cex. Drupal füllt den Hash beim Import automatisch — funktional unbedenklich, aber Drift-Indikator.

Quelle: .claude/agents/drupal-config-architecture-reviewer.md § Config-Drift-Hinweise
web/modules/custom/solcom_editorial/solcom_editorial.module:34 Judgement Call
JudgementDirekter Aufruf privater Contrib-Funktion _scheduler_content_moderation_integration_states_values()

Underscore-Präfix signalisiert in Drupal "non-public API". Bricht ohne Semver-Warnung wenn das Contrib-Modul die Funktion umbenennt. Besser: gleiche Logik selbst implementieren (Field-Storage-Options-Map filtern auf erlaubte Transitions des aktuellen Moderation-State).

Quelle: Drupal Coding Standards "Functions beginning with underscore are considered private"

Spec

config/sync/workflows.workflow.basic_editorial.yml:51-57 — publish-Transition Kritisch: Implementiert, aber falsch
Hardpublish erlaubt unpublished → published — bricht Hard-Review-Gate

Die publish-Transition hat in from: sowohl in_review als auch unpublished. Laut PRD-Modul 1 Transitions-Tabelle und der Jira-Kommentar-Spec ("Hard-Review: Draft → In Review → Published (kein Shortcut)") soll publish ausschliesslich aus in_review kommen. Mit dem aktuellen Zustand kann content_manager Inhalte ohne Review-Zyklus aus unpublished direkt publizieren.

Quelle: PRD §Modul 1 Transitions-Tabelle + Jira P2503-105 Kommentar Nico Köhle
config/sync/workflows.workflow.basic_editorial.yml:38-44 — create_new_draft Hard: Fehlende Anforderung
Gapcreate_new_draft fehlt published als Quell-State

from: [unpublished, draft] — PRD-Spec verlangt zusätzlich published, damit aus einer veröffentlichten Seite heraus ein neuer Draft für Korrekturen geöffnet werden kann (typischer Redaktions-Workflow).

Quelle: PRD §Modul 1 Transitions-Tabelle
Scheduler-Datumsfeld-Sichtbarkeit (publish_on / unpublish_on) Hard: Fehlende Anforderung
GapDatumsfeld bleibt für content_editor sichtbar

PRD §Modul 3: "Das Scheduler-Datumsfeld wird nur für Rollen mit Publish-Berechtigung angezeigt — content_editor sieht es nicht." Im Diff fehlt eine Field-Permission-Config für publish_on/unpublish_on und ein separates Form-Display je Rolle. Der Hook in solcom_editorial.module versteckt nur publish_state/unpublish_state, nicht die Datumsfelder.

Quelle: PRD §Modul 3 — Scheduler Integration
Tests — fehlen vollständig Hard: Fehlende Anforderung
GapKeine einzige Test-Datei im Diff

PRD §Testing Decisions verlangt explizit Drupal-Integrationstests gegen laufende Instanz (Transitions, Hard-Review-Gate, Scheduler-Feld-Sichtbarkeit, Trash-Permissions, Vacancy-Unberührtheit). CLAUDE.md §Testing Requirements: "New features: MUST cover happy path, error handling, edge cases. PR rejection: No tests = immediate rejection."

Quelle: PRD §Testing Decisions + CLAUDE.md §Testing Requirements
web/modules/custom/solcom_editorial/ — gesamtes Modul Scope Creep: Custom-PHP gegen Spec
CreepCustom-PHP-Modul gegen "kein Custom-PHP"-Vorgabe

Jira-Kommentar Nico Köhle: "Implementierungsmodule (alle Config-only, kein Custom-PHP)". Der hook_form_alter löst zwar ein echtes UX-Problem (Moderation-State-Dropdown zeigt unzulässige Zielzustände), aber das ist nicht spezifiziert. Optionen: (a) Modul behalten und PRD/ADR-Update zur Spec-Korrektur; (b) Modul entfernen, Verhalten via Field-Permissions oder Form-Display-Mode lösen.

Quelle: Jira P2503-105 Kommentar + PRD-Vorgabe "Alle vier Module reine Drupal-Konfiguration (YAML)"
config/sync/core.entity_form_display.node.blog.default.yml Scope Creep
CreepField-Weight-Reorder ohne Spec-Bezug

18 Zeilen geändert (nur weight-Anpassungen plus parent_selection: 1). Keine PRD-Anforderung an Form-Display-Reorder für blog.

Quelle: PRD — kein Eintrag für Form-Display-Anpassung
config/sync/canvas.content_template.node.{blog,page}.full.yml Scope Creep
Creepcomponent_version-Hash-Update

Nicht Teil von P2503-105 — Canvas-Component-Version-Drift, gehört in einen separaten Commit/Story.

Quelle: PRD — keine Canvas-Änderung im Scope
config/sync/system.action.user_{add,remove}_role_action.content_manager.yml Scope Creep
CreepBulk-User-Role-Actions nicht in Spec

Nützlich für Administration, aber unbeauftragt. Auto-generated durch Drupal beim Anlegen einer Rolle — kann bleiben, aber explizit nennen.

Quelle: PRD — keine Bulk-Action-Anforderung