# Chevereto V4 Architecture Reference > Repository: `github.com/chevereto/chevereto` (branch `4.5`) > Latest release: **4.5.2** (Apr 21, 2026) > License: AGPL-3.0 (Free edition) / Commercial proprietary (Lite/Pro) > Author: Rodolfo Berrios (rodolfo@chevereto.com) --- ## 1. Overview Chevereto is a **self-hosted media-sharing platform** (like Flickr/Imgur) that allows users to run their own image/video hosting website. It has been in development since 2007 and is currently on V4. The codebase is primarily PHP (83.7%) with JavaScript (10.4%) and CSS (5.6%). The project has **921+ stars**, **72+ forks**, and **4 contributors**. It supports multi-tenancy, multi-user, multi-language (30+ languages), and multiple storage backends. --- ## 2. Tech Stack | Category | Technologies | |----------|-------------| | **Language** | PHP 8.2+ | | **Framework** | Chevere (custom PSR-7/PSR-15 framework by same author) | | **Frontend** | Vanilla JavaScript, CSS | | **Database** | MySQL / MariaDB (PDO) | | **Cache** | Redis (primary), file-based fallback (PSR-16) | | **Image Processing** | Imagick, Intervention Image (`intervention/image` ^2.6) | | **Video Processing** | php-ffmpeg (`php-ffmpeg/php-ffmpeg` ^1.2) | | **Router** | Chevere Router (`chevere/router` ^0.9.1) | | **HTTP** | Chevere HTTP (`chevere/http` ^0.7.1), Guzzle PSR-7 | | **Auth** | Firebase JWT (`firebase/php-jwt` ^7.0), Google2FA | | **Mail** | Symfony Mailer with 15+ transport integrations | | **Storage** | AWS SDK S3 (`aws/aws-sdk-php` ^3.336.15), local filesystem | | **EXIF** | php-exif, XMP Metadata Extractor | | **QR Codes** | chillerlan/php-qrcode, Google2FA QR Code | | **Encryption** | phpseclib/phpseclib ^3.0 | | **Testing** | PHPUnit ^9.2, PHPStan ^1.11, Easy Coding Standard ^12.2 | | **Refactoring** | Rector | | **Debug** | PsySH ^0.11, XRdebug, Chevere var-dump | --- ## 3. Directory Structure ``` chevereto/ ├── index.php # Entry point → delegates to app/ ├── .htaccess # Apache rewrite rules ├── LICENSE # AGPL-3.0 │ ├── app/ # Application root │ ├── composer.json # PHP dependencies │ ├── composer.lock │ ├── env-default.php # 100+ default env vars │ ├── configurator.php # Config processor │ ├── upgrading.php # Upgrade screen handler │ ├── phpstan.neon # PHPStan configuration │ ├── phpstan-bootstrap.php │ ├── rector.php # Rector configuration │ │ │ ├── src/ # Modern PSR-4 code (Chevereto\ namespace) │ │ ├── Config/ # Config singleton │ │ ├── Encryption/ # Encrypt/decrypt functions │ │ │ └── functions.php │ │ ├── Http/ # HTTP layer │ │ │ ├── Controllers/Api/V4/ # API V4 controllers (13+) │ │ │ └── Middlewares/ # IP restrict, API key auth, signed req │ │ ├── Legacy/ # Legacy systems (modern namespace) │ │ │ ├── Classes/ # ~40 core domain classes │ │ │ ├── G/ # Global helpers, Gettext, Handler │ │ │ ├── functions.php │ │ │ └── functions-render.php │ │ ├── Tenants/ # Multi-tenant system │ │ ├── Traits/Instance/ # Singleton trait │ │ ├── Vars/ # Immutable superglobal wrappers │ │ └── PCRE.php # PCRE regex enum │ │ │ ├── routes/ # Modern route definitions │ │ ├── api-v4.php # Main API v4 routes │ │ ├── api-v4-admin.php # Admin API routes │ │ ├── api-v4-manager.php # Manager API routes │ │ └── tenants-internal-api-v4.php # Internal tenant API │ │ │ ├── legacy/ # Legacy boot & app code │ │ ├── entrypoints/ │ │ │ └── index.php # Web entry point │ │ ├── load/ # Bootstrap files │ │ │ ├── php-boot.php │ │ │ ├── app.php │ │ │ ├── l10n.php │ │ │ └── integrity-check.php │ │ ├── routes/ # 30+ legacy route handlers │ │ ├── commands/ # 19 CLI commands │ │ └── install/ # Installer │ │ │ ├── schemas/ # Database schemas │ │ ├── mysql-5/ │ │ └── mysql-8/ │ │ │ ├── languages/ # 30+ i18n translation files │ ├── bin/ # CLI entry points │ │ ├── cli, legacy, repl, tenants │ ├── tests/ # PHPUnit tests │ ├── .cache/ │ └── .psysh/ │ ├── content/ # Web-accessible assets │ ├── images/ │ ├── legacy/ │ └── pages/ │ ├── images/ # Default media ├── importing/ # Bulk import scripts ├── sdk/ # Client-side SDK │ ├── pup.js # Upload widget (full) │ └── pup.min.js # Upload widget (minified) │ ├── .github/ # GitHub Actions, templates ├── .package/ # Docker packaging ├── .ecs/ # Easy Coding Standard config ├── .vscode/ # Editor settings └── .tinkerwell/ # Tinkerwell snippets ``` --- ## 4. Architecture & Design Patterns ### 4.1 Dual Codebase (Legacy + Modern Migration) The application is in active transition from legacy procedural code to modern PSR-4 namespaced code: - **Modern**: `app/src/` uses `Chevereto\` namespace, PSR-4 autoloading, proper DI via constructor injection, PHP 8 attributes - **Legacy**: `app/legacy/` and `app/src/Legacy/` contain older procedural code being progressively migrated - Both coexist via Composer autoload and a custom boot sequence The autoload configuration explicitly loads function files to bridge the two worlds: ```json "autoload": { "files": [ "src/Encryption/functions.php", "src/Vars/functions.php", "src/Legacy/functions.php", "src/Legacy/functions-render.php", "src/Legacy/G/functions.php", "src/Legacy/G/functions-render.php", "legacy/load/integrity-check.php", "legacy/load/app.php", "legacy/load/l10n.php" ], "psr-4": { "Chevereto\\": "src/" } } ``` ### 4.2 Request Lifecycle ``` index.php └─→ app/legacy/entrypoints/index.php ├─ Defines ACCESS = 'web' ├─ Requires php-boot.php (framework bootstrap) ├─ Parses URL path from REQUEST_URI ├─ Checks for /upgrading route └─ Calls loaderHandler() → bootstraps app ├─ Loads environment config ├─ Initializes database connection ├─ Sets up cache ├─ Boots routing system └─ Dispatches to appropriate route handler ``` ### 4.3 Environment Configuration All configuration is driven by `CHEVERETO_*` environment variables. Defaults are defined in `app/env-default.php` which returns an associative array of 100+ settings: - **Database**: `CHEVERETO_DB_*` (driver, host, name, user, pass, port, prefix, PDO attrs) - **Cache**: `CHEVERETO_CACHE_*` (driver, host, port, password, key prefix, TTL, stampede) - **Feature Flags**: `CHEVERETO_ENABLE_*` (~50 boolean toggles for features) - **Limits**: `CHEVERETO_MAX_*` (file size, upload size, users, albums, tags, etc.) - **Storage**: Local and S3-compatible - **Encryption**: `CHEVERETO_ENCRYPTION_KEY` - **Multi-tenant**: `CHEVERETO_ENABLE_TENANTS`, `CHEVERETO_TENANT_*` - **External Services**: Akismet, ModerateContent, ProjectArachnid, StopForumSpam - **Binary paths**: exiftool, exiftran, ffmpeg, ffprobe - **Traefik/Proxy**: `CHEVERETO_HOSTNAME`, `CHEVERETO_SERVICE_NAME`, `CHEVERETO_SERVICE_PORT`, `CHEVERETO_PROXY_ENTRYPOINT` - **Debug/Dev**: `CHEVERETO_DEBUG_LEVEL`, `CHEVERETO_ENABLE_DEBUG`, XRdebug integration ### 4.4 Routing **Two routing systems coexist:** #### Modern (Chevere Router) — `app/routes/` Routes are defined using the Chevere Router DSL with middleware chains: ```php use function Chevere\Router\route; use function Chevere\Router\routes; return routes( route( '/_/api/4/config/traefik', GET: TenantsConfigTraefikGet::class, ), )->withAppendMiddleware( RestrictIpAccess::with(allowList: '127.0.0.1,::1,172.16.0.0/12'), TenantsApiKeyAuthorization::class, ); ``` Route files: | File | Prefix | Purpose | |------|--------|---------| | `api-v4.php` | `/api/4/` | Main public API v4 | | `api-v4-admin.php` | `/api/4/` | Admin endpoints (storages) | | `api-v4-manager.php` | `/api/4/` | Manager endpoints (ban users) | | `tenants-internal-api-v4.php` | `/_/api/4/` | Internal tenant management | #### Legacy Routing — `app/legacy/routes/` Uses `Chevereto\Legacy\G\Handler` class with path-based matching. Configurable route slugs are stored in the database settings: ``` Settings constants: ROUTING_REGEX = '([\w_-]+)' ROUTING_REGEX_PATH = '([\w\/_-]+)' ``` Configurable routes: `route_user` (→ `user`), `route_image` (→ `image`), `route_album` (→ `album`), `route_video` (→ `video`), `root_route` (→ `user`). Legacy routes support **virtual routing** — e.g., the video route maps to the image handler: ```php // app/legacy/routes/video.php $route = 'image'; virtualRouteHandleRedirect($route, ..., 'video'); $handler->mapRoute($route); ``` 30+ legacy route handler files: account, album, api, api-v1, captcha-verify, category, connect, dashboard, explore, following, image, importer-jobs, index, install, json, login, logout, moderate, oembed, page, plugin, redirect, search, settings, signup, tag, tag-autocomplete, update, upload, user, user-albums, video, webmanifest. ### 4.5 Attribute-based Controllers (PHP 8 Attributes) Controllers use PHP 8 attributes for HTTP metadata: ```php #[Response( new Status(200), new Header('Content-Type', 'application/json'), )] class TenantsGet extends Controller { public function __construct( private Tenants $tenants, ) {} public function __invoke(): array { return $this->tenants->getTenants(); } } ``` ### 4.6 HTTP Middleware Layer Located in `app/src/Http/Middlewares/`: - **`RestrictIpAccess.php`** — IP allow/deny list enforcement (used on internal tenant API) - **`SignedRequest.php`** — Validates signed request headers for internal communication - **`TenantsApiKeyAuthorization.php`** — API key-based authorization for tenant management - **`Cors.php`** — CORS header handling Middlewares can be applied per-route-group via the Router's `withAppendMiddleware()` method. ### 4.7 Multi-Tenant System Enabled via `CHEVERETO_ENABLE_TENANTS`. Built for SaaS deployment with first-class support: #### Core Classes (`app/src/Tenants/`) | Class | Purpose | |-------|---------| | `Tenant.php` | Single tenant entity (hostname, limits, service config) | | `Tenants.php` | Repository/collection — fetches tenants from DB | | `TenantsConfig.php` | Generates **Traefik** reverse proxy config dynamically | | `TenantsApiKey.php` | API key model for tenant auth | | `TenantPlan.php` | Tenant plan (pricing tier with limits) | #### Traefik Integration The system dynamically generates Traefik configuration so each tenant gets its own virtual host: ```php // TenantsConfig generates: [ 'http' => [ 'routers' => [ 'tenant-{id}' => [ 'rule' => "Host(`{hostname}`)", 'service' => '{service}', 'entryPoints' => ['{entryPoint}'], 'middlewares' => [...], ], ], 'services' => [ '{service}' => [ 'loadBalancer' => [ 'servers' => [['url' => "http://{service}:{port}"]], 'passHostHeader' => true, ], ], ], ], ] ``` #### Tenant API Endpoints All under `Chevereto\Http\Controllers\Api\V4\`: | Endpoint | Method | Purpose | |----------|--------|---------| | `/_/api/4/config/traefik` | GET | Generate Traefik proxy config | | `/_/api/4/tenants` | GET | List all tenants | | `/_/api/4/tenants` | POST | Create tenant | | `/_/api/4/tenants/{id}` | GET | Get single tenant | | `/_/api/4/tenants/{id}` | PATCH | Update tenant | | `/_/api/4/tenants/{id}` | DELETE | Delete tenant | | `/_/api/4/tenants/plans` | GET | List all plans | | `/_/api/4/tenants/plans` | POST | Create plan | | `/_/api/4/tenants/plans/{id}` | GET | Get plan | | `/_/api/4/tenants/plans/{id}` | PATCH | Update plan | | `/_/api/4/tenants/plans/{id}` | DELETE | Delete plan | | `/_/api/4/tenants/auth/verify` | POST | Verify tenant auth | | `/_/api/4/tenants/{id}/user/{id}/password` | PATCH | Reset user password | ### 4.8 Immutable Superglobal Wrappers (Vars namespace) Superglobals are wrapped as **immutable value objects** using an `ImmutableMapTrait`: | Class | Source | Mutable? | |-------|--------|----------| | `EnvVar` | `$_ENV` | Immutable | | `GetVar` | `$_GET` | Immutable | | `PostVar` | `$_POST` | Immutable | | `FilesVar` | `$_FILES` | Immutable | | `CookieVar` | `$_COOKIE` | Mutable (for setting cookies) | Backed by helper functions in `app/src/Vars/functions.php` (e.g., `env()`). ### 4.9 Config Singleton `Chevereto\Config\Config` uses the `AssertStaticInstanceTrait` to enforce a single application configuration instance. Loaded from environment variables via `app/configurator.php` and `app/env-default.php`. ### 4.10 Website Modes: Community vs Personal - **Community mode** (multi-user, default): Full social features — followers, likes, signups, guest uploads, user routing - **Personal mode** (single profile): Disables followers, likes, signups, guest uploads, user routing; maps a single user to a custom route path --- ## 5. Legacy Domain Classes Located in `app/src/Legacy/Classes/` — ~40 classes forming the core domain model: | Class | Purpose | |-------|---------| | `Album.php` | Album CRUD and management | | `ApiKey.php` | API key authentication | | `AssetStorage.php` | Storage for CSS/JS/images with S3 settings | | `Cache.php` | Cache abstraction layer | | `Categories.php` / `Category.php` | Category CRUD | | `Confirmation.php` | Email/account confirmations | | `DB.php` | Database abstraction (PDO wrapper) | | `ExecutableBinary.php` | Checks binary paths/config | | `ExifTool.php` / `ExifTran.php` | EXIF processing via external tools | | `Follow.php` | User follow relationships | | `Image.php` | Image CRUD and metadata | | `ImageConvert.php` / `ImageResize.php` | Image format conversion and resizing | | `Import.php` / `ImporterFilterIterator.php` | Bulk importing from filesystem | | `IpBan.php` | IP ban list enforcement | | `KeyValue.php` / `KeyValueInterface.php` / `KeyValueNull.php` | Key-value store (Null Object pattern) | | `L10n.php` | Locale and localization handling | | `Listing.php` | Paginated data listings | | `LocalStorage.php` / `Storage.php` / `StorageApis.php` | Storage backend abstraction | | `Lock.php` | Mutex/locking mechanism | | `Login.php` | Authentication handling | | `Notification.php` | Notification system | | `Page.php` | Custom pages | | `Palettes.php` | Color palette extraction from images | | `ProjectArachnid.php` | CSAM detection via Project Arachnid | | `Queue.php` | Background job queue | | `RequestLog.php` | Request logging | | `Search.php` | Search functionality | | `Settings.php` | Application settings (DB-persisted) | | `Stat.php` | Statistics tracking | | `Tag.php` / `Tags.php` | Tag CRUD | | `TwoFactor.php` | 2FA authentication | | `Upload.php` / `Uploads.php` | Upload handling and processing | | `User.php` | User CRUD | | `Variable.php` | Variable handling | | `XmpMetadataExtractor.php` | XMP metadata extraction | --- ## 6. Global Helper Functions `app/src/Legacy/G/` provides globally-available functions loaded via Composer's `files` autoload: - **`functions.php`** — Sanitization, formatting, routing helpers, URL building (`get_base_url()`, `get_sorted_url()`), date formatting, string manipulation - **`functions-render.php`** — Template rendering helpers, HTML generation - **`Gettext.php`** — Gettext i18n wrapper class - **`Handler.php`** — Legacy request handler (route dispatch, settings, user context) --- ## 7. Database Schema Schemas stored as SQL files in `app/schemas/`: - `mysql-5/` — MySQL 5.x compatible - `mysql-8/` — MySQL 8.x compatible (with newer features) Database migration is handled via CLI command `database-migrate.php`. **Table prefix**: Configurable via `CHEVERETO_DB_TABLE_PREFIX` (default: `chv_`). Key domain tables (inferred from classes and schema): users, images, albums, categories, tags, storage_apis, api_keys, pages, notifications, stats, ip_bans, follows, queues, request_log, settings, confirmations, tenants, tenant_plans. --- ## 8. Image & Video Processing Pipeline **Image formats supported**: AVIF, JPEG, PNG, BMP, GIF, WEBP **Processing flow**: 1. Upload received → validated (size, type, flood/rate check) 2. EXIF data extracted (ExifTool or PHP exif via `lychee-org/php-exif`) 3. XMP metadata extracted (via `XmpMetadataExtractor`) 4. Image converted/resized as needed (Intervention Image + Imagick) 5. Color palette extracted (`Palettes` class) 6. Watermark applied (if `CHEVERETO_ENABLE_UPLOAD_WATERMARK` is enabled) 7. Thumbnails generated (multiple sizes) 8. Stored to configured storage backend (local or S3) 9. Metadata saved to database **External binary dependencies** (configurable paths): exiftool, exiftran, ffmpeg, ffprobe --- ## 9. Storage Backends ### Architecture Strategy pattern with three main classes: - **`Storage`** (`Chevereto\Legacy\Classes\Storage`) — Main abstraction with static methods for upload/delete - **`AssetStorage`** — Asset-specific storage (CSS, JS) with S3-compatible settings - **`LocalStorage`** — Local filesystem storage ### Backend Types 1. **Local filesystem** — default, stores in `PATH_PUBLIC` 2. **AWS S3** — via `aws/aws-sdk-php ^3.336.15` (configurable: region, bucket, key, secret, endpoint, `use_path_style_endpoint`) 3. **S3-compatible** — Any S3 API provider (DigitalOcean Spaces, MinIO, etc.) ### Storage Settings (DB-persisted) Per-storage config: `account_id`, `account_name`, `api_id`, `bucket`, `key`, `region`, `secret`, `server`, `service`, `url`, `use_path_style_endpoint`, `is_https`, `is_active`. ### CDN Support CDN delivery via external URLs, toggled by `CHEVERETO_ENABLE_CDN`. --- ## 10. Cache Architecture - **Primary driver**: Redis (via `CHEVERETO_CACHE_DRIVER`) - **Fallback**: File-based cache (Scrapbook library) - **PSR compliance**: PSR-16 (cache via `chevere/cache`) - **Configuration**: Host, port, password, key prefix (`chv:` default), TTL (max 86400s), stampede protection - **CLI commands**: `cache-flush.php`, `cache-view.php` --- ## 11. Security & Authentication | Layer | Implementation | |-------|----------------| | **Password hashing** | PHP native `password_hash()` / `password_verify()` | | **2FA** | Google2FA (`pragmarx/google2fa`) with QR codes | | **JWT** | Firebase php-jwt (`firebase/php-jwt ^7.0`) for API auth | | **API Keys** | Database-backed API key authentication | | **IP Bans** | IP-based access control (`IpBan` class + middleware) | | **Rate limiting** | Upload flood protection | | **Signed requests** | For internal/tenant API communication | | **Router secret** | Internal routing verification | | **External anti-abuse** | Akismet (spam), ProjectArachnid (CSAM), StopForumSpam, ModerateContent | | **CORS** | Via middleware | --- ## 12. Mail System Uses Symfony Mailer with DSN-based transport switching. 15+ integrations all configured via `CHEVERETO_MAILER_DSN` environment variable: | Supported Transports | |----------------------| | Amazon SES, AhaSend, Azure, Brevo, Infobip, Mailgun, Mailjet, Mailomat, MailPace, MailerSend, Mailtrap, Mailchimp, Microsoft Graph, Postal, Postmark, Resend, Scaleway, SendGrid, Sweego | --- ## 13. Encryption System Located in `app/src/Encryption/` (`Chevereto\Encryption\Key` namespace): - Encrypts/decrypts sensitive settings (secrets) before persisting to DB - `CHEVERETO_ENCRYPTION_KEY` env var provides the master key - CLI commands: `encrypt-secrets.php`, `decrypt-secrets.php` - Uses `phpseclib/phpseclib ^3.0` for cryptography primitives --- ## 14. CLI System Three CLI entry points in `app/bin/`: - **`cli`** — Modern CLI interface (tenant-aware) - **`legacy`** — Legacy CLI interface - **`repl`** — PsySH interactive shell - **`tenants`** — Tenant management CLI ### CLI Commands (`app/legacy/commands/`) — 19 commands: | Command | Purpose | |---------|---------| | `bulk-importer.php` | Import images from filesystem | | `cache-flush.php` | Flush all cache | | `cache-view.php` | View cache contents | | `cipher.php` | Encryption/decryption tool | | `cron.php` | Scheduled tasks runner | | `database-migrate.php` | Run database migrations | | `decrypt-secrets.php` | Decrypt sensitive settings | | `encrypt-secrets.php` | Encrypt sensitive settings | | `htaccess-checksum.php` | Verify .htaccess integrity | | `htaccess-enforce.php` | Enforce .htaccess rules | | `install.php` | Initial installation | | `js.php` | JavaScript asset management | | `langs.php` | Language file management | | `password-reset.php` | Reset user password | | `setting-get.php` | Get a setting value | | `setting-update.php` | Update a setting | | `stats.php` | View statistics | | `stats-rebuild.php` | Rebuild statistics | | `version.php` | Show version | | `version-installed.php` | Show installed version | --- ## 15. Feature Flags (Key Toggles) From `env-default.php`: | Variable | Default | Purpose | |----------|---------|---------| | `CHEVERETO_ENABLE_API_GUEST` | `false` | Anonymous API access | | `CHEVERETO_ENABLE_API_USER` | `true` | User API access | | `CHEVERETO_ENABLE_BANNERS` | `false` | Advertising banners | | `CHEVERETO_ENABLE_BULK_IMPORTER` | `false` | Bulk import tool | | `CHEVERETO_ENABLE_CAPTCHA` | `true` | CAPTCHA protection | | `CHEVERETO_ENABLE_CDN` | `false` | CDN content delivery | | `CHEVERETO_ENABLE_COOKIE_COMPLIANCE` | `false` | GDPR cookie notice | | `CHEVERETO_ENABLE_FOLLOWERS` | `true` | User follow system | | `CHEVERETO_ENABLE_LIKES` | `true` | Like system | | `CHEVERETO_ENABLE_MODERATION` | `false` | Content moderation | | `CHEVERETO_ENABLE_NOTIFICATIONS` | `true` | Notification system | | `CHEVERETO_ENABLE_TENANTS` | `false` | Multi-tenant mode | | `CHEVERETO_ENABLE_USERS` | `true` | User registration/login | | `CHEVERETO_ENABLE_UPLOAD_URL` | `false` | URL-based uploads | | `CHEVERETO_ENABLE_UPLOAD_WATERMARK` | `false` | Image watermarking | --- ## 16. Editions (Licensing) - **Free** (AGPL-3.0): Core features, community support - **Lite**: Additional features, paid license - **Pro**: All features, commercial license Feature gating in the dashboard UI uses helpers like `badgePaid('lite')` and `inputDisabledPaid('lite')` to conditionally show/hide or disable premium features. Edition tracking lives in `app/.editions`. --- ## 17. Dev Tools & Quality | Tool | Purpose | Config | |------|---------|--------| | **PHPStan** | Static analysis (level 5+) | `app/phpstan.neon` | | **ECS (Easy Coding Standard)** | Code style | `.ecs/` directory | | **Rector** | Automated refactoring | `app/rector.php` | | **PHPUnit** | Unit/integration tests | `app/phpunit-report.xml` | | **XRdebug** | Debug toolbar | `CHEVERETO_XRDEBUG_*` env vars | | **PsySH** | Interactive debug shell | `app/.psysh/` | | **Tinkerwell** | Code snippets | `.tinkerwell/` | --- ## 18. Docker & Deployment - **Docker packaging** in `.package/` directory - **Docker image** via GitHub Packages (`ghcr.io/chevereto/chevereto`) - **Multi-arch**: x86_64 and arm64 - **Docker Compose** via [chevereto/docker](https://github.com/chevereto/docker) repo - **Deployment options**: Pure Docker, Chevereto Docker, VPS, cPanel, Plesk, Installatron, Softaculous, SwiftWave, Cloudron --- ## 19. API Architecture Summary ### API V4 (Modern) | Route Group | Path Prefix | Auth | Routes File | |-------------|-------------|------|-------------| | User API | `/api/4/` | JWT/API Key | `api-v4.php` | | Admin API | `/api/4/` | JWT + admin role | `api-v4-admin.php` | | Manager API | `/api/4/` | JWT + manager role | `api-v4-manager.php` | | Internal Tenant | `/_/api/4/` | IP allow + API Key | `tenants-internal-api-v4.php` | ### Legacy API - Legacy JSON endpoint accessible via `get_base_url('json')` - Used by admin dashboard for CRUD operations on storages --- ## 20. Key Architecture Decisions 1. **Env-var driven config**: All settings via environment variables, no config files to edit 2. **Feature flags everywhere**: Toggle any capability on/off without code changes 3. **Dual routing**: Modern Chevere Router for API V4, legacy routing for web pages 4. **Progressive migration**: Old code lives in `Legacy/` namespaces, being gradually refactored to modern PSR-4 5. **PSR compliance**: PSR-4 (autoload), PSR-7 (HTTP messages), PSR-15 (HTTP handlers), PSR-16 (cache) 6. **Multi-tenant by design**: From database schema to API layer to reverse proxy config 7. **Storage abstraction**: Strategy pattern for local vs S3 vs S3-compatible backends 8. **Mailer abstraction**: Symfony Mailer with DSN-based transport switching 9. **Security layers**: JWT + 2FA + API keys + IP bans + signed requests + rate limiting 10. **Chevere framework**: Custom PHP framework by same author — attribute-based controllers, immutable superglobal wrappers, router with middleware chains 11. **Singleton pattern** for application config (`Config` class) 12. **Null Object pattern** for optional caching (`KeyValueNull`) 13. **Adaptor pattern** for reverse proxy config generation (`TenantsConfig` → Traefik) 14. **Immutable value objects** for superglobals (`EnvVar`, `GetVar`, `PostVar`, etc.)