VOOZH about

URL: https://deepwiki.com/mathsgod/light/2-architecture

⇱ Architecture | mathsgod/light | DeepWiki


Loading...
Last indexed: 31 January 2026 (cf9511)
Menu

Architecture

Purpose and Scope

This document describes the overall system architecture of the Light framework, including its layered design, major components, and how they interact. It covers the structural organization of the codebase, the request processing pipeline, and the dependency injection system that ties everything together.

For detailed information about specific subsystems, see:

  • Core application kernel implementation: 3
  • GraphQL API design: 4
  • Authentication and authorization systems: 5
  • Data persistence layer: 6
  • File storage architecture: 7

Layered Architecture Overview

The Light framework implements a classic layered architecture with clear separation of concerns. Each layer has specific responsibilities and communicates through well-defined interfaces.


Sources: src/App.php1-941

Core Components

The following table lists the primary components and their responsibilities:

ComponentClass/NamespaceResponsibility
Application KernelLight\AppCentral orchestrator, implements PSR-15 middleware and request handler
HTTP ServerLight\ServerPSR-15 server wrapper, middleware pipeline
GraphQL EngineTheCodingMachine\GraphQLiteSchema generation and query execution
AuthenticationAuth\ServiceJWT token validation and user context
AuthorizationLight\RbacRole-based access control
Data ModelsLight\ModelBase class for all database models
Database LayerLight\DbDatabase abstraction over Laminas\Db
File StorageLeague\Flysystem\MountManagerMulti-backend file storage
CacheSymfony\CachePSR-6/PSR-16 caching
DI ContainerLeague\Container\ContainerDependency injection

Sources: src/App.php38-147 composer.json10-36

Application Kernel: Light\App

The Light\App class serves as the central orchestrator and is the most important component in the system. It implements both MiddlewareInterface and RequestHandlerInterface from PSR-15, allowing it to act as both middleware and a request handler.


The App constructor performs extensive initialization:

  1. Timezone Configuration: Sets timezone from TZ environment variable
  2. Container Setup: Creates League\Container\Container instance
  3. Server Initialization: Creates Light\Server and pipes itself as middleware
  4. Controller Registration: Registers all controllers in the container
  5. Model Configuration: Sets static container reference for models
  6. Cache Setup: Configures caching based on development/production mode
  7. GraphQL Factory: Initializes SchemaFactory with namespaces and type mappers
  8. RBAC Loading: Loads roles and permissions from YAML and database
  9. Menu Loading: Loads menu structure from YAML and configuration
  10. Filesystem Setup: Configures MountManager with all filesystem backends

Sources: src/App.php59-147

Dependency Injection Container

The framework uses League\Container for dependency injection. Services are registered in the container during application initialization and can be resolved with autowiring support.


Key registration patterns:

  • Singleton services: App, Rbac, MountManager registered once
  • Per-request services: ServerRequestInterface, Auth\Service registered on each request
  • Factory functions: Used for services requiring custom initialization (e.g., FileManagerController)

Sources: src/App.php68-103 src/App.php365-366 src/App.php533-535

Request Processing Pipeline

The Light framework processes HTTP requests through a three-phase pipeline: request preprocessing, GraphQL execution, and response generation.


Phase 1: Request Preprocessing (src/App.php500-537):

  • Returns empty response for OPTIONS requests
  • Parses JSON request body if not already parsed
  • Processes file uploads via GraphQL upload middleware
  • Initializes Auth\Service to extract and validate JWT tokens
  • Injects authentication and authorization services into SchemaFactory
  • Stores request and auth service in container

Phase 2: GraphQL Execution (src/App.php154-170 src/App.php567-579):

  • Extracts GraphQL query and variables from request body
  • Creates GraphQL schema from factory
  • Executes query with context
  • Returns execution result with errors if any

Phase 3: Response Generation (src/App.php154-170):

  • Serializes execution result to JSON
  • Includes debug information in development mode
  • Applies UTF-8 encoding flags
  • Returns PSR-7 JsonResponse

Sources: src/App.php500-537 src/App.php154-170 src/App.php567-579

Component Initialization Flow

The initialization sequence ensures all dependencies are available when needed:


Sources: src/App.php59-147

RBAC Integration

The RBAC (Role-Based Access Control) system is loaded during application initialization and integrated into the GraphQL execution pipeline:


The RBAC system supports:

  • Hierarchical roles: Roles can inherit from parent roles
  • Multiple permission sources: YAML files, database, and dynamic discovery
  • Field-level authorization: @Right annotations on GraphQL fields
  • Method-level authentication: @Logged annotations requiring login
  • Wildcard permissions: Administrator role gets #administrators permission
  • User-specific permissions: Direct permission grants to users

Sources: src/App.php306-366 src/App.php392-472 src/App.php529-530

File Storage Architecture

The file storage system uses Flysystem's MountManager to provide a unified interface across multiple storage backends:


Each filesystem is mounted with a unique prefix (e.g., local://, s3://), enabling location-based routing. The MountManager aggregates all configured filesystems and provides operations like has(), read(), write(), and mimeType() that work across backends.

The Drive class wraps a filesystem configuration with additional metadata, while the Node interface provides a common abstraction for files and folders.

Sources: src/App.php134-147 src/App.php695-787 src/App.php834-839

GraphQL Schema Generation

The GraphQL schema is generated at runtime using GraphQLite's annotation-based approach:


The schema factory:

  1. Scans the Light namespace for annotated classes
  2. Uses reflection to discover queries, mutations, and types
  3. Applies custom type mappers for Light\Db models
  4. Injects authentication and authorization services
  5. Caches the generated schema (15 seconds in dev, permanent in prod)

Sources: src/App.php121-127 src/App.php529-530 src/App.php577-578

Configuration Management

Configuration is sourced from multiple locations with different scopes:

SourcePurposeWhen LoadedExamples
.env fileSecrets and environment-specific settingsStartupJWT_SECRET, DATABASE_*, OAuth client IDs
Config modelRuntime-configurable settingsOn accessmode, access_token_expire, fs, menus
YAML filesStructural definitionsStartuppermissions.yml, menus.yml
db.jsonDatabase schemaCLI commandsTable definitions, relationships

The Config model provides a key-value store in the database:


Sources: src/App.php64-66 src/App.php106-119 src/App.php174-191 src/App.php338-343

Routing and Entry Points

The framework provides two primary entry points:

HTTP Server (src/App.php843-922):

  • Serves GraphQL API at the base path
  • File access routes: /fs/{protocol}/{path} and /drive/{index}/{path}
  • Token refresh endpoint: /refresh_token
  • Uses League\Route for routing with Light\Server wrapper

CLI Tool (bin/light):

  • Symfony Console-based commands
  • Database management: db:install
  • Code generation: make:model, make:controller, make:input, make:ts

The Light\Server class wraps Laminas Stratigility for PSR-15 middleware pipeline processing.

Sources: src/App.php843-922 composer.json55

Development vs Production Mode

The application adjusts behavior based on the mode configuration:

AspectDevelopmentProduction
Schema cache lifetime15 secondsPermanent (until code change)
GraphQL debug infoIncluded (traces, messages)Excluded
Default modeUsed if config unavailableN/A

Mode is determined by checking Config.mode value during initialization:


Sources: src/App.php106-119 src/App.php160-164 src/App.php581-584

Event System

The application implements EventDispatcherAware from League\Event, enabling event-driven architecture for extensibility:


This allows subsystems (particularly the file system) to dispatch events like FolderCreating, FileWriting, NodeMoving, and FileUploading for custom validation or processing logic.

Sources: src/App.php38-41