Generated: 2025-10-16
Total Models: 131 Eloquent models
Database Migrations: 368 migrations
Multi-Tenancy: Row-level with instance_id
Every model includes instance_id for tenant isolation:
// Automatic instance_id assignment
public static function boot(){
parent::boot();
self::creating(function($model){
$authUser = Auth::user();
if ($authUser && !$model->instance_id) {
$model->instance_id = $authUser->instance_id;
}
});
}
| Metric | Count |
|---|---|
| Total Tables | ~370 tables (from 368 migrations) |
| Eloquent Models | 131 models |
| Pivot Tables | ~40 many-to-many relationships |
| Polymorphic Tables | 5 universal models |
All models use standard Laravel patterns and custom traits:
Standard Traits:
php
use HasFactory; // Model factories for testing
use SoftDeletes; // Soft delete (never hard delete)
use Searchable; // Laravel Scout full-text search
Custom Traits:
php
use HasOperations; // Audit trail (Panoscape History package)
use HasHistories; // Alternative audit trail trait
use HasSlug; // URL-friendly slugs (Spatie Sluggable)
use HasCustomFields; // Dynamic custom fields support
User Model Special Traits:
php
use HasApiTokens; // Laravel Sanctum authentication
use Notifiable; // Laravel notifications
class ExampleModel extends Model
{
use HasFactory, SoftDeletes, HasOperations, Searchable;
// Mass-assignable attributes
protected $fillable = [
'instance_id', // Multi-tenancy
'name',
'description',
// ... other fields
];
// Hidden from JSON responses
protected $hidden = ['password', 'remember_token'];
// Type casting
protected $casts = [
'metadata' => 'array',
'created_at' => 'datetime',
];
// Auto-set instance_id on create
public static function boot() { /* ... */ }
// Relationships
public function relatedModel() { /* ... */ }
}
All primary models use soft deletes:
use Illuminate\Database\Eloquent\SoftDeletes;
class Deal extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
}
// Query only non-deleted records (default)
$deals = Deal::all();
// Include soft-deleted records
$deals = Deal::withTrashed()->get();
// Only soft-deleted records
$deals = Deal::onlyTrashed()->get();
Models track all changes using HasOperations or HasHistories:
use Panoscape\History\HasOperations;
class Deal extends Model
{
use HasOperations;
}
// Access history
$deal->history; // Collection of all changes
$deal->logs; // Alias for history
Models use Laravel Scout with Meilisearch:
use Laravel\Scout\Searchable;
class User extends Model
{
use Searchable;
// All models indexed in 'global_index'
public function searchableAs()
{
return 'global_index';
}
// Unique key across all models
public function getScoutKey()
{
return class_basename(static::class) . '-' . $this->id;
}
// Define searchable data
public function toSearchableArray()
{
return [
'model_id' => $this->id,
'model' => class_basename(static::class),
'name' => $this->fullName(),
'url' => "/users/{$this->slug}/overview",
'access_ids' => $accessIDs, // Permission filtering
];
}
}
Purpose: Employee/user accounts with authentication
File: app/Models/User.php
Key Attributes:
php
protected $fillable = [
'instance_id', // Tenant isolation
'first_name',
'last_name',
'email',
'slug', // URL-friendly identifier
'password',
'avatar',
'language', // User interface language
'phone',
'status', // active, inactive
'parent_function_id', // Manager reference
'department_access_ids', // Array - accessible departments
'ceo', // Boolean flag
'manager_hr', // Boolean flag
'is_shareholder',
'is_partner',
'firebase_token', // Push notifications
];
Relationships (100+ relationships): ```php // Identity public function user_detail() // hasOne - UserDetail public function instance() // belongsTo - Instance
// Organizational public function departments() // belongsToMany - Department public function roles() // belongsToMany - Role public function parent_function() // belongsTo - User (manager) public function children_functions() // hasMany - User (subordinates)
// HR & Evaluation public function skills() // belongsToMany - Skill (with level) public function foreign_languages() // belongsToMany - ForeignLanguage public function user_evaluations() // hasMany - UserEvaluation public function user_files() // hasMany - UserFile
// Tasks & Projects public function tasks() // hasMany - Task public function projects() // belongsToMany - Project public function task_watchers() // belongsToMany - Task (watching) public function task_timers() // hasMany - TaskTimer
// CRM public function deals() // hasMany - Deal public function activities() // hasMany - Activity
// Procedures public function responsible_procedures() // hasMany - Procedure public function procedure_approval_requests() // hasMany
// OKR public function objectives() // hasMany - Objective public function key_results() // hasMany - KeyResult public function master_goals() // belongsToMany - MasterGoal
// Vacation public function vacation_days() // belongsToMany - VacationDay public function vacation_user_settings() // hasMany
// Permissions public function rights() // belongsToMany - Right public function special_rights() // hasMany - SpecialRight
// Communications public function comments() // hasMany - Comment public function notification_logs() // hasMany - NotificationLog public function announces() // belongsToMany - Announce
// AI public function ai_threads() // hasMany - AiThread public function ai_logs() // hasMany - AiLog ```
Key Methods:
php
public function fullName() // Returns "FirstName LastName"
public function getAvatarOrGravatar() // Returns avatar URL or Gravatar
public function isAdmin($moduleRight) // Check admin rights
public function isCeo() // Check CEO status
public function hasRight($rightName) // Permission check
Purpose: Organizational units with hierarchy
File: app/Models/Department.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'name',
'parent_id', // Self-referencing for hierarchy
'responsible_id', // Department head
'description',
'status',
];
Relationships:
php
public function parent() // belongsTo - Department
public function children() // hasMany - Department
public function users() // belongsToMany - User
public function responsible() // belongsTo - User
Hierarchical Structure:
Company Root Department
├── Sales Department
│ ├── Enterprise Sales
│ └── SMB Sales
├── Engineering Department
│ ├── Backend Team
│ └── Frontend Team
└── HR Department
Purpose: Job positions (NOT permissions)
File: app/Models/Role.php
Important: Role ≠ Permission. Role = Job Position.
Key Attributes:
php
protected $fillable = [
'instance_id',
'name', // e.g., "Senior Developer", "Sales Manager"
'department_id',
'description',
'responsibilities', // JSON array of responsibilities
];
Relationships:
php
public function department() // belongsTo - Department
public function users() // belongsToMany - User
public function procedures() // hasMany - Procedure
public function managers() // belongsToMany - User (role managers)
Purpose: Actual permissions (NOT job positions)
File: app/Models/Right.php
Key Attributes:
php
protected $fillable = [
'name', // e.g., ADMIN_CRM, EMPLOYEE_TASK
'description',
'module', // Module grouping
];
Pivot Table: user_right
php
Schema::create('user_right', function (Blueprint $table) {
$table->foreignId('user_id');
$table->foreignId('right_id');
$table->integer('scope')->default(0); // 0=NONE, 1=OWN, 2=DEPT, 3=ALL
});
Scope Levels:
- 0 - NONE: No access
- 1 - OWN: Only own records
- 2 - DEPARTMENT_DOWN: Own department + subordinate departments
- 3 - ALL: All records in instance
Relationships:
php
public function users() // belongsToMany - User (with scope pivot)
| Model | Purpose | File |
|---|---|---|
| UserDetail | Extended user profile data | UserDetail.php |
| Skill | Skills catalog | Skill.php |
| UserFile | Employee documents with expiry | UserFile.php |
| UserFileCategory | Document categories | UserFileCategory.php |
| UserFileTemplate | Document templates | UserFileTemplate.php |
| UserEvaluation | Performance evaluations | UserEvaluation.php |
| CustomEvaluation | Custom evaluation forms | CustomEvaluation.php |
| CustomEvaluationStage | Evaluation stages | CustomEvaluationStage.php |
| EvaluationBonus | Bonus calculation | EvaluationBonus.php |
| VacantJob | Job postings | VacantJob.php |
| VacantJobAnnounce | Job announcements | VacantJobAnnounce.php |
| ForeignLanguage | Language catalog | ForeignLanguage.php |
| Review | Peer reviews | Review.php |
| WorkSchedule | Work schedule definitions | WorkSchedule.php |
| Schedule | Schedule details | Schedule.php |
| Clocking | Time clock entries | Clocking.php |
| ClockingSession | Clock sessions | ClockingSession.php |
| ClockingLock | Period locks | ClockingLock.php |
| PunchDevice | Physical time clock devices | PunchDevice.php |
Purpose: Sales opportunity tracking
File: app/Models/Deal.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'title',
'description',
'source_id', // Lead source
'expected_close_date',
'person_id', // Contact person
'pipeline_id',
'stage_id', // Current stage in pipeline
'estimate_value',
'currency_id',
'responsible_id', // Assigned sales rep
'organization_id', // Company
'status', // open, won, lost
'closed_status',
'closed_at',
'scoring', // Deal quality score
'added_by_user_id',
'created_by_ai', // Boolean - AI-generated deal
];
Relationships:
php
public function instance() // belongsTo - Instance
public function organization() // belongsTo - Organization
public function person() // belongsTo - Person
public function responsible() // belongsTo - User
public function pipeline() // belongsTo - Pipeline
public function stage() // belongsTo - Stage
public function source() // belongsTo - DealSource
public function currency() // belongsTo - Currency
public function products() // belongsToMany - Product
public function tasks() // hasMany - Task
public function comments() // hasMany - Comment
public function user_files() // hasMany - UserFile
public function tags() // belongsToMany - Tag
public function stage_counters() // hasMany - StageCounter
public function added_by() // belongsTo - User
Custom Fields Support: ```php use HasCustomFields; // Trait for dynamic fields
// Custom field values stored in custom_field_values table $deal->getCustomFieldValue(‘priority’); $deal->setCustomFieldValue(‘priority’, ‘high’); ```
Purpose: Company/client management
File: app/Models/Organization.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'name',
'cui', // Tax ID
'j', // Registration number
'phone',
'email',
'website',
'description',
'address_id',
'organization_type_id',
'cod_caen', // Industry code
'activity_domain',
'year_of_establishment',
'status',
];
Relationships:
php
public function deals() // hasMany - Deal
public function persons() // hasMany - Person
public function address() // belongsTo - Address
public function organization_type() // belongsTo - OrganizationType
public function comments() // hasMany - Comment
public function tags() // belongsToMany - Tag
Purpose: Individual contact management
File: app/Models/Person.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'first_name',
'last_name',
'email',
'phone',
'position', // Job title
'organization_id',
'status',
];
Relationships:
php
public function organization() // belongsTo - Organization
public function deals() // hasMany - Deal
public function comments() // hasMany - Comment
Purpose: Sales pipeline configuration
Pipeline Model: ```php class Pipeline extends Model { protected $fillable = [ ‘instance_id’, ‘name’, ‘is_default’, ‘status’, ];
public function stages() // hasMany - Stage (ordered)
public function deals() // hasMany - Deal
} ```
Stage Model: ```php class Stage extends Model { protected $fillable = [ ‘instance_id’, ‘name’, ‘pipeline_id’, ‘order’, // Display order ‘probability’, // Win probability % ‘type’, // open, won, lost ‘status’, ];
public function pipeline() // belongsTo - Pipeline
public function deals() // hasMany - Deal
public function stage_counters() // hasMany - StageCounter
} ```
| Model | Purpose | File |
|---|---|---|
| DealSource | Lead source tracking | DealSource.php |
| Activity | Activity logging | Activity.php |
| StageCounter | Time in stage tracking | StageCounter.php |
| DiscountLink | Discount code management | DiscountLink.php |
| Brand | Brand/product line | Brand.php |
| Product | Product catalog | Product.php |
| ProductType | Product categories | ProductType.php |
| ProductVat | VAT rates | ProductVat.php |
| Currency | Currency definitions | Currency.php |
| OrganizationType | Organization categories | OrganizationType.php |
| Address | Address storage | Address.php |
| Proforma | Proforma invoices | Proforma.php |
Purpose: Task assignment and tracking
File: app/Models/Task.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'title',
'description',
'user_id', // Assigned user
'project_id',
'deal_id', // Optional link to deal
'priority', // 1=low, 2=medium, 3=high, 4=urgent
'status', // pending, in_progress, completed
'start_date',
'deadline',
'estimated_time', // Minutes
'actual_time', // Minutes (from timers)
'added_by_user_id',
'parent_task_id', // Task dependencies
];
Relationships:
php
public function user() // belongsTo - User (assignee)
public function added_by() // belongsTo - User (creator)
public function project() // belongsTo - Project
public function deal() // belongsTo - Deal
public function parent_task() // belongsTo - Task
public function sub_tasks() // hasMany - Task
public function comments() // hasMany - Comment
public function watchers() // belongsToMany - User
public function task_timers() // hasMany - TaskTimer
public function task_logs() // hasMany - TaskLog
public function checklists() // hasMany - Checklist
Purpose: Project management
File: app/Models/Project.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'name',
'description',
'responsible_id',
'start_date',
'deadline',
'status', // active, completed, archived
'added_by_user_id',
];
Pivot Table: project_user
php
Schema::create('project_user', function (Blueprint $table) {
$table->foreignId('project_id');
$table->foreignId('user_id');
$table->boolean('editor')->default(false); // Can edit project
$table->timestamps();
});
Relationships:
php
public function responsible() // belongsTo - User
public function users() // belongsToMany - User (with editor pivot)
public function tasks() // hasMany - Task
public function meetings() // hasMany - Meeting
public function comments() // hasMany - Comment
Purpose: Meeting scheduling and management
File: app/Models/Meeting.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'title',
'description',
'project_id',
'date',
'start_time',
'end_time',
'location',
'added_by_user_id',
'status',
];
Pivot Table: meeting_user
php
Schema::create('meeting_user', function (Blueprint $table) {
$table->foreignId('meeting_id');
$table->foreignId('user_id');
$table->string('response')->nullable(); // accepted, declined, tentative
$table->string('token_link')->nullable(); // Unique meeting link
$table->string('right')->nullable(); // view, edit
$table->timestamps();
});
Relationships:
php
public function project() // belongsTo - Project
public function users() // belongsToMany - User (with response)
public function added_by() // belongsTo - User
public function meeting_sessions() // hasMany - MeetingSession
public function meeting_summaries() // hasMany - MeetingSummary
public function meeting_reviews() // hasMany - MeetingReview
public function comments() // hasMany - Comment
| Model | Purpose | File |
|---|---|---|
| TaskTimer | Time tracking entries | TaskTimer.php |
| TaskLog | Task activity log | TaskLog.php |
| Checklist | Task checklists | Checklist.php |
| MeetingSession | Meeting execution tracking | MeetingSession.php |
| MeetingSummary | Meeting notes/minutes | MeetingSummary.php |
| MeetingReview | Post-meeting reviews | MeetingReview.php |
| Promise | Daily commitment tracking | Promise.php |
Purpose: Business process documentation
File: app/Models/Procedure.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'title',
'description',
'process_id', // Parent process
'responsible_id',
'type', // guideline, course, checklist
'status', // draft, active, archived
'version',
'steps', // JSON array of procedure steps
];
Relationships:
php
public function process() // belongsTo - Process
public function responsible() // belongsTo - User
public function procedure_logs() // hasMany - ProcedureLog (executions)
public function procedure_approval_requests() // hasMany
public function procedure_checks() // hasMany - ProcedureCheck
public function procedure_analytics() // hasMany - ProcedureAnalytic
Purpose: Process definition and versioning
Process Model: ```php class Process extends Model { protected $fillable = [ ‘instance_id’, ‘name’, ‘description’, ‘responsible_id’, ‘current_version_id’, // Active version ‘status’, ];
public function responsible() // belongsTo - User
public function versions() // hasMany - ProcessVersion
public function procedures() // hasMany - Procedure
} ```
ProcessVersion Model: ```php class ProcessVersion extends Model { protected $fillable = [ ‘process_id’, ‘version_number’, ‘description’, ‘flow_data’, // JSON - process flow diagram ‘is_active’, ];
public function process() // belongsTo - Process
} ```
Purpose: Procedure execution tracking
File: app/Models/ProcedureLog.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'procedure_id',
'user_id', // Executor
'started_at',
'completed_at',
'status', // in_progress, completed, failed
'step_data', // JSON - step completion data
'duration', // Minutes
];
Relationships:
php
public function procedure() // belongsTo - Procedure
public function user() // belongsTo - User
| Model | Purpose | File |
|---|---|---|
| ProcedureCheck | Checklist items | ProcedureCheck.php |
| ProcedureApprovalRequest | Approval workflows | ProcedureApprovalRequest.php |
| ProcedureAnalytic | Analytics data | ProcedureAnalytic.php |
| ProcedureHistory | Change history | ProcedureHistory.php |
| UserApproval | User approval status | UserApproval.php |
| RoleResponsibility | Role responsibilities | RoleResponsibility.php |
| RoleResponsibilityDraft | Draft responsibilities | RoleResponsibilityDraft.php |
| UserResponsibilityLog | Responsibility tracking | UserResponsibilityLog.php |
| AggregateResponsibilityLog | Aggregated logs | AggregateResponsibilityLog.php |
| AutomationTemplate | Automation rules | AutomationTemplate.php |
| AutomationRuleExecution | Execution logs | AutomationRuleExecution.php |
| DocumentTemplate | Document templates | DocumentTemplate.php |
| ImprovementProposal | Process improvements | ImprovementProposal.php |
| ImprovementFile | Improvement attachments | ImprovementFile.php |
Purpose: High-level goal definition
File: app/Models/Objective.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'title',
'description',
'user_id', // Owner
'master_goal_id', // Parent company goal
'start_date',
'end_date',
'status', // active, completed, archived
'progress', // 0-100%
];
Relationships:
php
public function user() // belongsTo - User
public function master_goal() // belongsTo - MasterGoal
public function key_results() // hasMany - KeyResult
public function pinned_by_users() // belongsToMany - User
public function comments() // hasMany - Comment
Purpose: Measurable key result tracking
File: app/Models/KeyResult.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'title',
'description',
'objective_id',
'user_id', // Owner
'start_value', // Starting metric
'target_value', // Goal metric
'current_value', // Current metric
'unit', // Measurement unit
'start_date',
'end_date',
'status',
];
Relationships:
php
public function objective() // belongsTo - Objective
public function user() // belongsTo - User
public function key_result_logs() // hasMany - KeyResultLog
public function comments() // hasMany - Comment
Purpose: Progress update tracking
File: app/Models/KeyResultLog.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'key_result_id',
'user_id',
'value', // New value
'comment',
'created_at',
];
Relationships:
php
public function key_result() // belongsTo - KeyResult
public function user() // belongsTo - User
| Model | Purpose | File |
|---|---|---|
| MasterGoal | Company-wide objectives | MasterGoal.php |
| Indicator | KPI indicators | Indicator.php |
| IndicatorLog | KPI tracking logs | IndicatorLog.php |
| IntermediateTarget | Milestone tracking | IntermediateTarget.php |
Purpose: Vacation request management
File: app/Models/VacationDay.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'start_date',
'end_date',
'vacation_type_id',
'description',
'status', // pending, approved, rejected
'legal_days', // Number of legal vacation days
];
Pivot Table: user_vacation_day
php
Schema::create('user_vacation_day', function (Blueprint $table) {
$table->foreignId('user_id');
$table->foreignId('vacation_day_id');
$table->foreignId('substitute_id')->nullable(); // Covering employee
$table->string('status'); // pending, approved
$table->decimal('required_legal_days', 5, 2);
$table->timestamps();
});
Relationships:
php
public function vacation_type() // belongsTo - VacationType
public function users() // belongsToMany - User (with pivot)
public function vacation_approvals() // hasMany - VacationApproval
Purpose: Vacation type configuration
File: app/Models/VacationType.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'name', // e.g., "Paid Leave", "Sick Leave"
'requires_approval',
'affects_balance', // Deducts from annual balance
'color', // UI color code
];
Relationships:
php
public function vacation_days() // hasMany - VacationDay
| Model | Purpose | File |
|---|---|---|
| VacationPlanner | Team vacation planning | VacationPlanner.php |
| UserVacationPlanner | User vacation plans | UserVacationPlanner.php |
| VacationApproval | Approval workflow | VacationApproval.php |
| VacationExcuse | Medical excuses | VacationExcuse.php |
| VacationCar | Company car bookings | VacationCar.php |
| VacationUserSetting | User vacation settings | VacationUserSetting.php |
| YearPlanner | Annual planning | YearPlanner.php |
| DraftPlanner | Draft plans | DraftPlanner.php |
Purpose: Individual asset tracking
File: app/Models/AssetManagementItem.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'name',
'serial_number',
'asset_management_id', // Asset type/category
'status', // available, assigned, maintenance
'purchase_date',
'purchase_price',
'current_value',
'assigned_user_id',
'location',
'added_by_user_id',
];
Relationships:
php
public function asset_management() // belongsTo - AssetManagement
public function assigned_user() // belongsTo - User
public function added_by() // belongsTo - User
public function watchers() // belongsToMany - User
public function comments() // hasMany - Comment
public function user_files() // hasMany - UserFile (documents)
Purpose: Asset type/category definition
File: app/Models/AssetManagement.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'name', // e.g., "Laptops", "Office Furniture"
'description',
'depreciation_rate', // Annual depreciation %
'maintenance_interval', // Days
'category_id',
];
Relationships:
php
public function category() // belongsTo - Category
public function asset_management_items() // hasMany - AssetManagementItem
public function asset_management_templates() // hasMany
| Model | Purpose | File |
|---|---|---|
| AssetManagementTemplate | Asset templates | AssetManagementTemplate.php |
| AssetManagementUserRight | Asset permissions | AssetManagementUserRight.php |
| Category | Asset categorization | Category.php |
| Workstation | Workstation/desk management | Workstation.php |
Purpose: AI agent configuration
File: app/Models/AiAgent.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'name',
'description',
'role', // System role/persona
'ai_model_id', // OpenAI model
'temperature', // 0.0-2.0
'max_tokens',
'status',
];
Relationships:
php
public function ai_model() // belongsTo - AiModel
public function ai_threads() // hasMany - AiThread
public function ai_agent_snippets() // hasMany - AiAgentSnippet
public function ai_agent_file_templates() // hasMany
public function ai_agent_user_rights() // hasMany - permissions
Purpose: Conversation threading
File: app/Models/AiThread.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'user_id',
'ai_agent_id',
'title',
'messages', // JSON array of messages
'status', // active, archived
];
Relationships:
php
public function user() // belongsTo - User
public function ai_agent() // belongsTo - AiAgent
| Model | Purpose | File |
|---|---|---|
| AiModel | AI model configuration | AiModel.php |
| AiPrompt | Prompt template library | AiPrompt.php |
| AiLog | AI usage logging | AiLog.php |
| AiAgentSnippet | Code snippet library | AiAgentSnippet.php |
| AiAgentFileTemplate | File templates | AiAgentFileTemplate.php |
| AiAgentUserRight | Agent permissions | AiAgentUserRight.php |
Purpose: Universal commenting system
File: app/Models/Comment.php
Pattern: Multiple foreign keys (not true polymorphic)
Key Attributes:
php
protected $fillable = [
'instance_id',
'author_id',
'announce_id', // Link to Announce
'meeting_id', // Link to Meeting
'task_id', // Link to Task
'objective_id', // Link to Objective
'key_result_id', // Link to KeyResult
'deal_id', // Link to Deal
'asset_management_item_id', // Link to Asset
'organization_id', // Link to Organization
'project_id', // Link to Project
'custom_evaluation_id', // Link to CustomEvaluation
'body', // Comment text
'status', // draft, live
'type',
];
Relationships:
php
public function author() // belongsTo - User
public function announce() // belongsTo - Announce
public function meeting() // belongsTo - Meeting
public function task() // belongsTo - Task
public function objective() // belongsTo - Objective
public function key_result() // belongsTo - KeyResult
public function deal() // belongsTo - Deal
public function asset_management_item() // belongsTo - AssetManagementItem
public function organization() // belongsTo - Organization
public function project() // belongsTo - Project
public function custom_evaluation() // belongsTo - CustomEvaluation
Helper Methods:
php
public function getRelationModel() // Returns related model instance
public function getRelationType() // Returns relation name (e.g., 'task')
Purpose: Universal tagging system
File: app/Models/Tag.php
Pattern: Many-to-many pivot tables
Key Attributes:
php
protected $fillable = [
'instance_id',
'name',
'color', // Hex color code
'type', // Module categorization
];
Pivot Tables:
- deal_tag
- task_tag
- organization_tag
- etc.
Relationships:
php
public function deals() // belongsToMany - Deal
public function tasks() // belongsToMany - Task
public function organizations() // belongsToMany - Organization
// ... more relationships
Purpose: In-app notification tracking
File: app/Models/NotificationLog.php
Key Attributes:
php
protected $fillable = [
'instance_id',
'user_id',
'title',
'description',
'frontend_type', // Module context
'entity_id', // Related entity ID
'entity_slug', // URL slug
'is_read',
'created_at',
];
Frontend Types:
php
const FE_TASKS = 'Tasks';
const FE_DEALS = 'Deals';
const FE_EVALUATIONS = 'Evaluations';
const FE_PROCEDURES = 'Procedures';
const FE_MEETINGS = 'Meetings';
// ... more types
Relationships:
php
public function user() // belongsTo - User
Purpose: Dynamic field configuration
CustomField Model: ```php class CustomField extends Model { protected $fillable = [ ‘instance_id’, ‘name’, ‘field_type’, // text, number, date, select, etc. ‘entity_type’, // deal, organization, person, etc. ‘options’, // JSON array for select fields ‘is_required’, ‘order’, ‘custom_field_section_id’, ‘status’, ];
public function custom_field_section() // belongsTo
public function custom_field_values() // hasMany
} ```
CustomFieldValue Model: ```php class CustomFieldValue extends Model { protected $fillable = [ ‘instance_id’, ‘custom_field_id’, ‘entity_type’, // Model class ‘entity_id’, // Model ID ‘value’, // Field value ];
public function custom_field() // belongsTo - CustomField
} ```
Usage Example: ```php // Get custom field value $deal->getCustomFieldValue(‘industry’);
// Set custom field value $deal->setCustomFieldValue(‘industry’, ‘Technology’); ```
Purpose: Change tracking for all models
Package: panoscape/history
Pattern: Automatic via HasOperations trait
Table: model_histories
php
Schema::create('model_histories', function (Blueprint $table) {
$table->id();
$table->morphs('model'); // model_type, model_id
$table->text('message');
$table->foreignId('user_id')->nullable();
$table->text('meta')->nullable(); // JSON of changed fields
$table->timestamps();
});
Usage: ```php // Access history $deal->history; // Collection of all changes
// Typical history entry [ ‘model_type’ => ‘App\Models\Deal’, ‘model_id’ => 123, ‘message’ => ‘updated’, ‘user_id’ => 45, ‘meta’ => [ [‘key’ => ‘title’, ‘old’ => ‘Old Title’, ‘new’ => ‘New Title’], [‘key’ => ‘stage_id’, ‘old’ => 5, ‘new’ => 6], ] ] ```
| Model | Purpose | File |
|---|---|---|
| Instance | Tenant/organization | Instance.php |
| Announce | Company announcements | Announce.php |
| CronjobMail | Queued email batch | CronjobMail.php |
| Device | User device tracking | Device.php |
| SmsMessage | SMS notification log | SmsMessage.php |
| Unit | Measurement units | Unit.php |
| Trigger | Event triggers | Trigger.php |
| Report | Report definitions | Report.php |
| Voucher | Voucher/coupon system | Voucher.php |
| Package | Package definitions | Package.php |
| Cronjob | Scheduled job definitions | Cronjob.php |
| WebsocketStatus | WebSocket connection tracking | WebsocketStatus.php |
| SoftwareUpdate | Version update tracking | SoftwareUpdate.php |
| OverallInformation | Instance metadata | OverallInformation.php |
| InstanceNotification | Instance-wide notifications | InstanceNotification.php |
| GamingPoint | Gamification points | GamingPoint.php |
| GlobalCourse | Global course catalog | GlobalCourse.php |
| CourseSection | Course sections | CourseSection.php |
| PurchaseIntention | Purchase requests | PurchaseIntention.php |
| CustomFieldSection | Custom field grouping | CustomFieldSection.php |
Instance
│
├──► User (many)
│ ├──► UserDetail (one)
│ ├──► Department (many-to-many)
│ ├──► Role (many-to-many)
│ ├──► Skill (many-to-many with level)
│ ├──► Right (many-to-many with scope)
│ ├──► UserFile (many)
│ ├──► UserEvaluation (many)
│ └──► User (parent_function) - Manager hierarchy
│
├──► Department (many)
│ ├──► Department (parent) - Hierarchy
│ ├──► User (responsible) - Department head
│ └──► User (many-to-many) - Members
│
└──► Role (many)
├──► Department (one)
└──► User (many-to-many)
Instance
│
├──► Deal (many)
│ ├──► Organization (one)
│ ├──► Person (one)
│ ├──► User (responsible)
│ ├──► Pipeline (one)
│ ├──► Stage (one)
│ ├──► DealSource (one)
│ ├──► Currency (one)
│ ├──► Product (many-to-many)
│ ├──► Task (many)
│ ├──► Comment (many)
│ ├──► Tag (many-to-many)
│ └──► UserFile (many)
│
├──► Organization (many)
│ ├──► Person (many)
│ ├──► Deal (many)
│ ├──► Address (one)
│ ├──► OrganizationType (one)
│ ├──► Comment (many)
│ └──► Tag (many-to-many)
│
├──► Person (many)
│ ├──► Organization (one)
│ └──► Deal (many)
│
└──► Pipeline (many)
├──► Stage (many, ordered)
└──► Deal (many)
Instance
│
├──► Project (many)
│ ├──► User (responsible)
│ ├──► User (many-to-many with editor flag) - Team
│ ├──► Task (many)
│ ├──► Meeting (many)
│ └──► Comment (many)
│
├──► Task (many)
│ ├──► User (assigned)
│ ├──► User (added_by)
│ ├──► Project (one)
│ ├──► Deal (one, optional)
│ ├──► Task (parent_task) - Dependencies
│ ├──► Task (sub_tasks) - Children
│ ├──► User (watchers, many-to-many)
│ ├──► TaskTimer (many)
│ ├──► TaskLog (many)
│ ├──► Checklist (many)
│ └──► Comment (many)
│
└──► Meeting (many)
├──► Project (one)
├──► User (added_by)
├──► User (many-to-many with response) - Attendees
├──► MeetingSession (many)
├──► MeetingSummary (many)
└──► Comment (many)
Instance
│
├──► Process (many)
│ ├──► User (responsible)
│ ├──► ProcessVersion (many)
│ └──► Procedure (many)
│
├──► ProcessVersion (many)
│ └──► Process (one)
│
└──► Procedure (many)
├──► Process (one)
├──► User (responsible)
├──► ProcedureLog (many) - Executions
├──► ProcedureApprovalRequest (many)
├──► ProcedureCheck (many)
└──► ProcedureAnalytic (many)
Instance
│
├──► MasterGoal (many) - Company goals
│ ├──► User (many-to-many) - Managers
│ └──► Objective (many)
│
├──► Objective (many)
│ ├──► User (owner)
│ ├──► MasterGoal (one)
│ ├──► KeyResult (many)
│ ├──► User (pinned_by, many-to-many)
│ └──► Comment (many)
│
├──► KeyResult (many)
│ ├──► Objective (one)
│ ├──► User (owner)
│ ├──► KeyResultLog (many) - Progress updates
│ └──► Comment (many)
│
└──► Indicator (many) - KPI
├──► User (owner)
└──► IndicatorLog (many)
Instance
│
├──► VacationType (many)
│ └──► VacationDay (many)
│
├──► VacationDay (many)
│ ├──► VacationType (one)
│ ├──► User (many-to-many with substitute)
│ └──► VacationApproval (many)
│
└──► VacationPlanner (many)
└──► UserVacationPlanner (many)
└──► User (one)
Comment
├──► User (author)
└──► Multiple entities via foreign keys:
├──► Task
├──► Deal
├──► Meeting
├──► Objective
├──► KeyResult
├──► Organization
├──► Project
└──► AssetManagementItem
Tag (many-to-many with multiple entities)
├──► Deal
├──► Task
├──► Organization
└──► ... (other taggable models)
| Module | Model Count | Key Models |
|---|---|---|
| HR | ~25 | User, Department, Role, Right, Skill, UserFile, UserEvaluation |
| CRM | ~15 | Deal, Organization, Person, Pipeline, Stage, Activity |
| Projects | ~10 | Project, Task, Meeting, TaskTimer, Checklist |
| Procedures | ~15 | Procedure, Process, ProcessVersion, ProcedureLog |
| OKR | ~5 | Objective, KeyResult, MasterGoal, Indicator |
| Vacation | ~10 | VacationDay, VacationType, VacationPlanner |
| Assets | ~5 | AssetManagementItem, AssetManagement, Workstation |
| AI | ~8 | AiAgent, AiModel, AiThread, AiPrompt |
| Shared | ~38 | Comment, Tag, NotificationLog, CustomField, Instance |
| Total | 131 | All models |
Multi-Tenancy:
sql
-- Every table
CREATE INDEX idx_instance_id ON table_name (instance_id);
Foreign Keys:
sql
-- All foreign key columns
CREATE INDEX idx_user_id ON tasks (user_id);
CREATE INDEX idx_department_id ON users (department_id);
Composite Indexes:
sql
-- Common query patterns
CREATE INDEX idx_instance_status ON deals (instance_id, status);
CREATE INDEX idx_instance_user ON tasks (instance_id, user_id, status);
CREATE INDEX idx_instance_date ON vacation_days (instance_id, start_date);
Search Performance:
sql
-- Text search columns
CREATE FULLTEXT INDEX idx_title_desc ON deals (title, description);
CREATE FULLTEXT INDEX idx_name ON users (first_name, last_name);
Document Generated: 2025-10-16 Total Models Documented: 131 Pattern: Laravel Eloquent ORM with multi-tenancy, soft deletes, and audit trail