refactor: resolve F-08 — extract duplicated dashboard query into StationDataService

Single getLatestReadings() method now shared by MapController,
HomeController, and AuthenticatedSessionController via DI.
This commit is contained in:
root
2026-06-02 23:05:10 +08:00
parent 1bb9c49194
commit 11a2067014
4 changed files with 64 additions and 100 deletions

View File

@@ -8,45 +8,21 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
use Illuminate\Support\Facades\DB;
use App\Models\ActivityLog;
use App\Services\StationDataService;
class AuthenticatedSessionController extends Controller
{
public function __construct(
private StationDataService $stationData
) {}
/**
* Display the login view.
*/
public function create(): View
{
$data = DB::table('station as s')
->leftJoin('rainfall as r', function($join) {
$join->on('r.stationid', '=', 's.stationid')
->whereRaw('r.timestamp = (SELECT MAX(timestamp) FROM rainfall WHERE stationid = s.stationid)');
})
->leftJoin('waterlevel as w', function($join) {
$join->on('w.stationid', '=', 's.stationid')
->whereRaw('w.datetime = (SELECT MAX(datetime) FROM waterlevel WHERE stationid = s.stationid)');
})
->leftJoin('siren as sir', function($join) {
$join->on('sir.stationid', '=', 's.stationid')
->whereRaw('sir.active_time = (SELECT MAX(active_time) FROM siren WHERE stationid = s.stationid)');
})
->whereNotNull('s.lat')
->whereNotNull('s.lng')
->where(function($query) {
$query->whereNotNull('r.hourly')
->orWhereNotNull('w.waterlevel');
})
->select(
's.*',
'r.hourly as rainfall_value',
'r.timestamp as rainfall_time',
'w.waterlevel as waterlevel_value',
'w.datetime as waterlevel_time',
'sir.level as siren_level',
'sir.active_time as siren_time'
)
->orderBy('s.stationid','asc')->get();
$data = $this->stationData->getLatestReadings();
return view('layout.dashboard', compact('data'));
}

View File

@@ -2,43 +2,17 @@
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use App\Services\StationDataService;
class HomeController extends Controller
{
public function __construct(
private StationDataService $stationData
) {}
public function index()
{
$data = DB::table('station as s')
->leftJoin('rainfall as r', function($join) {
$join->on('r.stationid', '=', 's.stationid')
->whereRaw('r.timestamp = (SELECT MAX(timestamp) FROM rainfall WHERE stationid = s.stationid)');
})
->leftJoin('waterlevel as w', function($join) {
$join->on('w.stationid', '=', 's.stationid')
->whereRaw('w.datetime = (SELECT MAX(datetime) FROM waterlevel WHERE stationid = s.stationid)');
})
->leftJoin('siren as sir', function($join) {
$join->on('sir.stationid', '=', 's.stationid')
->whereRaw('sir.active_time = (SELECT MAX(active_time) FROM siren WHERE stationid = s.stationid)');
})
->whereNotNull('s.lat')
->whereNotNull('s.lng')
->where(function($query) {
$query->whereNotNull('r.hourly')
->orWhereNotNull('w.waterlevel');
})
->select(
's.*',
'r.hourly as rainfall_value',
'r.timestamp as rainfall_time',
'w.waterlevel as waterlevel_value',
'w.datetime as waterlevel_time',
'sir.level as siren_level',
'sir.active_time as siren_time'
)
->orderBy('s.stationid', 'asc')
->get();
$data = $this->stationData->getLatestReadings();
return view('layout.dashboard', compact('data'));
}
}

View File

@@ -4,10 +4,14 @@ namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Services\StationDataService;
class MapController extends Controller
{
// Function Retrieve Data From Stations Table
public function __construct(
private StationDataService $stationData
) {}
public function getStations()
{
$stations = DB::table('station')
@@ -19,41 +23,9 @@ class MapController extends Controller
return response()->json($stations);
}
// Function Retrive Current Reading For Each Stations
public function getCurrentData()
{
$data = DB::table('station as s')
->leftJoin('rainfall as r', function($join) {
$join->on('r.stationid', '=', 's.stationid')
->whereRaw('r.timestamp = (SELECT MAX(timestamp) FROM rainfall WHERE stationid = s.stationid)');
})
->leftJoin('waterlevel as w', function($join) {
$join->on('w.stationid', '=', 's.stationid')
->whereRaw('w.datetime = (SELECT MAX(datetime) FROM waterlevel WHERE stationid = s.stationid)');
})
->leftJoin('siren as sir', function($join) {
$join->on('sir.stationid', '=', 's.stationid')
->whereRaw('sir.active_time = (SELECT MAX(active_time) FROM siren WHERE stationid = s.stationid)');
})
->whereNotNull('s.lat')
->whereNotNull('s.lng')
->where(function($query) {
$query->whereNotNull('r.hourly')
->orWhereNotNull('w.waterlevel');
})
->select(
's.*',
'r.hourly as rainfall_value',
'r.timestamp as rainfall_time',
'w.waterlevel as waterlevel_value',
'w.datetime as waterlevel_time',
'sir.level as siren_level',
'sir.active_time as siren_time'
)
->orderBy('s.stationid','asc')->get();
$data = $this->stationData->getLatestReadings();
return view('layout.dashboard', compact('data'));
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Services;
use Illuminate\Support\Facades\DB;
class StationDataService
{
public function getLatestReadings()
{
return DB::table('station as s')
->leftJoin('rainfall as r', function ($join) {
$join->on('r.stationid', '=', 's.stationid')
->whereRaw('r.timestamp = (SELECT MAX(timestamp) FROM rainfall WHERE stationid = s.stationid)');
})
->leftJoin('waterlevel as w', function ($join) {
$join->on('w.stationid', '=', 's.stationid')
->whereRaw('w.datetime = (SELECT MAX(datetime) FROM waterlevel WHERE stationid = s.stationid)');
})
->leftJoin('siren as sir', function ($join) {
$join->on('sir.stationid', '=', 's.stationid')
->whereRaw('sir.active_time = (SELECT MAX(active_time) FROM siren WHERE stationid = s.stationid)');
})
->whereNotNull('s.lat')
->whereNotNull('s.lng')
->where(function ($query) {
$query->whereNotNull('r.hourly')
->orWhereNotNull('w.waterlevel');
})
->select(
's.*',
'r.hourly as rainfall_value',
'r.timestamp as rainfall_time',
'w.waterlevel as waterlevel_value',
'w.datetime as waterlevel_time',
'sir.level as siren_level',
'sir.active_time as siren_time'
)
->orderBy('s.stationid', 'asc')
->get();
}
}