2026-06-01 22:55:50 +02:00
# 🧠 MEMORY.md — Stato Progetto
## Goal
2026-06-03 13:32:04 +02:00
- 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
2026-06-01 22:55:50 +02:00
## Constraints & Preferences
2026-06-03 13:32:04 +02:00
- Laravel 13, PHP 8.4, AdminLTE 4, MySQL/MariaDB (install.sql solo MySQL)
2026-06-02 20:29:47 +02:00
- Zero placeholder, zero TODO, codice funzionante
2026-06-03 13:32:04 +02:00
- Compatibilità cross-DB MySQL ↔ SQLite (fallback migration per SQLite)
2026-06-01 22:55:50 +02:00
## Progress
### Done
2026-06-03 13:32:04 +02:00
- **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)
2026-06-03 16:32:24 +02:00
- **Unified MySQL setup**: singolo tentativo PDO con `dbname` nel DSN — se fallisce (1044/1045/1049), passa automaticamente in root-mode: chiede password root, crea database + utente + GRANT ALL su `localhost` e `%`
- **Sostituito loop 30-retry** con connessione singola PDO (timeout 5s)
2026-06-03 16:23:27 +02:00
- **Fix parse error**: `\$adminName` → `$adminName` in `var_export()` nel ramo SQLite
- **Fix composer**: rimosso `sudo -u www-data` da composer (causa git dubious ownership + permission denied), aggiunto `COMPOSER_ROOT_VERSION=dev-main` ; `vendor` aggiunto al chown finale
2026-06-01 22:55:50 +02:00
### In Progress
2026-06-02 20:29:47 +02:00
- *(nessuno)*
2026-06-01 22:55:50 +02:00
### Blocked
2026-06-02 20:29:47 +02:00
- *(nessuno)*
2026-05-26 08:14:29 +02:00
## Key Decisions
2026-06-03 13:32:04 +02:00
- **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)
2026-06-03 16:23:27 +02:00
- **Composer senza sudo**: `COMPOSER_ROOT_VERSION=dev-main` per evitare git dubious ownership; composer eseguito come utente corrente (root), non più come www-data — dopo, `chown -R www-data vendor` per permessi lettura webserver
2026-06-03 16:32:24 +02:00
- **Unified MySQL setup**: PDO connect con `dbname` nel DSN → se fallisce 1044/1045/1049, root-mode: crea DB + utente + GRANT ALL su `localhost` e `%` + FLUSH
2026-05-26 08:14:29 +02:00
2026-06-01 22:55:50 +02:00
## Next Steps
2026-06-02 22:07:16 +02:00
- *(nessuno)*
2026-05-26 08:14:29 +02:00
2026-06-01 22:55:50 +02:00
## Critical Context
2026-06-03 13:32:04 +02:00
- `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
2026-06-03 16:23:27 +02:00
- Composer ora eseguito come utente corrente (root) con `COMPOSER_ROOT_VERSION=dev-main` per evitare git dubious ownership e permission denied su `vendor/`
- `vendor/` aggiunto al `chown` finale in entrambi i modi (Apache e Restore) per garantire leggibilità da www-data
- `ensureMysqlUserAndDb()` sanitizza input (rimuove `' " \0 \` ) prima di passarli a SQL exec
2026-05-26 08:14:29 +02:00
## Relevant Files
2026-06-03 13:32:04 +02:00
- `database/install.sql` : NEW — schema MySQL completo + seed data (1059 righe)
2026-06-03 16:23:27 +02:00
- `install.php` : MODIFIED — `createAdminUser()` + `ensureMysqlUserAndDb()` + composer fix + auto-create MySQL user