Skip to content

fix(dashboard): trend grafigi ay sonunda 7-11 aya dusuyordu - #4

Closed
ersinkoc wants to merge 3 commits into
CodeByPinar:mainfrom
ersinkoc:fix/dashboard-trend-month-window
Closed

fix(dashboard): trend grafigi ay sonunda 7-11 aya dusuyordu #4
ersinkoc wants to merge 3 commits into
CodeByPinar:mainfrom
ersinkoc:fix/dashboard-trend-month-window

Conversation

@ersinkoc

@ersinkoc ersinkoc commented Sep 11, 2026

Copy link
Copy Markdown

Hata

Dashboard trend grafiği ("son 12 ay: açılan / kapanan risk") ayın 29–31'ine denk gelen isteklerde yanlış pencere üretiyordu:

  • 12 ay yerine en fazla 7 ay görünüyor,
  • kayıp ayların riskleri hiç sayılmıyordu (hem etiket hem sayaç eksik),
  • SQL penceresinin alt sınırı (:since) bir ay geriden geliyordu.

Kök neden

api/dashboard_charts.php pencereyi şöyle kuruyordu:

for ($i = 11; $i >= 0; $i--) {
    $months[date('Y-m', strtotime("-{$i} month"))] = ['opened' => 0, 'closed' => 0];
}
$since = date('Y-m-01', strtotime('-11 month'));

strtotime('-N month') gün taşmasını kırmaz. Örn. 2026-05-31'de -1 month → "31 Nisan" → normalizasyonla 1 Mayıs'a taşar; aynı Y-m anahtarı iki kez üretilir, map'e çöker. 2026-05-31 örneğinde pencere 12 yerine 7 aya düşer (2025-06, 2025-09, 2025-11, 2026-02, 2026-04 kaybolur).

Çözüm

  • includes/functions.php'e recent_months(int $count, ?int $baseTs = null) eklendi: ay aritmetiği her zaman ayın 1'ine sabitlenir (first day of this month midnight), 1. günden çıkarılan ay asla taşmaz.
  • api/dashboard_charts.php bu yardımcıyı kullanır oldu; $since pencerenin en eski ayının 1'i olarak türetilir.

Kanıt ve doğrulama

  • Proof (pre-fix, FAIL): geçici proof-script 11 prob gününden 9'unda başarısız — ör. 2026-05-31 buckets=7 missing 2025-06,2025-09,2025-11,2026-02,2026-04 since=2025-07-01 (expected 2025-06-01) (exit 1).
  • Proof (post-fix, PASS): aynı prob matrisinde 12/12 kova, hizalı :since (exit 0).
  • Dayanıklı regresyon testi: tools/trend_months_test.php (DB gerektirmez): 22 OK / 0 FAIL — ay sonu günleri, artık yıl (2024-02-29), yıl sınırı, count sınırları (0/1/13/negatif), sıralama, :since türetimi ve uç nokta bağlantısı.
  • php -l: includes/functions.php, api/dashboard_charts.php — hata yok.
  • php tools/smoke_test.php bu Windows geliştirme kutusunda çevresel nedenlerle çalıştırılamıyor (repo /var/www/riskops ve config/database.php + MySQL bekliyor); hata bu değişiklikten bağımsız, fix öncesi ve sonrası aynı.

Not

Aynı hatalı kalıbın başka bir örneği reports/executive_summary.php:93 içinde görüldü (strtotime('-5 month')); tek-issue-per-round disiplini gereği bu PR'a dahil edilmedi — ayrı bir round için kaydedildi.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed dashboard trend charts occasionally displaying fewer than 12 months due to month-end date handling.
    • Trend windows now consistently include the correct chronological sequence of calendar months.
  • Tests
    • Added regression coverage for month-end dates, boundary counts, ordering, and trend-window date ranges.

Summary by cubic

Fixes the dashboard trend chart so it always shows 12 months at month-end; previously it could show 7–11 months because strtotime('-N month') overflows on the 29th–31st.

