def updateCommissionProjects()

in app/services/CommissionStatusPropagator.scala [111:176]


    def updateCommissionProjects(newStatus: EntryStatus.Value, commissionId: Int, projectsToVerify: Set[Int] = Set.empty): Future[Seq[Try[Int]]] = {
      val action: DBIO[Seq[(Int, ProjectEntry)]] = ProjectEntry.getProjectsEligibleForStatusChange(newStatus, commissionId)

      dbConfig.db.run(action).flatMap { projectTuples =>
        if (projectTuples.isEmpty) {
          logger.info(s"No projects found needing status update to $newStatus for commission $commissionId")
          Future.successful(Seq.empty)
        } else {
          logger.info(s"Found ${projectTuples.length} projects to update to $newStatus for commission $commissionId")
          logger.info(s"Project IDs to update: ${projectTuples.map(_._1).mkString(", ")}")
          
          // Process updates sequentially using foldLeft
          projectTuples.foldLeft(Future.successful(Seq.empty[Try[Int]])) { case (accFuture, (id, project)) =>
            accFuture.flatMap { acc =>
              val updatedProject = project.copy(status = newStatus)
              
              val updateAction = (for {
                _ <- DBIO.successful(logger.info(s"Starting transaction for project $id"))
                updateCount <- TableQuery[ProjectEntryRow].filter(_.id === id).update(updatedProject)
                _ = logger.info(s"Database update for project $id completed with count: $updateCount")
                verification <- TableQuery[ProjectEntryRow].filter(_.id === id).result.headOption
                _ = verification match {
                  case Some(updated) if updated.status == newStatus => 
                    logger.info(s"Verified project $id is now status: ${updated.status}")
                  case Some(updated) => 
                    logger.warn(s"Project $id status mismatch - expected: $newStatus, actual: ${updated.status}")
                    throw new Exception(s"Project $id status mismatch - expected: $newStatus, actual: ${updated.status}")
                  case None =>
                    logger.error(s"Could not verify project $id - not found after update")
                    throw new Exception(s"Project $id not found after update")
                }
              } yield (updateCount, verification)).transactionally

              dbConfig.db.run(updateAction).map {
                case (count, Some(updated)) if updated.status == newStatus =>
                  val projectSerializer = new ProjectEntrySerializer {}
                  implicit val projectsWrites: Writes[ProjectEntry] = projectSerializer.projectEntryWrites
                  rabbitMqPropagator.tell(
                    ChangeEvent(Seq(projectsWrites.writes(updatedProject)), Some("project"), UpdateOperation()),
                    Actor.noSender
                  )
                  logger.info(s"Successfully updated project $id and sent to RabbitMQ")
                  acc :+ Success(id)
                case (_, Some(updated)) =>
                  logger.error(s"Project $id update verification failed - status mismatch")
                  acc :+ Failure(new Exception(s"Project $id update verification failed"))
                case (_, None) =>
                  logger.error(s"Project $id update verification failed - project not found")
                  acc :+ Failure(new Exception(s"Project $id not found after update"))
              }.recover {
                case err =>
                  logger.error(s"Failed to update project $id", err)
                  acc :+ Failure(err)
              }
            }
          }.map { results =>
            val (successes, failures) = results.partition(_.isSuccess)
            logger.info(s"Update complete: ${successes.length} successes, ${failures.length} failures")
            if (failures.nonEmpty) {
              logger.error(s"Failed project updates: ${failures.map(_.failed.get.getMessage).mkString(", ")}")
            }
            results
          }
        }
      }
    }