lotteryAdmin(); abort_if($admin === null, 401); abort_if(! AdminAgentScope::nodeVisibleTo($admin, $agent_node), 403); $service = app(AgentProfileService::class); $profile = AgentProfile::query()->firstOrNew(['agent_node_id' => $agent_node->id]); $parent = $agent_node->parent_id !== null ? AgentNode::query()->find($agent_node->parent_id) : null; return ApiResponse::success([ ...$service->present($profile), 'parent_caps' => $service->parentCapsForNode($parent), 'risk_tags' => $agent_node->risk_tags ?? [], ]); } public function update( AdminAgentProfileUpdateRequest $request, AgentNode $agent_node, AgentProfileService $service, ): JsonResponse { $admin = $request->lotteryAdmin(); abort_if($admin === null, 401); abort_if(! AdminAgentScope::nodeVisibleTo($admin, $agent_node), 403); abort_if(! AdminAgentScope::nodeProfileEditableBy($admin, $agent_node), 403); $parent = $agent_node->parent_id !== null ? AgentNode::query()->find($agent_node->parent_id) : null; $payload = $request->validated(); if ($parent !== null) { $service->assertChildCapabilityGrantsWithinParent($parent, $payload, $admin); } $beforeProfile = AgentProfile::query()->where('agent_node_id', $agent_node->id)->first(); $beforeJson = $beforeProfile !== null ? $service->present($beforeProfile) : []; if ($request->has('risk_tags')) { $agent_node->risk_tags = array_values(array_unique(array_filter( array_map('strval', $request->input('risk_tags', [])), ))); $agent_node->save(); } $profile = $service->upsertForNode($agent_node, $payload, $parent); $afterJson = array_merge($service->present($profile), [ 'risk_tags' => $agent_node->risk_tags ?? [], ]); AuditLogger::recordForAdmin( $admin, $request, moduleCode: 'agent', actionCode: 'agent_profile.update', targetType: 'agent_node', targetId: (string) $agent_node->id, beforeJson: $beforeJson, afterJson: $afterJson, ); $request->attributes->set(RecordAdminApiAudit::ATTRIBUTE_AUDIT_RECORDED, true); return ApiResponse::success($afterJson); } }