Optimizations + fix failing tests
This commit is contained in:
parent
5a142d2a3c
commit
4412974cfb
7 changed files with 81 additions and 31 deletions
|
|
@ -17,14 +17,25 @@ class FeedsController extends BaseController
|
|||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$feeds = Feed::orderBy('is_active', 'desc')
|
||||
$perPage = min($request->get('per_page', 15), 100);
|
||||
|
||||
$feeds = Feed::with(['language'])
|
||||
->withCount('articles')
|
||||
->orderBy('is_active', 'desc')
|
||||
->orderBy('name')
|
||||
->get();
|
||||
->paginate($perPage);
|
||||
|
||||
return $this->sendResponse(
|
||||
FeedResource::collection($feeds),
|
||||
'Feeds retrieved successfully.'
|
||||
);
|
||||
return $this->sendResponse([
|
||||
'feeds' => FeedResource::collection($feeds->items()),
|
||||
'pagination' => [
|
||||
'current_page' => $feeds->currentPage(),
|
||||
'last_page' => $feeds->lastPage(),
|
||||
'per_page' => $feeds->perPage(),
|
||||
'total' => $feeds->total(),
|
||||
'from' => $feeds->firstItem(),
|
||||
'to' => $feeds->lastItem(),
|
||||
]
|
||||
], 'Feeds retrieved successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -63,14 +63,13 @@ public function store(Request $request): JsonResponse
|
|||
*/
|
||||
public function show(Feed $feed, PlatformChannel $channel): JsonResponse
|
||||
{
|
||||
$route = Route::where('feed_id', $feed->id)
|
||||
->where('platform_channel_id', $channel->id)
|
||||
->with(['feed', 'platformChannel'])
|
||||
->first();
|
||||
|
||||
$route = $this->findRoute($feed, $channel);
|
||||
|
||||
if (!$route) {
|
||||
return $this->sendNotFound('Routing configuration not found.');
|
||||
}
|
||||
|
||||
$route->load(['feed', 'platformChannel']);
|
||||
|
||||
return $this->sendResponse(
|
||||
new RouteResource($route),
|
||||
|
|
@ -84,9 +83,7 @@ public function show(Feed $feed, PlatformChannel $channel): JsonResponse
|
|||
public function update(Request $request, Feed $feed, PlatformChannel $channel): JsonResponse
|
||||
{
|
||||
try {
|
||||
$route = Route::where('feed_id', $feed->id)
|
||||
->where('platform_channel_id', $channel->id)
|
||||
->first();
|
||||
$route = $this->findRoute($feed, $channel);
|
||||
|
||||
if (!$route) {
|
||||
return $this->sendNotFound('Routing configuration not found.');
|
||||
|
|
@ -118,9 +115,7 @@ public function update(Request $request, Feed $feed, PlatformChannel $channel):
|
|||
public function destroy(Feed $feed, PlatformChannel $channel): JsonResponse
|
||||
{
|
||||
try {
|
||||
$route = Route::where('feed_id', $feed->id)
|
||||
->where('platform_channel_id', $channel->id)
|
||||
->first();
|
||||
$route = $this->findRoute($feed, $channel);
|
||||
|
||||
if (!$route) {
|
||||
return $this->sendNotFound('Routing configuration not found.');
|
||||
|
|
@ -145,9 +140,7 @@ public function destroy(Feed $feed, PlatformChannel $channel): JsonResponse
|
|||
public function toggle(Feed $feed, PlatformChannel $channel): JsonResponse
|
||||
{
|
||||
try {
|
||||
$route = Route::where('feed_id', $feed->id)
|
||||
->where('platform_channel_id', $channel->id)
|
||||
->first();
|
||||
$route = $this->findRoute($feed, $channel);
|
||||
|
||||
if (!$route) {
|
||||
return $this->sendNotFound('Routing configuration not found.');
|
||||
|
|
@ -168,4 +161,14 @@ public function toggle(Feed $feed, PlatformChannel $channel): JsonResponse
|
|||
return $this->sendError('Failed to toggle routing configuration status: ' . $e->getMessage(), [], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a route by feed and channel
|
||||
*/
|
||||
private function findRoute(Feed $feed, PlatformChannel $channel): ?Route
|
||||
{
|
||||
return Route::where('feed_id', $feed->id)
|
||||
->where('platform_channel_id', $channel->id)
|
||||
->first();
|
||||
}
|
||||
}
|
||||
|
|
@ -23,9 +23,10 @@ public function toArray(Request $request): array
|
|||
'description' => $this->description,
|
||||
'created_at' => $this->created_at->toISOString(),
|
||||
'updated_at' => $this->updated_at->toISOString(),
|
||||
'articles_count' => $this->when($request->routeIs('api.feeds.*'), function () {
|
||||
return $this->articles()->count();
|
||||
}),
|
||||
'articles_count' => $this->when(
|
||||
$request->routeIs('api.feeds.*') && isset($this->articles_count),
|
||||
$this->articles_count
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
use App\Models\Article;
|
||||
use App\Models\ArticlePublication;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class DashboardStatsService
|
||||
{
|
||||
|
|
@ -76,13 +77,35 @@ private function getDateRange(string $period): ?array
|
|||
*/
|
||||
public function getSystemStats(): array
|
||||
{
|
||||
// Optimize with single queries using conditional aggregation
|
||||
$feedStats = DB::table('feeds')
|
||||
->selectRaw('
|
||||
COUNT(*) as total_feeds,
|
||||
SUM(CASE WHEN is_active = 1 THEN 1 ELSE 0 END) as active_feeds
|
||||
')
|
||||
->first();
|
||||
|
||||
$channelStats = DB::table('platform_channels')
|
||||
->selectRaw('
|
||||
COUNT(*) as total_channels,
|
||||
SUM(CASE WHEN is_active = 1 THEN 1 ELSE 0 END) as active_channels
|
||||
')
|
||||
->first();
|
||||
|
||||
$routeStats = DB::table('routes')
|
||||
->selectRaw('
|
||||
COUNT(*) as total_routes,
|
||||
SUM(CASE WHEN is_active = 1 THEN 1 ELSE 0 END) as active_routes
|
||||
')
|
||||
->first();
|
||||
|
||||
return [
|
||||
'total_feeds' => \App\Models\Feed::count(),
|
||||
'active_feeds' => \App\Models\Feed::where('is_active', true)->count(),
|
||||
'total_channels' => \App\Models\PlatformChannel::count(),
|
||||
'active_channels' => \App\Models\PlatformChannel::where('is_active', true)->count(),
|
||||
'total_routes' => \App\Models\Route::count(),
|
||||
'active_routes' => \App\Models\Route::where('is_active', true)->count(),
|
||||
'total_feeds' => $feedStats->total_feeds,
|
||||
'active_feeds' => $feedStats->active_feeds,
|
||||
'total_channels' => $channelStats->total_channels,
|
||||
'active_channels' => $channelStats->active_channels,
|
||||
'total_routes' => $routeStats->total_routes,
|
||||
'active_routes' => $routeStats->active_routes,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,12 @@ public function up(): void
|
|||
$table->boolean('is_duplicate')->default(false);
|
||||
$table->timestamp('validated_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('url');
|
||||
$table->index('is_valid');
|
||||
$table->index('validated_at');
|
||||
$table->index('created_at');
|
||||
$table->index(['is_valid', 'created_at']);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ public function up(): void
|
|||
->after('is_duplicate');
|
||||
$table->timestamp('approved_at')->nullable()->after('approval_status');
|
||||
$table->string('approved_by')->nullable()->after('approved_at');
|
||||
|
||||
$table->index('approval_status');
|
||||
$table->index(['is_valid', 'approval_status']);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,10 @@ public function test_index_returns_successful_response(): void
|
|||
$response->assertStatus(200)
|
||||
->assertJsonStructure([
|
||||
'success',
|
||||
'data',
|
||||
'data' => [
|
||||
'feeds',
|
||||
'pagination'
|
||||
],
|
||||
'message'
|
||||
]);
|
||||
}
|
||||
|
|
@ -32,7 +35,7 @@ public function test_index_returns_feeds_ordered_by_active_status_then_name(): v
|
|||
$response = $this->getJson('/api/v1/feeds');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$feeds = $response->json('data');
|
||||
$feeds = $response->json('data.feeds');
|
||||
|
||||
// First should be active feeds in alphabetical order
|
||||
$this->assertEquals('A Feed', $feeds[0]['name']);
|
||||
|
|
|
|||
Loading…
Reference in a new issue