Skip to content

fix(reports): yonetici ozeti Son 6 Ay tablosu ay sonunda 3-5 aya dusuyordu - #5

Closed
ersinkoc wants to merge 2 commits into
CodeByPinar:mainfrom
ersinkoc:fix/executive-summary-month-window
Closed

fix(reports): yonetici ozeti Son 6 Ay tablosu ay sonunda 3-5 aya dusuyordu #5
ersinkoc wants to merge 2 commits into
CodeByPinar:mainfrom
ersinkoc:fix/executive-summary-month-window

Conversation

@ersinkoc

@ersinkoc ersinkoc commented Sep 11, 2026

Copy link
Copy Markdown

Hata

Yönetim özetindeki "Son 6 Ay" tablosu (açıılan / kapanan / net), rapor ayın 29–31'ine denk gelen bir günde istendiğinde yanlış pencere üretiyordu:

  • 6 ay yerine en fazla 3 satıra kadar düşüyordu (örn. 2026-05-31 tabanında 4 satır: 2026-02 ve 2026-04 tamamen kayboluyordu),
  • kayıp ayların riskleri açılan/kapanan/net rakamlarında hiç sayılmıyordu,
  • Temmuz 29–31'de SQL penceresinin alt sınırı :since bir ay geriden geliyordu (2026-03-01 yerine 2026-02-01).

Kök neden

reports/executive_summary.php:88-93 pencereyi şöyle kuruyordu:

for ($i = 5; $i >= 0; $i--) {
    $trend[date('Y-m', strtotime("-{$i} month"))] = ['acilan' => 0, 'kapanan' => 0];
}
$since = date('Y-m-01', strtotime('-5 month'));

strtotime('-N month') gün taşmasını kırmaz: hedef ayda o gün yoksa sonuç bir sonraki aya taşar, aynı Y-m anahtarı iki kez üretilir ve map küçülür. PR #1'deki dashboard hatasıyla aynı aile.

Çözüm

Kanıt ve doğrulama

  • Proof (pre-fix, FAIL): geçici proof-script 12 prob gününden 9'unda başarısız — örn. 2026-05-31 rows=4 missing 2026-02,2026-04, 2026-07-31 rows=3 since=2026-03-01 (expected 2026-02-01) (exit 1).
  • Proof (post-fix, PASS): aynı matriste 6/6 satır, hizalı :since (exit 0).
  • Dayanıklı regresyon testi genişletildi: tools/trend_months_test.php artık 25 kontrol ile 6 aylık pencereyi ve yönetici özeti bağlantısını da koruyor (DB gerektirmez: php tools/trend_months_test.php).
  • php -l: temiz. Tam kapı testi (tools/smoke_test.php) bu Windows kutusunda çevresel nedenlerle çalışmıyor (/var/www/riskops + config/database.php + MySQL bekliyor); hatanın bu değişiklikle ilişkisi yok.

Kapsam çiti

Bu PR yalnızca reports/executive_summary.php ve tools/trend_months_test.php dosyalarını değiştirir.

Neden istifli (stacked)?

trend_months_test.php, PR #1'de eklenen recent_months() yardımcısına bağlıdır ve o yardımcı bu PR'ın çitinin dışındadır. Bu yüzden dal, PR #1 dalının (fix/dashboard-trend-month-window) üzerine istiflenmiştir: PR'nin diff'i tam olarak yukarıdaki iki dosyayı gösterir. PR #1 birleştiğinde GitHub bu PR'nin base'ini otomatik olarak main'e çevirir.


Not (upstream): Bu PR fork'tan CodeByPinar/riskops:main'e açılmıştır. Dal, aynı anda açık olan dashboard düzeltmesini de içerir (fix/dashboard-trend-month-window dalındaki commit); o PR birleşene kadar bu PR'nin diff'i dashboard dosyalarını da gösterir. Birleştirme sırası: önce dashboard PR'i, sonra bu PR.


Summary by cubic

Fixes month-end date overflow in trend windows so the dashboard chart and the executive summary's "Last 6 Months" table always show the full 12 or 6 months.

Previously, strtotime('-N month') skipped the target month when the current day (29th–31st) didn't exist there, shrinking windows to as few as 3 rows and dropping months from the opened/closed counts. The window is now built from the new recent_months() helper, which anchors to the 1st of each month, and $since derives from the oldest key.

Bug Fixes

  • api/dashboard_charts.php and reports/executive_summary.php now use recent_months() instead of strtotime('-N month').
  • Adds recent_months() to includes/functions.php; no migration needed.
  • Adds tools/trend_months_test.php with 25 checks covering month-end days, leap years, and consumer wiring; runs without a database.

Written for commit 331929c. 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.
@ersinkoc ersinkoc changed the title fix/executive summary month window fix(reports): yonetici ozeti Son 6 Ay tablosu ay sonunda 3-5 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.

1 issue 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:127">
P2: If `executive_summary.php` keeps `recent_months(6)` but regresses the `:since` boundary, this test still passes. Assert that the consumer derives `$since` from `$monthKeys[0] . '-01'` (or otherwise exercise that boundary) so the reported fix is covered.</violation>
</file>

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

Re-trigger cubic


$srcExec = (string)file_get_contents(__DIR__ . '/../reports/executive_summary.php');
check('reports/executive_summary.php recent_months() kullaniyor',
str_contains($srcExec, 'recent_months(6)'));

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: If executive_summary.php keeps recent_months(6) but regresses the :since boundary, this test still passes. Assert that the consumer derives $since from $monthKeys[0] . '-01' (or otherwise exercise that boundary) so the reported fix is covered.

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 127:

<comment>If `executive_summary.php` keeps `recent_months(6)` but regresses the `:since` boundary, this test still passes. Assert that the consumer derives `$since` from `$monthKeys[0] . '-01'` (or otherwise exercise that boundary) so the reported fix is covered.</comment>

<file context>
@@ -0,0 +1,147 @@
+
+$srcExec = (string)file_get_contents(__DIR__ . '/../reports/executive_summary.php');
+check('reports/executive_summary.php recent_months() kullaniyor',
+    str_contains($srcExec, 'recent_months(6)'));
+check('yonetici ozeti bozuk strtotime ay ifadeleri kaldirildi',
+    !str_contains($srcExec, 'strtotime("-{') && !str_contains($srcExec, "strtotime('-5 month')"));
</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