# 🧠 MEMORY.md — Stato Progetto ## Goal - Risolvere login non funzionante dopo fresh install (causa: tinker senza escaping + `2>/dev/null`) - Sostituire tinker per creazione admin con PDO prepared statement + SQL file per schema ## Constraints & Preferences - Laravel 13, PHP 8.4, AdminLTE 4, MySQL/MariaDB (install.sql solo MySQL) - Zero placeholder, zero TODO, codice funzionante - Compatibilità cross-DB MySQL ↔ SQLite (fallback migration per SQLite) ## Progress ### Done - **Creazione `database/install.sql`** — schema MySQL completo + seed data (~1059 righe): - Tutte le 45 tabelle nello stato finale (consolidate da 58 migration) - Seed: 119 diocesi, 54 comuni, 8 tipologie documenti, 8 tipologie eventi, 8 ruoli, 23 permessi Spatie, 2 ruoli Spatie, 3 role preset, 5 email folders, 1 riga app_settings - **NON contiene l'admin** (creato via PDO da install.php) - `SET FOREIGN_KEY_CHECKS=0` per ordine tabelle, riattivato alla fine - **Riscritto `install.php`** — eliminata dipendenza da tinker per la creazione admin: - Aggiunta funzione `createAdminUser()`: PDO prepared statement + `password_hash()` + Spatie role assignment - Fresh Install Apache: importa `install.sql` via `mysql` CLI, poi crea admin via PDO - Fresh Install Docker: copia `install.sql` nel container, importa via mysql CLI, crea admin via script PHP temporaneo con `var_export()` (safe) - Restore: crea admin via PDO se non esiste - Fallback SQLite: mantiene `php artisan migrate --seed` + tinker ma con `var_export()` per escaping - Step 5 rinominato da "MIGRATION E SEED" a "SCHEMA DATABASE E DATI BASE" - Step 6 usa PDO invece di tinker (MySQL) ### In Progress - *(nessuno)* ### Blocked - *(nessuno)* ## Key Decisions - **PDO > tinker**: `createAdminUser()` usa PDO prepared statement con `password_hash()`, niente interpolazione PHP in stringhe shell → zero escaping issues - **`install.sql` > migration sequenziali**: unico file SQL per fresh install, più veloce e debuggabile (si può lanciare `mysql < install.sql` a mano) - **`var_export()` per tinker fallback**: nei rari casi SQLite, si usa `var_export()` che produce stringhe PHP valide con escaping automatico - **`2>/dev/null` rimosso** dal MySQL main path (non serve più, non c'è tinker) - **Docker MySQL credenziali**: hardcoded `mysql:glastree:secret:glastree` (dal docker-compose.mysql.yml) ## Next Steps - *(nessuno)* ## Critical Context - `install.sql` è solo per MySQL. SQLite usa `php artisan migrate --seed` + `DatabaseSeeder` - `DatabaseSeeder` crea ancora admin `admin@glastree.local / password` ma per MySQL viene cancellato dal PDO script - `createAdminUser()` setta `is_admin=1`, `status='active'`, `permissions` completo, `role_preset_id=1`, e Spatie `model_has_roles` con role_id=1 - `password_hash($pass, PASSWORD_BCRYPT)` produce hash `$2y$...` compatibile con `Hash::check()` di Laravel ## Relevant Files - `database/install.sql`: NEW — schema MySQL completo + seed data (1059 righe) - `install.php`: MODIFIED — `createAdminUser()` function + SQL import + PDO admin + Docker/restore adattati