feat(projects-bulk): update_regions handler with bitmask OR/AND-NOT

Refactor ProjectService::bulkAction to accept full payload array and
return structured {updated, skipped, warnings}. Add bulkUpdateRegions
using PG raw bitmask expr (region_mask | add) & ~remove & 255.
Add stubs for bulkUpdateDays/bulkUpdateLimit (Tasks 3-4). Update
controller to pass merged payload and return service result directly.
Un-todo Task-1 region validation test; add regions bitmask test (18/20).
Update phpstan-baseline: actingAs count 5->6, restore match.unhandled.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Дмитрий
2026-05-12 14:48:10 +03:00
parent 08f02100fe
commit 8220a85a5d
4 changed files with 75 additions and 11 deletions
@@ -139,7 +139,7 @@ class ProjectController extends Controller
return response()->json(['data' => new ProjectResource($project->fresh())]);
}
/** POST /api/projects/bulk — batch pause/resume/archive */
/** POST /api/projects/bulk — batch pause/resume/archive/update_regions/update_days/update_limit */
public function bulk(BulkProjectActionRequest $request): JsonResponse
{
$tenantId = $request->user()->tenant_id;
@@ -168,8 +168,16 @@ class ProjectController extends Controller
$ids = $request->validated('ids') ?? [];
}
$updated = $this->projects->bulkAction($tenantId, $action, $ids);
if (count($ids) > 500) {
return response()->json([
'errors' => ['scope' => ['Слишком много проектов под фильтр (>500). Уточните фильтры или выберите вручную.']],
], 422);
}
return response()->json(['updated' => $updated]);
$payload = array_merge($request->validated(), ['ids' => $ids]);
$result = $this->projects->bulkAction($tenantId, $action, $payload);
return response()->json($result);
}
}