Skip to content

Backend Architecture

The Stratpoint Timesheet Application backend is built on Laravel 8.x, following modern PHP development practices and architectural patterns. This section provides detailed information about the backend structure, design patterns, and implementation details.

Application Structure

Directory Organization

app/
├── Console/              # Artisan commands
├── Exceptions/           # Exception handlers
├── Http/                 # HTTP layer components
│   ├── Controllers/      # Request controllers
│   ├── Middleware/       # HTTP middleware
│   ├── Requests/         # Form request validation
│   ├── Resources/        # API resource transformers
│   ├── Services/         # Business logic services
│   └── Traits/          # Reusable traits
├── Jobs/                # Queue jobs
├── Mail/                # Mail classes
├── Models/              # Eloquent models
├── Providers/           # Service providers
├── helpers.php          # Global helper functions
└── validators.php       # Custom validators

Core Components

Controllers
Handle HTTP requests and coordinate between services and models
Models
Eloquent ORM models representing database entities and business logic
Services
Encapsulate complex business logic and external integrations
Middleware
Process HTTP requests and responses with cross-cutting concerns
Jobs
Asynchronous background tasks for heavy operations

Design Patterns

Model-View-Controller (MVC)

The application strictly follows the MVC pattern:

graph LR
    A[HTTP Request] --> B[Route]
    B --> C[Middleware]
    C --> D[Controller]
    D --> E[Service Layer]
    E --> F[Model]
    F --> G[Database]
    D --> H[Response]
    H --> I[JSON/View]

Active Record Pattern

The application uses Laravel's Active Record pattern via Eloquent ORM, with static methods for complex queries:

// Example: User model with static query methods
class User extends BaseModel
{
    public static function getFilters($options = [])
    {
        // Static query methods for complex filtering
        return self::select(['id', 'firstname', 'lastname', 'email'])
                   ->where('isActive', 1)
                   ->when($options['role_id'] ?? null, function($query, $roleId) {
                       return $query->where('role_id', $roleId);
                   })
                   ->get();
    }
}

Note: No repository pattern is implemented - the application follows Laravel's Active Record approach.

Service Layer Pattern

Business logic is encapsulated in service classes:

graph TB
    A[Controller] --> B[Service Class]
    B --> C[Model 1]
    B --> D[Model 2]
    B --> E[External API]
    B --> F[Cache]
    C --> G[Database]
    D --> G

Actual Service Classes: - AuthService: JWT authentication and app source validation - BrewerySsoService: SSO infrastructure (not active) - ProjectService: Project-related business logic - UtilizationService: Resource utilization calculations - ProjectResourceService: Project resource management - PaymentMilestoneService: Payment milestone processing - FileUploadService: File upload operations - FileExportService: Report export functionality - UserService: User management operations

Database Layer

Eloquent ORM

The application uses Laravel's Eloquent ORM for database interactions:

Base Model
All models extend BaseModel with audit logging and authentication context
class BaseModel extends Model
{
    protected $casts = [
        'created_at' => 'datetime:Y-m-d H:i:s',
        'updated_at' => 'datetime:Y-m-d H:i:s',
    ];

    public static function getAuthUser()
    {
        // Get authenticated user from request context
    }

    // Automatic audit logging on delete
    public static function boot()
    {
        parent::boot();
        static::deleting(function($model) {
            // Audit log implementation
        });
    }
}
Model Relationships
Comprehensive relationship definitions between entities
class Project extends BaseModel
{
    public function client()
    {
        return $this->belongsTo(Client::class);
    }

    public function projectUsers()
    {
        return $this->hasMany(ProjectUser::class);
    }

    public function timelogs()
    {
        return $this->hasManyThrough(Timelog::class, ProjectUser::class);
    }
}

Database Migrations

Comprehensive migration system for database schema management:

// Example migration structure
class CreateTimelogsTable extends Migration
{
    public function up()
    {
        Schema::create('timelogs', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained();
            $table->foreignId('project_user_id')->nullable()->constrained();
            $table->foreignId('tasktype_id')->constrained();
            $table->datetime('startTime');
            $table->datetime('stopTime');
            $table->decimal('spentHours', 8, 2);
            $table->text('description');
            $table->string('status')->default('pending');
            $table->timestamps();
            $table->softDeletes();

            $table->index(['user_id', 'startTime']);
            $table->index(['status', 'created_at']);
        });
    }
}

HTTP Layer

Routing Structure

The application uses a structured routing approach:

// API routes with versioning
Route::group(['prefix' => 'v2', 'middleware' => ['throttle:100,1']], function () {
    // Authentication routes
    Route::resource('authenticate', 'TokenAuthController');

    // Protected routes
    Route::group(['middleware' => ['my.jwt.auth']], function () {
        Route::resource('timelogs', 'TimelogController');
        Route::resource('projects', 'ProjectController');
        // ... other resources
    });
});

// Specialized module routes
include('sinop.php');
include('csat.php');
include('f1.php');
// ... other modules

Middleware Stack

Custom middleware handles cross-cutting concerns:

