Skip to main content

๐Ÿ”„ Request Lifecycle

Every Request Starts at index.phpโ€‹

  1. Define constants (ROOT, APP, CONFIG)
  2. Load helper functions
  3. Check if installed (does config/database.php exist?)
  4. If not installed โ†’ redirect to /install/
  5. Load DB config + helpers, start session
  6. Compute request path (handles subdirectory installs)
  7. 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 $page and includes layout.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