"summary":"Extract repeated repository boilerplate (ID extraction, array sanitization, unwrap/normalization) into shared support utilities to eliminate ~290 lines of duplication across 6+ repository files.",
"assumptions":[
"MintyPHP DB layer returns nested arrays with table-name keys (e.g. $row['tenants']).",
"All repositories use the same unwrap, unwrapList, extractIds, and sanitizePositiveIds patterns.",
"A trait or static helper class is the right abstraction — no base repository class needed (repositories are thin)."
"lib/Repository/Access/PermissionRepository.php — ID extraction patterns",
"lib/Repository/Access/UserRoleRepository.php — ID sanitization",
"lib/Repository/Org/UserDepartmentRepository.php — ID sanitization",
"New file: lib/Repository/Support/RepositoryArrayHelper.php"
],
"out":[
"Repository method signatures (public API unchanged)",
"Repository SQL queries (not touched)",
"Service layer changes",
"Frontend changes"
]
},
"guardrails":{
"required_guard_ids":[
"GR-CORE-001",
"GR-LANG-001",
"GR-LANG-002",
"GR-TEST-001",
"GR-TEST-002"
],
"required_quality_gate_ids":[
"QG-001",
"QG-002",
"QG-003",
"QG-006"
]
},
"success_criteria":[
{
"id":"SC-001",
"criterion":"A single RepositoryArrayHelper class exists in lib/Repository/Support/ providing extractIds(), sanitizePositiveIds(), unwrap(), and unwrapList() as static methods."
},
{
"id":"SC-002",
"criterion":"All 6+ repository files use RepositoryArrayHelper instead of inline implementations. No duplicate unwrap/extractIds/sanitize logic remains."
},
{
"id":"SC-003",
"criterion":"Repository public method signatures and return values are identical before and after refactoring (pure internal refactor)."
"criterion":"PHPUnit, PHPStan, Architecture Contract, and CS checks pass green; zero new failures introduced by this task (pre-existing failures are out of scope)."