Skip to content

fix(database): bos veritabaninda kurulum ERROR 1005 ile kiriliyordu - #3

Closed
ersinkoc wants to merge 1 commit into
CodeByPinar:mainfrom
ersinkoc:fix/fresh-db-bootstrap
Closed

fix(database): bos veritabaninda kurulum ERROR 1005 ile kiriliyordu #3
ersinkoc wants to merge 1 commit into
CodeByPinar:mainfrom
ersinkoc:fix/fresh-db-bootstrap

Conversation

@ersinkoc

@ersinkoc ersinkoc commented Sep 11, 2026

Copy link
Copy Markdown

Hata

README'nin belgelenmiş kurulum akışı (sudo mysql riskops < database/schema.sql + seed.sql) boş bir veritabanında çalışamıyordu — iki yüzeyi olan tek kurulum deliği:

  1. Repoda hiçbir yerde CREATE TABLE users yoktu: schema.sql'in ilk tablosu (departments) FOREIGN KEY (manager_id) REFERENCES users (id) içeriyor, bölüm 10 ise users tablosunu yalnızca ALTER ediyordu (tablo "mevcut" varsayılıyordu). Boş kurulum ERROR 1005 (errno 150) ile ilk tabloda kırılıyordu.
  2. Belgelenmiş ilk admin hiçbir yerde INSERT edilmiyordu: seed.sql yalnızca mevcut admin@riskops.local kaydını UPDATE ediyor; README'nin vaat ettiği ilk giriş hesabı (Admin123456, ilk girişte değişim zorunlu) oluşmuyordu — kurulum sonunda sisteme girilemiyordu.

Çözüm

  • database/schema.sql bölüm 0: CREATE TABLE IF NOT EXISTS users (temel kolonlar; role ENUM varsayılan 'viewer' — en az yetki ilkesi). Bölüm 10'daki IF NOT EXISTS ALTER'lar aynen kaldı: mevcut kurulumlar için yükseltme yolu, bu yüzden dosya idempotent (üst üste çalıştırılabilir).
  • database/seed.sql: belgelenmiş ilk admin INSERT IGNORE ile eklenir (bcrypt hash, must_change_password=1); hemen altındaki mevcut UPDATE onu IT departmanına bağlar.

Kanıt ve doğrulama

Proof-script gerçek schema.sql + seed.sql dosyalarını boşaltılmış bir karalama veritabanında çalıştırdı:

  • Öncesi (FAIL): statement #4: ERROR 1005 ... Can't create table departments (errno: 150).
  • Sonrası (PASS): 10 tablo oluştu; admin rol/durum/parola-değişim-zorunlu doğrulandı; password_verify('Admin123456') true.

Dayanıklı regresyon testi tools/fresh_bootstrap_test.php (yerel MariaDB ister; karalama veritabanını kendisi düşürür): 13 OK / 0 FAIL — boş kurulum ve dosyanın kendi idempotenti (ikinci uygulama: hatasız, admin/ayar kopyası yok).

Mevcut kurulumlarda geriye dönük uyumluluk: düzeltilmiş schema.sql + seed.sql canlı bir veritabanına yeniden uygulandı → temiz no-op.

