Questa guida è rivolta a sviluppatori e progettisti che devono mantenere, estendere o integrare il sistema Atlas Medical Center. Descrive architettura, stack, convenzioni e flussi principali.
fetch e risposte JSON dove previsto.BASE_URI (vedi index.php).Services/Mail/) per OTP, attivazione medici, reset password, conferma prenotazioni.atlas-medical/
├── index.php # Entry: .env BASE_URI, sessione, bootstrap, router
├── bootstrap.php # Costanti, autoload, Database
├── .env # BASE_URI, APP_READ_ONLY, DB, mail, segreti (non in repo)
├── Core/ # Router, ReadOnlyGuard, AuthGuard, BaseController, Csrf, Database, ErrorHandler
├── Controllers/
│ ├── Auth/ # Login, OTP, Logout, ChangePassword, SetPassword, RequestPasswordReset, ChooseRole
│ ├── Admin/ # Dashboard, Doctor, Patient, Specialization, DoctorLeave, DoctorSlotTemplate
│ ├── Doctor/ # Dashboard, Patient, Visit, Report, Profile
│ ├── Reception/ # Dashboard, Appointments
│ ├── Public/ # Home, Booking, Guida, Storage, Specialization, Doctor
│ └── System/ # SystemController, Setup, AdminUsers, Accounts, ChangePassword, Audit, Commands, …
├── Models/ # Entità dominio e Models/System/
├── Views/ # Template PHP per area + layouts + partials (es. read-only-banner)
├── Services/ # SystemLogger, OtpService, AuditTrailService, Mail, …
├── routes/ # web.php, admin.php, doctor.php, reception.php, auth.php, system_admin.php, …
├── public/ # assets (js, css)
├── storage/ # File caricati (referti, foto medici)
├── docs/ # Guide HTML, markdown architettura, audit, storage
└── sql/ # Script SQL (migrazioni, fix)
index.php legge .env per BASE_URI (prima della sessione, per allineare il path del cookie), imposta i parametri di sessione, avvia la sessione, carica bootstrap.php, registra error handler e shutdown, istanzia il Router(BASE_URI), include tutti i file in routes/ e chiama dispatch().
bootstrap.php carica l’intero .env in $_ENV e definisce tra le altre:
APP_ENV – ambiente (es. local, production).APP_READ_ONLY – booleano da filter_var(..., FILTER_VALIDATE_BOOLEAN): se vero, il router applica ReadOnlyGuard (vedi sotto).ATLAS_PATH – directory radice del progetto (path fisico).BASE_URI – path logico nell’URL (es. /siti/atlas-medical).Autoload PSR-4: namespace root = directory radice progetto. Classe Database con getReader() / getWriter().
Il router gestisce solo GET e POST. All’inizio di Router::dispatch(), dopo resolvePath():
Core/ReadOnlyGuard.php): se APP_READ_ONLY è vero, consente GET, HEAD, OPTIONS; blocca gli altri metodi; per POST consente solo path in whitelist (login, OTP, scelta/switch ruolo). In caso di blocco: JSON 503 con ErrorHandler::jsonError e messaggio Sistema temporaneamente in sola lettura., oppure HTML Views/system/read-only-blocked.php per richieste non-AJAX.Pattern di route:
$router->get('/guida', [GuidaController::class, 'index']);$router->post('#^/admin/doctors/(\d+)/toggle-status$#', [...]); → i gruppi catturati sono argomenti del metodo del controller.CSRF: le richieste POST sono soggette a verifica CSRF, salvo i path in Router::$csrfExempt (es. /login, /set-password). Il token va incluso nei form come _csrf e nelle chiamate AJAX (body o header).
Ordine di caricamento rotte: system.php, web.php, admin.php, doctor.php, roles.php, otp.php, auth.php, reception.php, patient.php, specializations.php, system_admin.php. La prima corrispondenza vince.
PUT/PATCH/DELETE: non sono registrati nel router; in modalità normale si ottiene 405; in sola lettura vengono comunque intercettati dal ReadOnlyGuard prima.
AuthGuard (in Core/):
requireAuth() – Verifica sessione (auth_user_id), per i doctor anche OTP verificato e password aggiornata.requireDoctor() – Richiede auth + doctor_id in sessione.requireRole('admin' | 'super_admin' | 'reception') – Richiede auth e ruolo; il super_admin può accedere alle aree previste per admin/reception/system.Session: dopo il login: auth_user_id, active_role, roles; per i doctor anche doctor_id, otp_verified.
Account disattivati: in LoginController si controlla is_active; se disattivo, errore e nessuna sessione.
Due connessioni PDO: Database::getReader() (SELECT) e Database::getWriter() (INSERT/UPDATE/DELETE). I model ricevono il PDO dal costruttore; i controller usano reader per letture e writer per scritture.
Tabelle principali: doctors, doctor_accounts, patients, appointments, doctor_slots, doctor_slot_templates, doctor_leave_periods, medical_reports, admin_users, specializations, system_actions, system_access_logs, audit_trail, otp_codes, … Schema e moduli in docs/ATLAS_MEDICAL_EVOLUTION_ARCHITECTURE.md.
Convenzione model: namespace Models o Models\System; tipizzazione dove possibile; per le write usare getWriter().
I controller estendono Core\BaseController. Metodi principali:
render($view, $data = [], $useLayout = true)redirect($path)jsonResponse($success, $message, $data = [], $status = 200) – formato success, message, data.Per AJAX: Accept: application/json e/o X-Requested-With: XMLHttpRequest → ErrorHandler::expectsJson() restituisce true (anche per errori centralizzati).
View in Views/ per area; layout in Views/layouts/ (public, admin, doctor, reception, system). Spesso window.APP_CONFIG = { BASE_URI, CSRF } in testata.
Sola lettura: Views/partials/read-only-banner.php è incluso dopo <body> nei layout principali e nella pagina login; mostra un avviso solo se APP_READ_ONLY è vero.
UI: Materialize, Material Icons, CSS in public/assets/css/.
| Servizio | Scopo |
|---|---|
| SystemLogger | system_actions |
| AuditTrailService | audit_trail (old/new, catena) |
| OtpService / OtpMailService | OTP e invio email |
| BookingConfirmationMailService | Conferma prenotazione |
| SlotRecurringService | Slot da template, esclusione assenze |
| SecurityLogger | Eventi sicurezza |
declare(strict_types=1); nei file PHP.jsonResponse / ErrorHandler::jsonError.SystemLogger::log() e, dove previsto, audit.routes/.render().Views/<area>/.jsonResponse.ReadOnlyGuard::ALLOWED_POST_PATHS solo dopo analisi.sql/, model, controller, view, logging/audit se necessario.BASE_URI uguale al path URL dell’app; APP_URL per link nelle email (HTTPS in produzione).true durante migrazione o freeze operativo; false in uso normale. Modifica reversibile senza toccare il codice..env (vedi chiavi DB_* nel progetto).docs/STORAGE_FLUSSO_E_PATCH.md e docs/AUDIT_TECNICO_PRODUZIONE.md).Hosting tipo Aruba: allineare BASE_URI al path pubblicato; abilitare HTTPS; verificare che .env non sia scaricabile; dopo upload file e test, disattivare APP_READ_ONLY.
Guida progettisti Atlas Medical. Per il dettaglio architetturale: docs/ATLAS_MEDICAL_EVOLUTION_ARCHITECTURE.md e docs/Architettura-Atlas-Medical.html (anche dal menu Guide nell’app).