๐ Request Lifecycle
Every Request Starts at index.phpโ
- Define constants (
ROOT,APP,CONFIG) - Load helper functions
- Check if installed (does
config/database.phpexist?) - If not installed โ redirect to
/install/ - Load DB config + helpers, start session
- Compute request path (handles subdirectory installs)
- Dispatch via
app/router.php
The Routerโ
app/router.php is a flat pattern-matching dispatch table. Patterns are compiled to regex and matched against the request path. Capture groups are passed as controller method arguments.
Authenticationโ
Most controllers call require_auth() which redirects unauthenticated users to /login. Admin-only endpoints use require_admin() which returns 403 JSON.
Sessions are populated on login with user_id, workspace_id, role, and regenerated to prevent session fixation.
Database Connectionโ
PDO connection is created lazily on first query (singleton). Uses ERRMODE_EXCEPTION and real prepared statements (EMULATE_PREPARES = false).
Response Formatsโ
- HTML Pages: Controller sets
$pageand includeslayout.php - JSON APIs:
json_response()sets Content-Type, echoes JSON, exits - SSE Stream: Persistent loop with
text/event-stream, ping every 2s, exits after 55s