php tools/smoke_test.php: 58 OK / 1 FAIL (yalnızca /var/www/riskops yerleşim yolu onaylaması — Windows checkout'ta karşılanamaz; işlevsel tüm kontroller geçiyor).

Kapsam çiti

Bu PR yalnızca database/schema.sql, database/seed.sql ve tools/fresh_bootstrap_test.php dosyalarını değiştirir. Dal doğrudan main üzerindendir; diğer açık PR'lara bağımlılığı yoktur.


Summary by cubic

Fixes fresh database installation failing with ERROR 1005 because schema.sql never created the users table, and seed.sql never inserted the documented initial admin account.

  • Adds CREATE TABLE IF NOT EXISTS users with minimal columns; existing ALTERs remain idempotent for upgrades.
  • Inserts the initial admin (admin@riskops.local / Admin123456) with INSERT IGNORE and forces password change.
  • Adds tools/fresh_bootstrap_test.php to verify clean install and re-run idempotency.

Written for commit 370c398. Summary will update on new commits.

Review in cubic

Kok neden: repoda hicbir yerde CREATE TABLE users yoktu; schema.sql'in
ilk tablosu (departments) manager_id uzerinden users(id)'ye FK
iceriyor ve bolum 10 yalnizca ALTER ediyordu. README'nin belgelenmis
kurulum akisi (schema.sql + seed.sql) bos veritabaninda ERROR 1005
(errno 150) ile kiriliyordu. Ikinci yuzey: seed.sql
admin@riskops.local kullanıcısını yalnizca UPDATE ediyor, INSERT eden
yoktu - kurulum sonunda belgelenmis giris hesabi (Admin123456, ilk
giriste degisim zorunlu) olusmuyordu.

Cozum:
- schema.sql bolum 0: CREATE TABLE IF NOT EXISTS users (temel kolonlar;
  role ENUM varsayilan 'viewer' - en az yetki). Bolum 10'daki IF NOT
  EXISTS ALTER'lar yukseltme yolu olarak aynen kaldi (idempotent).
- seed.sql: belgelenmis ilk admin INSERT IGNORE ile eklenir (bcrypt,
  must_change_password=1); mevcut UPDATE onu IT departmanina baglar.

Kanit: round-owned proof-script GERCEK schema.sql + seed.sql dosyalarini
bosaltilmis karalama veritabanina calistirdi: oncesinde FAIL
(statement CodeByPinar#4: ERROR 1005 departments), sonrasi PASS (10 tablo, admin
dogrulandi, password_verify('Admin123456') true).

Dayanikli regresyon testi tools/fresh_bootstrap_test.php eklendi
(yerel MariaDB ister; bos veritabaninda kurulum + ust uste tekrar
calismanin idempotentligi; karalama veritabanini kendisi dusurur):
13 OK / 0 FAIL. Mevcut kurulumda geriye donuk uyumluluk: duzeltilmis
schema+seed canli veritabanina tekrar uygulandi - temiz no-op.
php tools/smoke_test.php: 58 OK / 1 FAIL (yalnizca /var/www/riskops
yerlesim yolu onaylamasi; islevsel tum kontroller geciyor).
@ersinkoc ersinkoc changed the title fix(database): bos veritabaninda kurulum ERROR 1005 ile kiriliyordu fix(database): bos veritabaninda kurulum ERROR 1005 ile kiriliyordu 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.

4 issues found across 3 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/fresh_bootstrap_test.php">

<violation number="1" location="tools/fresh_bootstrap_test.php:31">
P2: The documented Ubuntu setup authenticates MariaDB root through `sudo mysql`, but this test forces TCP root login with a committed password that setup never creates. Read the connection credentials and socket from the environment, or use the configured test database account.</violation>

<violation number="2" location="tools/fresh_bootstrap_test.php:104">
P1: When a developer already has a database named `riskops_bootstrap_test`, this test irreversibly deletes it before running. Generate a unique scratch database per run or refuse to proceed when the fixed name exists.</violation>

<violation number="3" location="tools/fresh_bootstrap_test.php:141">
P2: This check labeled IT only verifies that `department_id` is non-null, so a seed regression linking the admin to Finance or another department still passes. Assert the joined department code is `IT`.</violation>

<violation number="4" location="tools/fresh_bootstrap_test.php:165">
P3: When schema.sql fails (the exact regression this test guards against), later `$pdo->query(...)->fetch()` calls on `users` throw an uncaught PDOException and the script crashes before the final OK/FAIL summary and exit code are printed. Guard the admin/settings and idempotency checks behind a schema-ok condition (or catch PDOException) so a regression yields a clean FAIL result instead of a fatal.</violation>
</file>

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

Re-trigger cubic

exit(1);
}

$root->exec('DROP DATABASE IF EXISTS ' . BOOTSTRAP_TEST_DB);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: When a developer already has a database named riskops_bootstrap_test, this test irreversibly deletes it before running. Generate a unique scratch database per run or refuse to proceed when the fixed name exists.

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

