ai_upgrade_assistant-0.2.0-alpha2/src/Service/UpdateHistoryService.php

src/Service/UpdateHistoryService.php
<?php

namespace Drupal\ai_upgrade_assistant\Service;

use Drupal\Core\Database\Connection;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\State\StateInterface;
use Drupal\Core\Datetime\DrupalDateTime;

/**
 * Service for tracking update history and outcomes.
 *
 * Maintains a detailed history of all updates, including:
 * - Success/failure status
 * - Duration
 * - Generated patches
 * - Error logs
 * - AI analysis results
 */
class UpdateHistoryService {

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * The state service.
   *
   * @var \Drupal\Core\State\StateInterface
   */
  protected $state;

  /**
   * The logger factory.
   *
   * @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
   */
  protected $loggerFactory;

  /**
   * Table names.
   */
  const HISTORY_TABLE = 'ai_upgrade_assistant_update_history';
  const PATCHES_TABLE = 'ai_upgrade_assistant_update_patches';
  const ERRORS_TABLE = 'ai_upgrade_assistant_update_errors';

  /**
   * Constructs a new UpdateHistoryService.
   *
   * @param \Drupal\Core\Database\Connection $database
   *   The database connection.
   * @param \Drupal\Core\State\StateInterface $state
   *   The state service.
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
   *   The logger factory service.
   */
  public function __construct(
    Connection $database,
    StateInterface $state,
    LoggerChannelFactoryInterface $logger_factory
  ) {
    $this->database = $database;
    $this->state = $state;
    $this->loggerFactory = $logger_factory;
  }

  /**
   * Records the start of an update.
   *
   * @param string $module_name
   *   The module being updated.
   * @param string $from_version
   *   Starting version.
   * @param string $to_version
   *   Target version.
   * @param array $metadata
   *   Additional update metadata.
   *
   * @return int
   *   The update ID.
   */
  public function recordUpdateStart($module_name, $from_version, $to_version, array $metadata = []) {
    $record = [
      'module_name' => $module_name,
      'from_version' => $from_version,
      'to_version' => $to_version,
      'status' => 'in_progress',
      'start_time' => time(),
      'metadata' => serialize($metadata),
    ];

    return $this->database->insert(self::HISTORY_TABLE)
      ->fields($record)
      ->execute();
  }

  /**
   * Records the completion of an update.
   *
   * @param int $update_id
   *   The update ID.
   * @param string $status
   *   The final status ('success' or 'failure').
   * @param array $results
   *   Update results and metrics.
   */
  public function recordUpdateCompletion($update_id, $status, array $results = []) {
    $this->database->update(self::HISTORY_TABLE)
      ->fields([
        'status' => $status,
        'end_time' => time(),
        'results' => serialize($results),
      ])
      ->condition('id', $update_id)
      ->execute();

    // Update success rate metrics
    $this->updateSuccessMetrics($status);
  }

  /**
   * Records generated patches for an update.
   *
   * @param int $update_id
   *   The update ID.
   * @param array $patches
   *   Array of patch information.
   */
  public function recordPatches($update_id, array $patches) {
    foreach ($patches as $patch) {
      $record = [
        'update_id' => $update_id,
        'file_path' => $patch['file'],
        'patch_content' => $patch['content'],
        'ai_confidence' => $patch['confidence'] ?? NULL,
        'status' => $patch['status'],
        'created' => time(),
      ];

      $this->database->insert(self::PATCHES_TABLE)
        ->fields($record)
        ->execute();
    }
  }

  /**
   * Records errors encountered during an update.
   *
   * @param int $update_id
   *   The update ID.
   * @param array $errors
   *   Array of error information.
   */
  public function recordErrors($update_id, array $errors) {
    foreach ($errors as $error) {
      $record = [
        'update_id' => $update_id,
        'error_type' => $error['type'],
        'message' => $error['message'],
        'stack_trace' => $error['trace'] ?? '',
        'timestamp' => time(),
      ];

      $this->database->insert(self::ERRORS_TABLE)
        ->fields($record)
        ->execute();
    }
  }

  /**
   * Gets update history for a module.
   *
   * @param string $module_name
   *   The module name.
   * @param int $limit
   *   Number of records to return.
   *
   * @return array
   *   Update history records.
   */
  public function getModuleHistory($module_name, $limit = 10) {
    return $this->database->select(self::HISTORY_TABLE, 'h')
      ->fields('h')
      ->condition('module_name', $module_name)
      ->orderBy('start_time', 'DESC')
      ->range(0, $limit)
      ->execute()
      ->fetchAll();
  }

  /**
   * Gets detailed information about a specific update.
   *
   * @param int $update_id
   *   The update ID.
   *
   * @return array
   *   Detailed update information.
   */
  public function getUpdateDetails($update_id) {
    $update = $this->database->select(self::HISTORY_TABLE, 'h')
      ->fields('h')
      ->condition('id', $update_id)
      ->execute()
      ->fetchAssoc();

    if (!$update) {
      return NULL;
    }

    // Get patches
    $patches = $this->database->select(self::PATCHES_TABLE, 'p')
      ->fields('p')
      ->condition('update_id', $update_id)
      ->execute()
      ->fetchAll();

    // Get errors
    $errors = $this->database->select(self::ERRORS_TABLE, 'e')
      ->fields('e')
      ->condition('update_id', $update_id)
      ->execute()
      ->fetchAll();

    return [
      'update' => $update,
      'patches' => $patches,
      'errors' => $errors,
    ];
  }

  /**
   * Gets success metrics for updates.
   *
   * @param string $period
   *   Time period ('day', 'week', 'month', 'all').
   *
   * @return array
   *   Success metrics.
   */
  public function getSuccessMetrics($period = 'all') {
    $query = $this->database->select(self::HISTORY_TABLE, 'h')
      ->fields('h', ['status']);

    if ($period !== 'all') {
      $timestamp = strtotime("-1 $period");
      $query->condition('start_time', $timestamp, '>');
    }

    $results = $query->execute()->fetchAll();

    $total = count($results);
    $successful = count(array_filter($results, function ($r) {
      return $r->status === 'success';
    }));

    return [
      'total' => $total,
      'successful' => $successful,
      'success_rate' => $total ? ($successful / $total) * 100 : 0,
      'period' => $period,
    ];
  }

  /**
   * Updates success rate metrics in state.
   *
   * @param string $status
   *   The status of the latest update.
   */
  protected function updateSuccessMetrics($status) {
    $metrics = $this->state->get('ai_upgrade_assistant.success_metrics', [
      'total' => 0,
      'successful' => 0,
    ]);

    $metrics['total']++;
    if ($status === 'success') {
      $metrics['successful']++;
    }

    $this->state->set('ai_upgrade_assistant.success_metrics', $metrics);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc