Architettura¶
GesTask segue il template Yii2 Advanced: più applicazioni con entrypoint,
configurazione, sessione e cookie propri, che condividono il dominio in
common/.
Le applicazioni¶
| Applicazione | Entrypoint | Id | Scopo |
|---|---|---|---|
| Frontend | frontend/web/index.php |
app-frontend |
L'interfaccia degli utenti. Vedi Frontend. |
| Backend | backend/web/index.php |
app-backend |
Il pannello di amministrazione. Vedi Pannello di amministrazione. |
| API | api/web/index.php |
app-api |
API REST v1 senza sessione, server MCP (POST /mcp) ed endpoint OAuth. Vedi API HTTP e Connettore MCP. |
| Console | yii, yii.bat (yii_test per il database di test) |
app-console |
Migrazioni e attività pianificate. Vedi Console. |
L'API è l'unica applicazione che php init non genera: i suoi file sono
versionati, non ha un main-local.php, e YII_ENV si legge con getenv()
(predefinito prod; il debug è attivo solo con dev).
Dove sta la logica¶
controller (frontend, api, backend, console)
│ leggono l'input, controllano i permessi, serializzano
▼
servizi in common/services ← regole di dominio, transazioni, notifiche
│
▼
modelli Active Record + behavior ← validazione, effetti automatici (storia,
numerazione, avanzamento, webhook)
I controller non contengono regole. Una task bloccata non si modifica, un team non resta senza amministratore, una riunione completata è in sola lettura: lo decide il servizio, e quindi vale uguale dal Kanban, dall'API e dalla console. I servizi principali sono descritti nelle pagine del dominio; l'elenco per area è in API HTTP.
Anche le letture delle pagine stanno nei servizi quando servono a più punti
d'ingresso: i numeri delle dashboard (DashboardStats, AdminStats), la
visibilità delle ore (TimesheetService::forViewer()), i team che
l'amministrazione vede (AdminScope). Il connettore MCP aggiunge un ultimo
anello: un tool di Claude esegue l'action dell'API, che chiama il servizio.
Claude ──MCP──▶ api/controllers/McpController ──▶ action v1 ──▶ servizio
Configurazione¶
Ordine di caricamento¶
| Applicazione | File, dal più generale al più specifico |
|---|---|
| Frontend, backend | common/config/main.php → common/config/main-local.php → <app>/config/main.php → <app>/config/main-local.php |
| API | common/config/main.php → common/config/main-local.php → api/config/main.php |
| Console | come frontend e backend, con console/config/ |
yii_test |
common main, main-local, test, test-local, poi console main, main-local, test, test-local |
I params seguono lo stesso ordine (params.php, poi params-local.php, prima
di common e poi dell'applicazione) e si fondono con array_merge.
I file *-local.php non sono versionati: li crea php init a partire da
environments/dev o environments/prod.
Docker¶
Se la variabile DOCKER_ENV è valorizzata, i main-local.php aggiungono
common/config/docker.php. Quel file:
- configura
db,redis,queue(Redis) emailerdalle variabili d'ambiente; - sovrascrive dopo il caricamento i
paramsche dipendono dall'installazione: mittente e destinatari delle email,frontendUrl,backendUrl, chiavi VAPID, server ntfy, token del bot Telegram.
L'elenco completo delle variabili è in Deploy con Docker.
Componenti comuni¶
common/config/main.php definisce:
nameGesTasketimeZoneEurope/Rome, ripetuto in ogni applicazione;authManager:common\rbac\ProtectedDbManager, RBAC su database (vedi Sicurezza);cache:FileCache(ArrayCachenei test);formatterin italiano con formatid/m/Y,d/m/Y H:i,H:i. Non usare i formati estesi (long,medium,full): senzaintlcompleto producono date in inglese;urlManagercon URL "belli" e senza nome dello script;assetManager.appendTimestamp, per invalidare la cache del browser a ogni modifica degli asset.
Il mailer sta nel main-local.php: in sviluppo useFileTransport salva le
email in runtime/mail invece di inviarle.
Parametri da conoscere¶
In common/config/params.php:
| Parametro | A cosa serve |
|---|---|
protectedAccounts |
Account sempre super amministratori e sempre attivi. Vedi Sicurezza. |
teamOverseers |
Account che vedono tutti i team, compresi gli spazi personali. |
masterTokenAdmins |
Account che gestiscono i token API master. |
user.passwordMinLength, user.passwordResetTokenExpire |
8 caratteri, 3600 secondi. |
pushNotifications, ntfy, telegram |
Configurazione dei canali di notifica. |
outboundRequests |
Eccezioni alla protezione SSRF (allowedHosts, allowPrivateNetworks). |
webhooks |
maxAttempts (5) e retentionDays (30) delle consegne. |
trash.retentionDays |
Giorni dopo cui trash/purge elimina definitivamente, con purged_at (30). null: mai. |
audit |
enabled, ignoredModels, retentionDays (365) del registro operazioni. |
attachments.maxSize |
Dimensione massima di un allegato (20 MB). |
mcp |
Indirizzi pubblici di frontend e API (variabili MCP_FRONTEND_URL, MCP_API_URL) e durata dei token OAuth del connettore MCP. |
L'alias @api è definito in common/config/bootstrap.php, quindi anche la
console raggiunge le classi dell'API (lo usa php yii mcp/tools).
Bootstrap comuni¶
Le classi in common/bootstrap/ si caricano in tutte e quattro le applicazioni
(salvo dove indicato):
| Classe | Cosa fa |
|---|---|
MailerBootstrap |
Fa risolvere MailerInterface sul componente mailer, così nei test si usa il mailer di Codeception. |
SecurityHeadersBootstrap |
Solo web. Aggiunge gli header di sicurezza (vedi Sicurezza). |
AccountProtectionBootstrap |
Solo web. Prima di ogni azione riallinea gli account protetti. |
AuditLogBootstrap |
Registra creazioni, modifiche, eliminazioni, cestino, login e logout nel registro operazioni. |
AdminAlertBootstrap |
Raccoglie le task spostate nel cestino durante la richiesta e invia agli amministratori una sola email alla fine. |
Code di lavoro¶
Le operazioni lente (email, notifiche esterne, consegna dei webhook) sono job in
common/jobs/: SendMailJob, SendNotificationJob,
SendExternalNotificationJob, DeliverWebhookJob. Si accodano sempre con
common/services/JobDispatcher::push(), che:
- aspetta il commit della transazione in corso, e scarta il job se la transazione viene annullata;
- usa
Yii::$app->queuese esiste (in Docker: Redis, con il workerphp yii queue/listen); - altrimenti esegue il job subito, nella stessa richiesta. È quello che succede in XAMPP: tutto funziona, ma le richieste che notificano molte persone sono più lente.
Convenzioni del dominio¶
- uuid.
common/behaviors/UuidBehaviorassegna uno uuid v4 prima della validazione. L'id numerico resta chiave primaria ed esterna ma non esce mai: gli URL usano/<controller>/<action>/<uuid>, l'API e i webhook solo uuid. - Serializzazione chiusa. I modelli esposti definiscono
fields()come elenco esplicito: una colonna nuova non finisce nell'API per errore, e i segreti (firma dei webhook, token dei link, destinazioni delle notifiche) non escono mai. - Cestino. I modelli che si possono ripristinare implementano
SoftDeletable(vedi Cestino e registro operazioni).find()esclude da solo gli elementi eliminati. - Permessi nel servizio. Ogni operazione risolve il team della risorsa e chiede a RBAC; vedi Team e ruoli.