<comment>When a developer already has a database named `riskops_bootstrap_test`, this test irreversibly deletes it before running. Generate a unique scratch database per run or refuse to proceed when the fixed name exists.</comment>

<file context>
@@ -0,0 +1,186 @@
+    exit(1);
+}
+
+$root->exec('DROP DATABASE IF EXISTS ' . BOOTSTRAP_TEST_DB);
+$root->exec('CREATE DATABASE ' . BOOTSTRAP_TEST_DB
+    . ' CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci');
</file context>

if (is_array($u)) {
check('admin rol/durum/parola-degisimi zorunlu',
$u['role'] === 'admin' && (int)$u['status'] === 1 && (int)$u['must_change_password'] === 1);
check('admin departmana bagli (IT)', $u['department_id'] !== null);

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 check labeled IT only verifies that department_id is non-null, so a seed regression linking the admin to Finance or another department still passes. Assert the joined department code is IT.

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

<comment>This check labeled IT only verifies that `department_id` is non-null, so a seed regression linking the admin to Finance or another department still passes. Assert the joined department code is `IT`.</comment>

<file context>
@@ -0,0 +1,186 @@
+    if (is_array($u)) {
+        check('admin rol/durum/parola-degisimi zorunlu',
+            $u['role'] === 'admin' && (int)$u['status'] === 1 && (int)$u['must_change_password'] === 1);
+        check('admin departmana bagli (IT)', $u['department_id'] !== null);
+        check("password_verify('Admin123456')",
+            password_verify('Admin123456', (string)$u['password']));
</file context>
Suggested change
check('admin departmana bagli (IT)', $u['department_id'] !== null);
check('admin departmana bagli (IT)',
(string)$pdo->query('SELECT code FROM departments WHERE id = ' . (int)$u['department_id'])->fetchColumn() === 'IT');

}

const BOOTSTRAP_TEST_DB = 'riskops_bootstrap_test';
const BOOTSTRAP_TEST_ROOT_PASS = 'riskops_local_root';

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: The documented Ubuntu setup authenticates MariaDB root through sudo mysql, but this test forces TCP root login with a committed password that setup never creates. Read the connection credentials and socket from the environment, or use the configured test database account.

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

<comment>The documented Ubuntu setup authenticates MariaDB root through `sudo mysql`, but this test forces TCP root login with a committed password that setup never creates. Read the connection credentials and socket from the environment, or use the configured test database account.</comment>

<file context>
@@ -0,0 +1,186 @@
+}
+
+const BOOTSTRAP_TEST_DB = 'riskops_bootstrap_test';
+const BOOTSTRAP_TEST_ROOT_PASS = 'riskops_local_root';
+
+$expectedTables = [
</file context>

sort($tables2);
check('tablo sayisi degismedi (10)', $tables2 === $expectedTables, count($tables2) . ' tablo');

$adminCount = (int)$pdo->query(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: When schema.sql fails (the exact regression this test guards against), later $pdo->query(...)->fetch() calls on users throw an uncaught PDOException and the script crashes before the final OK/FAIL summary and exit code are printed. Guard the admin/settings and idempotency checks behind a schema-ok condition (or catch PDOException) so a regression yields a clean FAIL result instead of a fatal.

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

<comment>When schema.sql fails (the exact regression this test guards against), later `$pdo->query(...)->fetch()` calls on `users` throw an uncaught PDOException and the script crashes before the final OK/FAIL summary and exit code are printed. Guard the admin/settings and idempotency checks behind a schema-ok condition (or catch PDOException) so a regression yields a clean FAIL result instead of a fatal.</comment>

<file context>
@@ -0,0 +1,186 @@
+sort($tables2);
+check('tablo sayisi degismedi (10)', $tables2 === $expectedTables, count($tables2) . ' tablo');
+
+$adminCount = (int)$pdo->query(
+    "SELECT COUNT(*) FROM users WHERE email = 'admin@riskops.local'"
+)->fetchColumn();
</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