Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
AIRequestLogService
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
4 / 4
5
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAllPaginated
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 findById
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 regenerate
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace App\Http\Services;
4
5use App\Http\Models\FlyMsgAI\AIRequestLog;
6use App\Http\Repositories\AIRequestLogRepository;
7use Illuminate\Contracts\Pagination\LengthAwarePaginator;
8
9/**
10 * Service for managing AI request log operations.
11 *
12 * Handles listing, viewing, and regenerating AI request logs
13 * for the CMC admin monitoring page.
14 */
15class AIRequestLogService
16{
17    public function __construct(
18        private readonly AIRequestLogRepository $logRepository,
19        private readonly NodeJsAIBridgeService $bridgeService
20    ) {}
21
22    /**
23     * Get paginated AI request logs with optional filters.
24     *
25     * @param  array{
26     *     user_id?: string,
27     *     company_id?: string,
28     *     feature?: string,
29     *     status?: string,
30     *     search?: string,
31     *     sort_order?: string,
32     *     date_from?: string,
33     *     date_to?: string
34     * }  $filters  Optional filter criteria
35     * @param  int  $perPage  Number of items per page
36     */
37    public function getAllPaginated(array $filters = [], int $perPage = 25): LengthAwarePaginator
38    {
39        return $this->logRepository->getAllPaginated($filters, $perPage);
40    }
41
42    /**
43     * Find a single AI request log by ID.
44     *
45     * @param  string  $id  The log entry ID
46     */
47    public function findById(string $id): ?AIRequestLog
48    {
49        return $this->logRepository->findById($id);
50    }
51
52    /**
53     * Re-execute an AI request with modified parameters.
54     *
55     * Reads the original log entry, applies parameter overrides,
56     * and creates a new log entry with regenerated=true.
57     *
58     * @param  string  $id  The original log entry ID to regenerate from
59     * @param  array{
60     *     prompt_input: string,
61     *     provider?: string,
62     *     model?: string,
63     *     temperature?: float,
64     *     max_tokens?: int,
65     *     top_p?: float
66     * }  $params  Modified parameters for regeneration
67     *
68     * @throws \Exception When the original log is not found or AI bridge fails
69     */
70    public function regenerate(string $id, array $params): AIRequestLog
71    {
72        $original = $this->logRepository->findById($id);
73
74        if (! $original) {
75            throw new \Exception('Original AI request log not found.');
76        }
77
78        $provider = $params['provider'] ?? $original->provider;
79        $model = $params['model'] ?? $original->model;
80
81        $payload = [
82            'provider' => $provider,
83            'model' => $model,
84            'prompt' => $params['prompt_input'],
85            'config' => [
86                'maxOutputTokens' => $params['max_tokens'] ?? 4096,
87                'temperature' => $params['temperature'] ?? 1.0,
88                'topP' => $params['top_p'] ?? 0.95,
89            ],
90        ];
91
92        $metadata = [
93            'user_id' => $original->user_id,
94            'company_id' => $original->company_id,
95            'feature' => $original->feature,
96            'context' => $original->context,
97            'regenerated' => true,
98            'regenerated_from_id' => (string) $original->_id,
99        ];
100
101        $this->bridgeService->generate($payload, $metadata);
102
103        // Return the most recently created log (the regenerated one)
104        $logs = $this->logRepository->findByUser($original->user_id, 1);
105
106        return $logs->first();
107    }
108}