Generated: 2025-10-16 Architecture Type: Laravel RESTful API Monolith with Multi-Module Structure Pattern: Multi-tenant SaaS Backend
┌─────────────────────────────────────────────────────────────┐
│ Client Applications │
├──────────────────────┬──────────────────────────────────────┤
│ VueJS Frontend │ Mobile App (iOS/Android) │
│ (Separate Repo) │ (Separate Repo) │
└──────────────────────┴──────────────────────────────────────┘
│
│ HTTPS / JSON
▼
┌─────────────────────────────────────────────────────────────┐
│ Laravel REST API (This Repository) │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ API Routes │ │ Controllers │ │ Middleware │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Form Requests│ │ Services │ │ Models │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ MySQL │ │ Redis │ │ AWS S3 │
│ Database │ │Cache/Queue│ │ Storage │
└──────────┘ └──────────┘ └──────────┘
│
▼
┌──────────────┐
│ Meilisearch │
│Search Engine │
└──────────────┘
instance_id)Presentation Layer (API): - Controllers handle HTTP requests/responses only - Thin controllers, business logic in services/models
Business Logic Layer: - Eloquent Models contain domain logic - Service classes for complex workflows - Manager classes for cross-cutting concerns (RightManager, ResponsibilityManager)
Data Access Pattern: - Direct Eloquent model usage (no Repository pattern) - Query logic lives in Models (scopes, relationships) - Complex queries extracted to Manager classes when needed
Data Layer: - Eloquent ORM for database abstraction - Migrations for schema versioning - Factories & Seeders for test data
Reusable Components:
- Polymorphic models for universal features (Comment, Tag, NotificationLog)
- Traits for shared behavior (HasOperations, Searchable, SoftDeletes)
- Helpers for common functions (app/Helpers/general.php)
- Form Requests for validation reuse
Laravel Conventions:
- PSR-4 autoloading (App\ namespace)
- RESTful resource controllers
- Eloquent naming conventions
- Migration & model naming patterns
Built-in Protections:
- CSRF protection (disabled for API, using Sanctum tokens)
- XSS protection via Blade escaping
- SQL injection prevention via Eloquent
- Mass assignment protection ($fillable/$guarded)
app/
├── Http/
│ ├── Controllers/
│ │ └── Api/ # 99 API Controllers
│ ├── Middleware/ # Authentication, tenant filtering
│ └── Requests/ # Form Request validation classes
├── Models/ # 131 Eloquent Models
├── Helpers/ # Utility functions
├── Managers/ # Cross-cutting logic (Rights, Responsibilities)
├── Enums/ # Enum constants (RightEnum, StatusEnum, etc.)
└── Traits/ # Reusable model behaviors
8 Core Business Modules:
HR Module
CRM Module
Projects & Tasks Module
Procedures Module
OKR Module
Vacation Module
Asset Management Module
AI Module
Row-Level Tenancy:
php
// Every model has instance_id for tenant isolation
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->foreignId('instance_id')->constrained();
// ... other columns
});
Automatic Tenant Scoping: ```php // Global scope on models protected static function boot() { parent::boot();
static::creating(function ($model) {
if (!$model->instance_id) {
$model->instance_id = auth()->user()->instance_id;
}
});
} ```
Query Filtering:
php
// Always filter by instance
$users = User::where('instance_id', auth()->user()->instance_id)->get();
1. Polymorphic Relationships
Universal features using polymorphic associations:
// comments table
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->foreignId('instance_id');
$table->foreignId('user_id');
$table->morphs('commentable'); // commentable_type, commentable_id
$table->text('content');
$table->timestamps();
});
// Usage
$task->comments()->create(['content' => '...']);
$deal->comments()->create(['content' => '...']);
2. Pivot Tables with Attributes
Many-to-many with extra data:
// user_right pivot table
Schema::create('user_right', function (Blueprint $table) {
$table->foreignId('user_id');
$table->foreignId('right_id');
$table->integer('scope')->default(0); // Extra attribute
$table->timestamps();
});
3. Hierarchical Data
Self-referencing tables:
// Departments with parent/child hierarchy
Schema::create('departments', function (Blueprint $table) {
$table->id();
$table->foreignId('parent_id')->nullable()->constrained('departments');
// ...
});
// Users with manager/subordinate hierarchy
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->foreignId('parent_function_id')->nullable()->constrained('users');
// ...
});
4. Soft Deletes
All primary models use soft deletes:
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model
{
use SoftDeletes;
}
Resource-Oriented Endpoints:
# Standard CRUD
GET /api/users # List
POST /api/users # Create
GET /api/users/{id} # Show
PUT /api/users/{id} # Update
DELETE /api/users/{id} # Delete (soft delete)
# Nested Resources
GET /api/users/{id}/tasks
POST /api/users/{id}/tasks
GET /api/users/{id}/subordinates
# Custom Actions
POST /api/users/{id}/assign-right
PUT /api/users/{id}/change-password
POST /api/tasks/{id}/complete
Standard Success Response:
json
{
"success": true,
"data": {
"id": 123,
"name": "John Doe",
// ...
},
"message": "Operation successful"
}
Standard Error Response:
json
{
"success": false,
"message": "Validation failed",
"errors": {
"email": ["The email field is required."]
}
}
Route::middleware(['api', 'auth:sanctum', 'instance'])->group(function () {
// API routes
});
Middleware Responsibilities:
- auth:sanctum - Authenticate API token
- instance - Enforce tenant isolation
- throttle - Rate limiting
- Custom middleware for rights checking
Token-Based Auth: ```php // Login POST /api/auth/login { “email”: “user@example.com”, “password”: “password” }
// Response { “token”: “1|abc123…”, “user”: {…} }
// Authenticated Requests Authorization: Bearer 1|abc123… ```
Role vs Rights Distinction: - Role = Job Position (e.g., “Senior Developer”) - Right = Permission (e.g., ADMIN_CRM, EMPLOYEE_TASK)
Permission Check: ```php // In FormRequest public function authorize() { return $this->user()->hasRight(RightEnum::ADMIN_USER); }
// In Controller if (!auth()->user()->hasRight(RightEnum::ADMIN_CRM)) { return response()->json([‘error’ => ‘Unauthorized’], 403); } ```
Scope-Based Filtering:
| Scope | Value | Access Level |
|---|---|---|
| NONE | 0 | No access |
| OWN | 1 | Only own records |
| DEPARTMENT_DOWN | 2 | Own dept + subordinate depts |
| ALL | 3 | All records in instance |
Special Role: - MASTER_ADMIN - Unrestricted access to everything in instance
Package: beyondcode/laravel-websockets
Architecture:
Laravel Application
│
├─► WebSocket Server (Port 6001)
│ └─► Pusher protocol compatible
│
└─► Broadcasting System
├─► Channels (private, presence, public)
└─► Events (TaskAssigned, DealUpdated, etc.)
Event Broadcasting: ```php // Broadcast event broadcast(new TaskAssigned($task, $user))->toOthers();
// Client subscription (VueJS)
Echo.private(user.${userId})
.listen(‘TaskAssigned’, (e) => {
// Handle notification
});
```
Flow:
Laravel Backend
│
├─► Create NotificationLog
├─► Send Firebase FCM message
│ │
│ ▼
│ Firebase Cloud Messaging
│ │
│ ├─► Mobile App (iOS/Android)
│ └─► Web Browser
│
└─► Queue Email (CronjobMail)
3-Channel Notification System: 1. In-app (NotificationLog + WebSocket) 2. Email (CronjobMail + Queue) 3. Push (Firebase FCM)
Configuration:
php
// config/filesystems.php
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
]
Usage: ```php // Store file Storage::disk(‘s3’)->put(‘avatars/user-123.jpg’, $file);
// Get URL $url = Storage::disk(‘s3’)->url(‘avatars/user-123.jpg’); ```
Architecture:
Laravel Scout
│
├─► Searchable Models (User, Task, Deal, etc.)
│ │
│ └─► toSearchableArray()
│
▼
Meilisearch Engine
│
└─► Global Search Index
Search Query:
php
// Search across all searchable models
$results = User::search('john')->get();
$tasks = Task::search('urgent')->get();
Features: - GPT-powered text generation - Conversation threading (AiThread) - Custom AI agents with roles (AiAgent) - Prompt templates (AiPrompt)
Vector Storage (Pinecone): - Embeddings for semantic search - Document similarity matching
Features: - One-time payments - Subscription management - Webhook handling
Recommended Stack:
┌────────────────────────────────────────┐
│ Load Balancer (nginx) │
└────────────────────────────────────────┘
│
┌───────────┴───────────┐
│ │
┌─────▼──────┐ ┌───────▼────┐
│ App Server │ │ App Server │
│ (PHP-FPM) │ │ (PHP-FPM) │
└────────────┘ └────────────┘
│ │
└───────────┬───────────┘
│
┌────────────┴───────────────┐
│ │
┌────▼─────┐ ┌──────▼──────┐ │
│ MySQL │ │ Redis │ │
│ (Primary)│ │ Cache/Queue │ │
└──────────┘ └─────────────┘ │
│
┌────────▼────────┐
│ Meilisearch │
│ Search Engine │
└─────────────────┘
Required Services: ```bash
php artisan queue:work
php artisan websockets:serve ```
Horizontal Scaling: - Multiple app servers behind load balancer - Shared session storage (Redis) - Shared file storage (S3)
Database Scaling: - Read replicas for heavy read operations - Index optimization on frequently queried columns
Cache Strategy: - Redis for session, cache, queue - Cache user rights and permissions - Cache custom fields configuration
Multi-Tenancy Security:
php
// Middleware ensures all queries filtered by instance_id
class EnsureTenantScope
{
public function handle($request, Closure $next)
{
if (auth()->check()) {
$instanceId = auth()->user()->instance_id;
// Validate all requests operate within tenant boundary
}
return $next($request);
}
}
Audit Trail: ```php use Panoscape\History\HasOperations;
class Deal extends Model { use HasOperations; // Automatic change tracking }
// Query history $deal->history; // All historical changes ```
Form Request Classes: ```php class UserFormRequest extends FormRequest { public function authorize() { return $this->user()->hasRight(RightEnum::ADMIN_USER); }
public function rules()
{
return [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
// ...
];
}
} ```
Prevent N+1 Queries: ```php // ❌ BAD - N+1 problem $users = User::all(); foreach ($users as $user) { echo $user->department->name; // Query per user }
// ✅ GOOD - Eager load $users = User::with(‘department’)->get(); ```
Cache Layers: 1. Application Cache (Redis) - Rights, custom fields, frequently accessed data 2. Query Result Cache - Expensive queries cached with TTL 3. HTTP Cache - API response caching for static endpoints
Key Indexes: ```sql – Multi-tenancy INDEX idx_instance_id ON users (instance_id);
– Foreign keys INDEX idx_department_id ON users (department_id);
– Composite indexes for common queries INDEX idx_instance_status ON tasks (instance_id, status); ```
Document Generated: 2025-10-16 Architecture Pattern: Laravel RESTful API Monolith (Multi-Module, Multi-Tenant) Deployment Model: Stateless API serving multiple client applications