graph TB
    A[HTTP Request] --> B[Throttle Middleware]
    B --> C[CORS Middleware]
    C --> D[Authentication Middleware]
    D --> E[Authorization Middleware]
    E --> F[Validation Middleware]
    F --> G[Logging Middleware]
    G --> H[Controller]

Key Middleware Components:

  • MyGetUserFromToken: Custom JWT authentication
  • AllowedAppSource: Application source validation
  • ValidateAllUserInputs: Input sanitization
  • LogAccess: Request logging and monitoring

Request Validation

Comprehensive input validation using Laravel's validation system:

class TimelogRequest extends FormRequest
{
    public function rules()
    {
        return [
            'startTime' => 'required|date',
            'stopTime' => 'required|date|after:startTime',
            'project_user_id' => 'required|exists:project_users,id',
            'description' => 'required|string|max:1000',
            'spentHours' => 'required|numeric|min:0.25|max:24'
        ];
    }
}

Business Logic Layer

Service Classes

Business logic is organized into focused service classes:

class AuthService
{
    public function authenticate($credentials)
    {
        // Authentication logic
    }

    public function checkAppAccessSource($request)
    {
        // App source validation
    }

    public function getNewToken($request)
    {
        // Token refresh logic
    }
}

Event System

Laravel's event system handles business events:

// Event definition
class TimelogApproved
{
    public $timelog;

    public function __construct(Timelog $timelog)
    {
        $this->timelog = $timelog;
    }
}

// Event listener
class SendApprovalNotification
{
    public function handle(TimelogApproved $event)
    {
        // Send notification logic
    }
}

Background Processing

Queue System

Asynchronous processing using Laravel Queues:

graph LR
    A[Web Request] --> B[Dispatch Job]
    B --> C[Queue]
    C --> D[Worker Process]
    D --> E[Job Execution]
    E --> F[Database Update]
    E --> G[Email Notification]
    E --> H[External API Call]

Job Types:

  • Email notifications
  • Report generation
  • Data synchronization
  • File processing
  • Cleanup tasks

Scheduled Tasks

Automated tasks using Laravel Scheduler:

protected function schedule(Schedule $schedule)
{
    $schedule->command('timesheet:emailDeficiencyLevel1')
             ->monthlyOn(20, '07:00')
             ->onOneServer();

    $schedule->command('timesheet:notifyProjectsNearDeadline')
             ->dailyAt('08:00')
             ->onOneServer();

    $schedule->command('timesheet:emailOffsetSummaryForTheMonth')
             ->weekly()
             ->mondays()
             ->at('20:00')
             ->onOneServer();
}

Security Implementation

Authentication System

JWT-based authentication implementation:

sequenceDiagram
    participant C as Client
    participant M as JWT Middleware
    participant A as Auth Service
    participant D as Database

    C->>M: Request with JWT Token
    M->>A: Validate JWT Token
    A->>D: Get User by Token Subject
    D->>A: User Data
    A->>M: Authentication Result
    M->>C: Allow/Deny Request

Note: SSO authentication infrastructure exists but is not currently active.

Authorization System

Role-based access control implementation:

class User extends BaseModel
{
    public function hasPermission($permissionId)
    {
        $permissions = explode(',', $this->permission_ids);
        return in_array($permissionId, $permissions);
    }

    public function isApproverFor($userId)
    {
        // Check approval hierarchy
    }
}

Data Encryption

Sensitive data encryption using Laravel's encryption:

use App\Http\Traits\EncryptableTrait;

class ProjectUser extends BaseModel
{
    use EncryptableTrait;

    protected $encryptable = [
        'hourlySalary',
        'sensitiveField'
    ];
}

API Design

RESTful API Structure

Consistent API design following REST principles:

GET    /api/v2/timelogs           # List timelogs
POST   /api/v2/timelogs           # Create timelog
GET    /api/v2/timelogs/{id}      # Show timelog
PUT    /api/v2/timelogs/{id}      # Update timelog
DELETE /api/v2/timelogs/{id}      # Delete timelog

Response Format

Actual response format used in the application:

{
    "header": {
        "status": 200,
        "title": "Resource Name",
        "description": "Operation completed successfully"
    },
    "body": {
        "data": [...]
    }
}

Simple Response (Common):

{
    "data": [...],
    "pagination": {
        "current_page": 1,
        "last_page": 10,
        "per_page": 50,
        "total": 500
    }
}

Performance Optimization

Caching Strategy

Multi-level caching implementation:

// Model-level caching
public static function getFilters()
{
    $cacheName = 'users.filters';
    return Cache::remember($cacheName, 3600, function () {
        return self::select(['id', 'name', 'email'])
                   ->where('is_active', 1)
                   ->get();
    });
}

Database Optimization

  • Proper indexing on frequently queried columns
  • Query optimization using Eloquent relationships
  • Database connection pooling
  • Read replica usage for reporting queries

Memory Management

  • Efficient data loading with pagination
  • Lazy loading of relationships
  • Memory-conscious batch processing
  • Garbage collection optimization

This backend architecture provides a solid foundation for the Stratpoint Timesheet Application, ensuring scalability, maintainability, and performance while supporting complex business requirements.