A bit of an hacky solution would be to have something like
def getReportsfromId(id : Int, endDate : DateTime) : Box[Seq[(ReportExecution)],Int)] 
it would do two query to the DB.
First, do a select max(id) from RudderSysEvents where  id > ? and executionTimeStamp <= ? 
This would return the limits of the search in database
Then, do
select T.nodeid, T.executiontimestamp, coalesce(C.iscomplete, false) from 
 (select distinct nodeid, executiontimestamp from ruddersysevents where id > ? and id < ?) as T left join 
(select true as isComplete, nodeid, executiontimestamp from 
                     ruddersysevents where id > ? and id < ? and ruleId like  'hasPolicyServer%' and component = 'common' and keyValue = 'EndRun') as C on T.nodeid = C.nodeid and T.executiontimestamp =  C.executiontimestamp

The second query can't return ids, so we need the first
We need to use the limit of the first to prevent leakage of information as reports may arrive between the queries

This may or may not have its place in this repo