Bug Fixes

  • Adds recent_months() in includes/functions.php to anchor month arithmetic to the 1st.
  • Updates api/dashboard_charts.php and reports/executive_summary.php to use the helper.
  • Adds tools/trend_months_test.php with 22 checks covering month-end, leap years, year boundaries, and endpoint wiring.

Written for commit f6ea251. Summary will update on new commits.

Review in cubic

Kok neden: strtotime('-N month') gun tasmasini kirmaz. Ayin 29-31'inde
hedef ayda o gun yoksa sonuc bir SONRAKI aya tasiyor; ayni 'Y-m' anahtari
iki kez uretiliyor ve api/dashboard_charts.php'deki 12 aylik trend
penceresi 7-11 aylik map'e cokuyordu. Kayip aylarin riskleri trend
graginde hic sayilmiyor, SQL penceresinin alt siniri (:since) da bir ay
geriden geliyordu.

Cozum: ay aritmetigi ayin 1'ine sabitlenen recent_months() yardimcisi
(includes/functions.php) eklendi; uc nokta bu yardimciyi kullaniyor.
1. gunden cikarilan ay asla tasamaz.

Kanit: .temp_files altindaki proof-script oncesinde 11 prob gununden
9'unda FAIL (buckets=7, since kayik), sonrasi PASS. Dayanikli regresyon
testi tools/trend_months_test.php olarak eklendi (22 kontrol: ay sonu
gunleri, artik yil, yil siniri, count sinirlari, uc nokta baglantisi;
DB gerektirmez, php tools/trend_months_test.php ile calisir).
…yordu

