feat(reports): restore the documented sample threshold, and draw the chart
MIN_SAMPLE goes back to the specified 10. The reason it had been lowered to 3 was real — a small clinic saw an empty report — but the fix was wrong: three samples do not make an average, and calling that "accurate" is worse than saying nothing. Rows below the threshold are now returned rather than dropped, with severity null and below_min_sample true. That refuses both mistakes: it claims no severity it cannot support, and it does not show a small clinic an empty page that implies everything is fine. They sort after the usable rows and render faded with a "small sample" badge. The utilization page gets its Recharts bar chart. The table stays underneath — six numeric columns are not something a chart answers — but the one question the table is bad at, "which resource is behind", is exactly what a chart is for. Colours come from the design tokens rather than hex, which is where a chart usually breaks in dark mode, and a resource with no calendar is left out entirely: null is not zero, and a zero bar would be a lie. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -97,7 +97,7 @@ class ReportTest extends ApiTestCase
|
||||
$service = $this->service($section, 'لیزر فولبادی', 60);
|
||||
$patient = $this->createUser(['ROLE_USER']);
|
||||
|
||||
for ($i = 1; $i <= 4; $i++) {
|
||||
for ($i = 1; $i <= 10; $i++) {
|
||||
$this->completed($doctor, $patient, $service, (int) $address->getClinicId(), 60, 90, $i);
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ class ReportTest extends ApiTestCase
|
||||
$service = $this->service($section, 'مشاوره', 60);
|
||||
$patient = $this->createUser(['ROLE_USER']);
|
||||
|
||||
for ($i = 1; $i <= 3; $i++) {
|
||||
for ($i = 1; $i <= 10; $i++) {
|
||||
$this->completed($doctor, $patient, $service, (int) $address->getClinicId(), 60, 30, $i);
|
||||
}
|
||||
|
||||
@@ -140,7 +140,13 @@ class ReportTest extends ApiTestCase
|
||||
}
|
||||
|
||||
/** زیر سه نمونه، میانگین معنا ندارد. */
|
||||
public function testASmallSampleIsNotReported(): void
|
||||
/**
|
||||
* ⭐ زیر آستانه **حذف نمیشود، بیشدت برمیگردد**.
|
||||
*
|
||||
* میانگین دو نمونه معنا ندارد و نباید کسی رویش تصمیم بگیرد؛ ولی حذف کاملش یعنی
|
||||
* کلینیک کوچک گزارشی خالی میبیند و فکر میکند همهچیز درست است.
|
||||
*/
|
||||
public function testASmallSampleIsShownWithoutASeverity(): void
|
||||
{
|
||||
[$user, $section, $address, $doctor] = $this->clinic();
|
||||
$service = $this->service($section, 'خدمت کمتکرار', 60);
|
||||
@@ -155,10 +161,15 @@ class ReportTest extends ApiTestCase
|
||||
$user,
|
||||
)['data']['rows'];
|
||||
|
||||
self::assertSame([], array_values(array_filter(
|
||||
$mine = array_values(array_filter(
|
||||
$rows,
|
||||
static fn (array $r): bool => $r['service_uuid'] === $service->getUuid(),
|
||||
)));
|
||||
));
|
||||
|
||||
self::assertCount(1, $mine);
|
||||
self::assertNull($mine[0]['severity'], 'با دو نمونه نباید شدتی ادعا شود');
|
||||
self::assertTrue($mine[0]['below_min_sample']);
|
||||
self::assertSame(2, $mine[0]['sample_size']);
|
||||
}
|
||||
|
||||
public function testAnAccurateServiceHasNoSeverity(): void
|
||||
@@ -167,7 +178,7 @@ class ReportTest extends ApiTestCase
|
||||
$service = $this->service($section, 'خدمت دقیق', 60);
|
||||
$patient = $this->createUser(['ROLE_USER']);
|
||||
|
||||
for ($i = 1; $i <= 3; $i++) {
|
||||
for ($i = 1; $i <= 10; $i++) {
|
||||
$this->completed($doctor, $patient, $service, (int) $address->getClinicId(), 60, 60, $i);
|
||||
}
|
||||
|
||||
@@ -202,7 +213,7 @@ class ReportTest extends ApiTestCase
|
||||
$service = $this->service($section, 'خدمت آستانه', $planned);
|
||||
$patient = $this->createUser(['ROLE_USER']);
|
||||
|
||||
for ($i = 1; $i <= 3; $i++) {
|
||||
for ($i = 1; $i <= 10; $i++) {
|
||||
$this->completed($doctor, $patient, $service, (int) $address->getClinicId(), $planned, $actual, $i);
|
||||
}
|
||||
|
||||
@@ -483,7 +494,7 @@ class ReportTest extends ApiTestCase
|
||||
$service = $this->service($section, 'لیزر', 60);
|
||||
$patient = $this->createUser(['ROLE_USER']);
|
||||
|
||||
for ($i = 1; $i <= 3; $i++) {
|
||||
for ($i = 1; $i <= 10; $i++) {
|
||||
$this->completed($doctor, $patient, $service, (int) $address->getClinicId(), 60, 90, $i);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user