feat: Enhance Support Reply Service with tone instructions and article details

- Added tone instruction retrieval to SupportReplyService.
- Improved user feedback when no relevant article is found.
- Included article URL and tone instruction in LLM prompt.
- Updated response format to include source information.
- Enhanced article management UI with search functionality and editing capabilities.
- Introduced a new API endpoint for nearest articles based on vector search.
- Added confidence badge component to display article confidence levels.
- Implemented tests for article searching, editing, and nearest article API.
- Removed obsolete .htaccess file.
This commit is contained in:
your name
2026-05-13 22:25:45 +02:00
parent c94d3f85e8
commit 9244899f9b
22 changed files with 813 additions and 123 deletions

View File

@@ -0,0 +1,62 @@
<?php
namespace Tests\Feature;
use App\DTOs\ArticleCandidateDTO;
use App\Repositories\Contracts\ArticleRepositoryInterface;
use App\Services\EmbeddingService;
use Mockery;
use Tests\Fakes\FakeArticleRepository;
use Tests\TestCase;
class NearestArticleApiTest extends TestCase
{
public function test_it_returns_nearest_published_articles(): void
{
$embeddingService = Mockery::mock(EmbeddingService::class);
$embeddingService
->shouldReceive('embed')
->once()
->with('Hoe stel ik DNS in?')
->andReturn([0.1, 0.2, 0.3]);
$embeddingService
->shouldReceive('context')
->once()
->andReturn([
'provider_instance_id' => 'instance-1',
'embedding_model' => 'embed-model',
]);
$repository = new FakeArticleRepository;
$repository->candidates = [
new ArticleCandidateDTO(
articleId: 10,
title: 'DNS instellen',
content: 'Open het DNS beheer en voeg de juiste records toe.',
distance: 0.12,
sourceUrl: 'https://example.test/articles/dns'
),
];
$this->app->instance(EmbeddingService::class, $embeddingService);
$this->app->instance(ArticleRepositoryInterface::class, $repository);
$response = $this->getJson('/api/articles/nearest?query=Hoe%20stel%20ik%20DNS%20in%3F&limit=5');
$response
->assertOk()
->assertJsonPath('data.0.article_id', 10)
->assertJsonPath('data.0.title', 'DNS instellen')
->assertJsonPath('data.0.similarity', 0.88)
->assertJsonPath('data.0.content', null)
->assertJsonPath('meta.published_only', true)
->assertJsonPath('meta.embedding_model', 'embed-model');
}
public function test_it_validates_the_search_query(): void
{
$response = $this->getJson('/api/articles/nearest?query=x');
$response->assertStatus(422);
}
}