Kok neden (PR #1 ile ailesi): strtotime('-N month') gun tasmasini kirmaz.
Ayin 29-31'inde hedef ayda o gun yoksa sonuc bir SONRAKI aya tasiyor;
reports/executive_summary.php'deki "Son 6 Ay" trend map'i yinelenen
'Y-m' anahtarlarindan 3-5 aya kadar kuculuyordu (2026-05-31 tabaninda
2026-02 ve 2026-04 tamamen kayboluyordu) ve SQL penceresinin alt siniri
Temmuz 29-31'de bir ay geride kaliyordu (2026-03-01 yerine 2026-02-01).

Cozum: pencere ayin 1'ine sabitlenen recent_months(6) ile kuruluyor
(PR #1'de eklenen yardimci); :since degeri en eski ayin 1'inden
turetiliyor.

Kanit: round-owned proof-script oncesinde 12 prob gununden 9'unda FAIL
(rows=3-5, since kayik), sonrasi PASS. Dayanikli regresyon testi
tools/trend_months_test.php genisletildi (25 kontrol: 6 aylik pencere +
yonetici ozeti baglanti guvenligi; DB gerektirmez).

Not: bu dal PR #1 (fix/dashboard-trend-month-window) uzerine istiflidir;
trend_months_test.php recent_months()'a baglidir. PR #1 birlestiginde
base otomatik olarak main'e doner.
fix(reports): yonetici ozeti Son 6 Ay tablosu ay sonunda 3-5 aya dusuyordu
@ersinkoc ersinkoc changed the title fix(dashboard): trend grafigi ay sonunda 7-11 aya dusuyordu fix(dashboard): trend grafigi ay sonunda 7-11 aya dusuyordu Sep 11, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 4 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tools/trend_months_test.php">

<violation number="1" location="tools/trend_months_test.php:94">
P2: At a month rollover, `recent_months(12)` can read a later month than `$now`, making this regression test fail intermittently; the null/default check has the same race. Use one stable base timestamp for the assertions, or explicitly allow the bounded rollover case.</violation>

<violation number="2" location="tools/trend_months_test.php:113">
P2: This `since` check only verifies the helper output, so a future dashboard regression that keeps `recent_months(12)` but uses the wrong `$since` boundary will still pass. Assert the dashboard assignment or extract the boundary calculation into testable code.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic


$now = time();
check('bugun (varsayilan taban): 12 ay',
recent_months(12) === expected_months($now, 12));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: At a month rollover, recent_months(12) can read a later month than $now, making this regression test fail intermittently; the null/default check has the same race. Use one stable base timestamp for the assertions, or explicitly allow the bounded rollover case.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tools/trend_months_test.php, line 94:

<comment>At a month rollover, `recent_months(12)` can read a later month than `$now`, making this regression test fail intermittently; the null/default check has the same race. Use one stable base timestamp for the assertions, or explicitly allow the bounded rollover case.</comment>

<file context>
@@ -0,0 +1,147 @@
+
+$now = time();
+check('bugun (varsayilan taban): 12 ay',
+    recent_months(12) === expected_months($now, 12));
+check('taban null acik gecilirse ayni sonuc',
+    recent_months(12, null) === recent_months(12));
</file context>

/* SQL :since degeri: en eski ayin 1'i (api/dashboard_charts.php tuketimi) */
$keys = recent_months(12, strtotime('2026-05-31 12:00:00'));
check('since = en eski ayin 1\'i (2026-05-31 taban)',
$keys[0] . '-01' === '2025-06-01', $keys[0] . '-01');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This since check only verifies the helper output, so a future dashboard regression that keeps recent_months(12) but uses the wrong $since boundary will still pass. Assert the dashboard assignment or extract the boundary calculation into testable code.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tools/trend_months_test.php, line 113:

<comment>This `since` check only verifies the helper output, so a future dashboard regression that keeps `recent_months(12)` but uses the wrong `$since` boundary will still pass. Assert the dashboard assignment or extract the boundary calculation into testable code.</comment>

<file context>
@@ -0,0 +1,147 @@
+/* SQL :since degeri: en eski ayin 1'i (api/dashboard_charts.php tuketimi) */
+$keys = recent_months(12, strtotime('2026-05-31 12:00:00'));
+check('since = en eski ayin 1\'i (2026-05-31 taban)',
+    $keys[0] . '-01' === '2025-06-01', $keys[0] . '-01');
+
+/* ------------------------------------------------------------------ */
</file context>

@CodeByPinar

Copy link
Copy Markdown
Owner

Teşekkürler. Dört bulguyu da doğruladım, dördü de gerçekti.

Özellikle schema.sql'deki eksik users tablosu ciddiydi: belgelenmiş
kurulumu tamamen kırıyordu ve yeni eklediğim Docker kurulumunu da
bozuyordu (docker-compose.yml şemayı initdb'ye bağlıyor). Yakaladığınız
için teşekkürler.

Düzeltmeleri main'e bağımsız olarak uyguladım (2530ae1). PR'ları merge
etmek yerine yeniden yazmamın iki sebebi var:

  1. PR'lar birbirinin üstüne istiflenmişti ve diff'leri çakışıyordu
    (fix(dashboard): trend grafigi ay sonunda 7-11 aya dusuyordu #1 ile fix(dashboard): trend grafigi ay sonunda 7-11 aya dusuyordu  #4 aynı düzeltmeyi içeriyor, fix(reports): yonetici ozeti Son 6 Ay tablosu ay sonunda 3-5 aya dusuyordu  #5 fix(dashboard): trend grafigi ay sonunda 7-11 aya dusuyordu  #4'ün üstünde duruyor).
  2. cubic'in test dosyalarına yaptığı eleştiriler haklıydı: sabit
    kodlanmış veritabanı parolası, sabit isimli veritabanını DROP etme,
    ilgisiz audit_logs satırlarını silen temizlik.

cubic'in son admin korumasına yaptığı P1 eleştirisini de hesaba kattım:
hedefin admin olup olmadığı artık transaction öncesi anlık görüntüden
değil, kilitli okumadan geliyor. Aksi hâlde hedef bu arada admin'e
yükseltilirse koruma tamamen atlanabilirdi.

Eklenen regresyon testleri:

  • tools/trend_months_test.php 35 OK (veritabanı gerektirmez)
  • tools/last_admin_race_test.php 7 OK (iki süreçli gerçek yarış;
    users tablosunu yedekler, finally bloğunda geri yükler)

#7 açık kalıyor - orada karşılığı olmayan bir test var, kapsamı
kaybetmek istemiyorum. İki P1 kapanınca memnuniyetle merge ederim.

Tekrar teşekkürler, başka bulgunuz olursa memnuniyetle bakarım.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants