Digital - Data Models & Database Schema

Generated: 2025-10-16 Total Models: 131 Eloquent models Database Migrations: 368 migrations Multi-Tenancy: Row-level with instance_id


Table of Contents

  1. Database Architecture
  2. Model Patterns
  3. HR Module Models
  4. CRM Module Models
  5. Projects & Tasks Module Models
  6. Procedures Module Models
  7. OKR Module Models
  8. Vacation Module Models
  9. Asset Management Module Models
  10. AI Module Models
  11. Shared/Polymorphic Models
  12. Relationship Diagrams

Database Architecture

Multi-Tenancy Pattern

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;
        }
    });
}

Database Scale

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

Model Patterns

Common Traits

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

Standard Model Structure

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() { /* ... */ }
}

Soft Delete Pattern

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();

Audit Trail Pattern

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

Search Pattern

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
        ];
    }
}

HR Module Models

User (Core Model)

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


Department

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


Role

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)


Right

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)


Other HR Models

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

CRM Module Models

Deal

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’); ```


Organization

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


Person

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


Pipeline & Stage

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

} ```


Other CRM Models

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

Projects & Tasks Module Models

Task

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


Project

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


Meeting

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


Other Project Models

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

Procedures Module Models

Procedure

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


Process & ProcessVersion

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

} ```


ProcedureLog

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


Other Procedure Models

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

OKR Module Models

Objective

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


KeyResult

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


KeyResultLog

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


Other OKR Models

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

Vacation Module Models

VacationDay

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


VacationType

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


Other Vacation Models

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

Asset Management Module Models

AssetManagementItem

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)


AssetManagement

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


Other Asset Models

Model Purpose File
AssetManagementTemplate Asset templates AssetManagementTemplate.php
AssetManagementUserRight Asset permissions AssetManagementUserRight.php
Category Asset categorization Category.php
Workstation Workstation/desk management Workstation.php

AI Module Models

AiAgent

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


AiThread

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


Other AI Models

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

Shared/Polymorphic Models

Comment

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')


Tag

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


NotificationLog

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


CustomField & CustomFieldValue

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’); ```


ModelHistory (Audit Trail)

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], ] ] ```


Other Shared Models

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

Relationship Diagrams

HR Module Relationships

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)

CRM Module Relationships

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)

Projects & Tasks Module Relationships

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)

Procedures Module Relationships

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)

OKR Module Relationships

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)

Vacation Module Relationships

Instance
    │
    ├──► VacationType (many)
    │     └──► VacationDay (many)
    │
    ├──► VacationDay (many)
    │     ├──► VacationType (one)
    │     ├──► User (many-to-many with substitute)
    │     └──► VacationApproval (many)
    │
    └──► VacationPlanner (many)
          └──► UserVacationPlanner (many)
                └──► User (one)

Comment & Tag Relationships (Universal)

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)

Model Count by Module

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

Database Indexes

Critical Indexes

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);


Related Documentation


Document Generated: 2025-10-16 Total Models Documented: 131 Pattern: Laravel Eloquent ORM with multi-tenancy, soft deletes, and audit trail