Architettura
La divisione moderna app/public, l'albero completo del progetto e come una richiesta fluisce dal browser al database e ritorno.
In questa pagina
Architettura
CBGenesis segue il layout moderno di ColdBox: il codice dell'applicazione รจ completamente separato dalla webroot pubblica, quindi nulla sotto app/ รจ mai direttamente accessibile dal web.
Panoramica a livelli
flowchart TD
A["Browser Request"] --> B
subgraph B["public/ โ Webroot"]
B1["Application.bx โ entry point, bootstraps ColdBox + ORM"]
B2["index.bxm โ front controller"]
B3["includes/ โ Vite compiled assets"]
end
B --> C
subgraph C["app/ โ Application code (not web-accessible)"]
C1["config/ โ ColdBox, Router, CacheBox, WireBox, Scheduler"]
C2["handlers/ โ Controllers, auth, admin, audit log"]
C3["models/ โ Entities, Services"]
C4["views/ + layouts/ โ BXM templates"]
C5["email_templates/ โ Token-based email bodies"]
C6["interceptors/ โ Audit logging hook"]
end
C --> D
subgraph D["resources/ โ Source assets"]
D1["assets/js/ โ Alpine components + stores"]
D2["assets/scss/ โ Bootstrap + custom SCSS"]
D3["database/ โ Migrations + seeders"]
end
D --> E
subgraph E["lib/ โ Dependencies (not source-controlled)"]
E1["coldbox/, testbox/, modules/ โ qb, cbsecurity, cborm, ..."]
end
Tutto ciรฒ a cui un aggressore potrebbe altrimenti navigare direttamente - codice sorgente degli handler, configurazione, template delle viste - semplicemente non vive sotto la webroot. app/Application.bx รจ una guardia di una riga con abort;, mantenuta solo affinchรฉ la convenzione del framework regga anche se un server web venisse mai configurato erroneamente per servire app/ direttamente.
Ciclo di vita della richiesta
Ogni richiesta entra attraverso public/Application.bx, che fa il bootstrap di ColdBox prima di passare il controllo al router e, infine, al tuo handler:
sequenceDiagram
Browser->>+public/Application.bx: HTTP Request
public/Application.bx->>+ColdBox Bootstrap: loadColdbox()
ColdBox Bootstrap->>+Main Handler: onRequestStart
Main Handler->>+Router: Match route
Router->>+Target Handler: Dispatch event
Target Handler->>+Service Layer: Business logic
Service Layer->>+ORM / qb: Data access
Target Handler->>+View / Layout: Render response
View / Layout-->>-Browser: HTML + Vite assets
Main.bx (app/handlers/Main.bx) รจ l'handler a evento implicito collegato in app/config/Coldbox.bx:
onAppInit- eseguesettingService.preFlightCheck(), seminando nel database ogni impostazione dell'app mancanteonRequestStart- caricaprc.settingseprc.authUserper ogni richiestaonException- il gestore delle eccezioni a livello di app
Interceptor
app/config/Coldbox.bx registra tre interceptor applicativi, in quest'ordine:
app/interceptors/AuditLogger.bx scrive nel registro di audit su quattro punti di intercettazione:
| Punto | Registrato |
|---|---|
postAuthentication | Un accesso riuscito |
preLogout | Una disconnessione |
cbSecurity_onInvalidAuthentication | Una richiesta che richiedeva una sessione e non ne aveva nessuna |
cbSecurity_onInvalidAuthorization | Un utente autenticato privo del permesso richiesto |
app/interceptors/RateLimiter.bx si attiva su preProcess - prima del routing, prima di qualsiasi handler - e limita cinque azioni Auth non autenticate (login, registrazione, dimentica/reimposta password, attivazione invito) per IP client. Vedi Rate limiting per le impostazioni e il funzionamento.
app/interceptors/SSOAuthorization.bx gestisce il punto di intercettazione
CBSSOAuthorization di cbSSO. Collega un'identitร provider verificata
al modello utente locale, applica la policy login-versus-linking,
approvvigiona gli utenti quando consentito e crea la sessione cbauth. Vedi
Single sign-on per il flusso di callback e
il motivo per cui cbGenesis usa un handler personalizzato invece dell'integrazione
generica cbAuth di cbSSO.
Aggiungi i tuoi all'array variables.interceptors in Coldbox.bx; si attivano nell'ordine di dichiarazione.
Task pianificati
app/config/Scheduler.bx registra tre task in background giornalieri, ciascuno con onOneServer() e withNoOverlaps() in modo che un deployment multi-istanza esegua ciascuno esattamente una volta:
| Task | Esegue alle | Elimina | Governato da |
|---|---|---|---|
| Purga i token API scaduti | 03:00 | Righe di user_api_tokens oltre la loro expiration | Durata del token impostata al momento dell'emissione da cbApiTokenMaxValidityMonths (default 12 mesi) - vedi Impostazioni dell'app |
| Purga i remember token scaduti | 03:15 | Righe di user_remember_tokens oltre la loro expiration | Scadenza fissa impostata quando il token viene emesso (SecurityService/RememberTokenService) |
| Purga i vecchi registri di audit | 03:30 | Righe di audit_logs piรน vecchie della finestra di conservazione | cbAuditLogRetentionDays (default 90; 0 disabilita la purga) - vedi Impostazioni dell'app |
Tutti e tre chiamano un metodo purgeExpiredTokens()/purgeOlderThan() sul servizio proprietario invece di interrogare direttamente la tabella, cosรฌ la stessa logica di purga รจ raggiungibile (e testabile) al di fuori dello scheduler. Aggiungi un nuovo task nello stesso modo - vedi Estendere l'app.
Albero completo del progetto
cbgenesis/
โโโ app/ Application code
โ โโโ Application.bx Abort-only gate (prevents direct /app access)
โ โโโ config/
โ โ โโโ Coldbox.bx Framework settings, environments, logging
โ โ โโโ Router.bx All application routes
โ โ โโโ CacheBox.bx Cache regions (default, template, sessions, rateLimit)
โ โ โโโ WireBox.bx DI container configuration
โ โ โโโ Scheduler.bx Scheduled tasks
โ โ โโโ modules/ Per-module settings (cbsecurity, cbauth, cborm, ...)
โ โโโ handlers/ Controllers (Auth, Dashboard, Users, Roles, ...)
โ โโโ layouts/ Admin, AuthCenter, AuthSplit, Main
โ โโโ models/
โ โ โโโ BaseEntity.bx ORM base: timestamps, soft delete, memento
โ โ โโโ BaseService.bx Service base: cborm + qb + cache + validation
โ โ โโโ security/ Role, Permission, APIToken, RememberToken,
โ โ โ Passkey, UserActionToken, SecurityService, ...
โ โ โโโ system/ User, Setting, AuditLog + their services
โ โโโ views/ BXM templates, one folder per handler
โ โ โโโ _components/ Reusable UI partials (app, auth, ui)
โ โโโ email_templates/ Token-based email body templates
โ โโโ helpers/ ApplicationHelper.bxm โ global view helpers
โ โโโ interceptors/ AuditLogger, RateLimiter, SSOAuthorization
โโโ public/
โ โโโ Application.bx Entry point โ ColdBox + ORM bootstrap
โ โโโ index.bxm Front controller placeholder
โ โโโ includes/ Vite production build output
โโโ resources/
โ โโโ assets/js/ Alpine entry, stores, components
โ โโโ assets/scss/ Bootstrap + custom SCSS
โ โโโ database/
โ โโโ migrations/ Schema migrations (cfmigrations)
โ โโโ seeds/ AdminData seeder
โโโ tests/
โ โโโ specs/integration/ Full HTTP-level specs
โ โโโ specs/unit/ Entity + service specs
โโโ lib/ Dependencies (gitignored, installed by `box install`)
โโโ runtime/ BoxLang engine config (boxlang.json)
โโโ server.json CommandBox server config (engine, webroot, aliases)
โโโ box.json Package manifest โ deps, scripts
โโโ package.json NPM โ Alpine, Bootstrap, Vite, ESLint
โโโ vite.config.mjs Vite + coldbox-vite-plugin
โโโ .env.example Environment template
Lo stack
| Livello | Tecnologia |
|---|---|
| Runtime | BoxLang 1.0+ (JVM) |
| Framework | ColdBox HMVC (bleeding edge) |
| CLI / Server | CommandBox + BoxLang MiniServer |
| Dependency Injection | WireBox |
| Sicurezza | cbsecurity + cbauth (basata su sessione + JWT) |
| Database | MySQL, MariaDB, PostgreSQL e MSSQL tramite Hibernate ORM (cborm); tutti e quattro i target di database sono supportati e coperti dal workflow di test del database del progetto |
| Query Builder | qb (SQL fluente) |
| Migrazioni | cfmigrations |
| Validazione | cbvalidation |
| cbmailservices | |
| Serializzazione | mementifier |
| Frontend | Bootstrap 5.3 ยท Alpine.js 3.x ยท Vite 6 |
| Icone | Phosphor Duotone |
| Tooltip | Tippy.js |