===== STRUCTURE ===== . ├── 0001_01_01_000000_create_users_table.php ├── 0001_01_01_000001_create_cache_table.php ├── 0001_01_01_000002_create_jobs_table.php ├── 2025_10_13_094015_create_personal_access_tokens_table.php ├── 2025_11_01_191535_create_visit_types_table.php ├── 2025_11_01_191610_create_cities_table.php ├── 2025_11_01_191702_create_listings_table.php ├── 2025_11_01_191748_create_products_table.php ├── 2025_11_01_191917_create_cycles_table.php ├── 2025_11_01_191918_create_visits_table.php ├── 2025_11_01_192014_create_visit_products_table.php ├── 2025_11_01_192400_create_objectives_table.php ├── 2025_11_01_192447_create_deplacements_table.php ├── 2025_11_01_192529_create_expenses_table.php ├── 2025_11_01_192612_create_permissions_table.php ├── 2025_11_01_192638_create_action_requests_table.php ├── 2025_11_01_192721_create_budgets_table.php ├── 2025_11_01_192756_create_appointments_table.php ├── 2025_11_01_192848_create_city_user_table.php ├── 2025_12_09_194910_create_salary_settings_table.php ├── 2025_12_09_195125_create_delegue_salaries_table.php ├── 2025_12_24_053940_create_notifications_table.php ├── 2026_03_15_144113_create_locations_table.php ├── 2026_03_15_144230_create_work_sessions_table.php ├── 2026_04_05_152915_create_visits_in_progress_table.php └── output.txt 1 directory, 26 files ===== CONTENU DES FICHIERS ===== ----- ./2025_12_24_053940_create_notifications_table.php ----- id(); $table->foreignId('user_id')->constrained()->cascadeOnDelete(); $table->string('title'); $table->text('message'); $table->string('type')->nullable(); // ex: visit, expense, permission, action, system $table->boolean('is_read')->default(false); $table->json('data')->nullable(); // payload (id visite, route, etc.) $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('notifications'); } }; ----- ./2025_11_01_192638_create_action_requests_table.php ----- id(); $table->foreignId('user_id')->constrained()->cascadeOnDelete(); $table->string('type'); // imprimerie $table->string('produit'); // INOSIFOL $table->text('objectif'); $table->decimal('budget', 10, 2); $table->date('date_demande'); $table->integer('duree_mois'); $table->enum('status', ['non_realise', 'recu'])->default('non_realise'); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('action_requests'); } }; ----- ./2025_11_01_192447_create_deplacements_table.php ----- id(); $table->foreignId('user_id')->constrained(); $table->string('from_city'); $table->string('to_city'); $table->decimal('distance_km', 6, 2)->nullable(); $table->dateTime('date_depart'); $table->enum('status', [ 'non_realise', 'en_cours', 'realise' ])->default('non_realise'); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('deplacements'); } }; ----- ./2025_11_01_191918_create_visits_table.php ----- id(); // Relations principales $table->foreignId('cycle_id')->constrained(); $table->foreignId('user_id')->constrained(); $table->foreignId('listing_id')->constrained(); $table->foreignId('user_accompagnant_id')->nullable()->constrained('users'); // Type de visite $table->enum('visite_type', ['Face à face','Double','Accompagné'])->default('Face à face'); // Date & heure $table->dateTime('date_visit')->nullable(); // 📍 Localisation $table->decimal('user_latitude', 10, 7)->nullable(); $table->decimal('user_longitude', 10, 7)->nullable(); $table->float('distance_meters')->nullable(); $table->boolean('admin_pending')->default(false); // 👤 Interlocuteur $table->string('interlocuteur')->nullable(); $table->string('role')->nullable(); // ✅ Drapeaux booléens $table->boolean('rupture_stock')->default(false); $table->boolean('marche_direct')->default(false); $table->boolean('objection')->default(false); $table->boolean('important')->default(false); // 🕒 Informations de visite $table->integer('elapsed_time')->default(0); $table->json('proposed_meds')->nullable(); $table->json('requested_meds')->nullable(); $table->json('results')->nullable(); $table->text('notes')->nullable(); // ✅ Statut de la visite $table->enum('status', ['valide','invalide','double','non_realisee'])->default('valide'); $table->decimal('poslat', 10, 7)->nullable(); $table->decimal('poslong', 10, 7)->nullable(); $table->boolean('has_ticket')->default(false); $table->boolean('is_far')->default(false); $table->string('far_reason')->nullable(); $table->text('far_explanation')->nullable(); $table->string('image')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('visits'); } }; ----- ./output.txt ----- ----- ./2025_11_01_192400_create_objectives_table.php ----- id(); $table->foreignId('cycle_id')->constrained(); $table->foreignId('user_id')->constrained(); $table->enum('category', [ 'docteur','pharmacie','clinique','urgence','maternite','prive' ]); $table->integer('target_visits')->default(0); $table->integer('achieved')->default(0); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('objectives'); } }; ----- ./0001_01_01_000000_create_users_table.php ----- id(); $table->string('code', 20)->unique()->comment('Code employé unique'); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); // Informations personnelles $table->string('phone', 20)->nullable(); $table->string('mobile', 20)->nullable(); $table->text('address')->nullable(); $table->date('birth_date')->nullable(); $table->string('national_id', 50)->nullable()->comment('CIN ou ID'); // Rôle et permissions $table->enum('role', ['delegue', 'manager', 'admin', 'visitor'])->default('visitor'); // Informations professionnelles $table->date('hire_date')->nullable(); $table->enum('contract_type', ['permanent', 'temporary', 'freelance'])->default('permanent'); $table->string('department', 50)->nullable(); $table->decimal('monthly_target', 10, 2)->default(0); $table->decimal('commission_rate', 5, 2)->default(0)->comment('Taux de commission en %'); // Véhicule de fonction $table->string('car_registration', 20)->nullable(); $table->string('car_model', 50)->nullable(); // Authentification et sécurité $table->string('fcm_token')->nullable()->comment('Token Firebase pour notifications'); $table->timestamp('last_login_at')->nullable(); $table->string('last_login_ip', 45)->nullable(); $table->integer('login_attempts')->default(0); $table->timestamp('locked_until')->nullable(); // Géolocalisation $table->decimal('last_location_latitude', 10, 8)->nullable(); $table->decimal('last_location_longitude', 11, 8)->nullable(); $table->timestamp('last_location_updated_at')->nullable(); // Paramètres et préférences $table->json('settings')->nullable()->comment('Paramètres utilisateur'); // État du compte $table->boolean('is_active')->default(true); $table->boolean('must_change_password')->default(false); $table->timestamp('password_changed_at')->nullable(); $table->softDeletes(); // Indexation $table->index('role'); $table->index(['is_active', 'role']); }); Schema::create('password_reset_tokens', function (Blueprint $table) { $table->string('email')->primary(); $table->string('token'); $table->timestamp('created_at')->nullable(); }); Schema::create('sessions', function (Blueprint $table) { $table->string('id')->primary(); $table->foreignId('user_id')->nullable()->index(); $table->string('ip_address', 45)->nullable(); $table->text('user_agent')->nullable(); $table->longText('payload'); $table->integer('last_activity')->index(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('users'); Schema::dropIfExists('password_reset_tokens'); Schema::dropIfExists('sessions'); } }; ----- ./2025_11_01_192612_create_permissions_table.php ----- id(); $table->foreignId('user_id')->constrained(); $table->date('start_date'); $table->date('end_date')->nullable(); $table->boolean('half_day')->default(false); $table->enum('period', ['matin','apres_midi'])->nullable(); $table->enum('reason', ['trajet','reunion','congres','formation','maladie','affaire_personnel']); $table->text('notes')->nullable(); $table->text('remarque_admin')->nullable(); $table->enum('status', ['accepté','en_cours','refus']); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('permissions'); } }; ----- ./2025_11_01_192721_create_budgets_table.php ----- id(); $table->foreignId('user_id')->constrained(); $table->foreignId('cycle_id')->constrained(); $table->decimal('total_budget',10,2); $table->decimal('used_budget',10,2)->default(0); $table->decimal('remaining_budget',10,2)->default(0); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('budgets'); } }; ----- ./2025_11_01_191610_create_cities_table.php ----- id(); $table->string('name'); $table->string('region')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('cities'); } }; ----- ./2025_11_01_192529_create_expenses_table.php ----- id(); $table->foreignId('user_id')->constrained(); $table->enum('category', ['transport','repas','hotel','autre']); $table->decimal('amount', 10, 2); $table->text('description')->nullable(); $table->enum('status', ['approuvee','rejete','en_attente'])->default('en_attente'); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('expenses'); } }; ----- ./2025_11_01_192756_create_appointments_table.php ----- id(); $table->foreignId('user_id')->constrained(); $table->foreignId('listing_id')->constrained(); $table->dateTime('date_appointment'); $table->text('notes')->nullable(); $table->enum('status',['planifie','realise','annule'])->default('planifie'); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('appointments'); } }; ----- ./2025_11_01_192848_create_city_user_table.php ----- id(); $table->foreignId('user_id')->constrained()->onDelete('cascade'); $table->foreignId('city_id')->constrained()->onDelete('cascade'); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('city_user'); } }; ----- ./2025_12_09_194910_create_salary_settings_table.php ----- id(); $table->decimal('prime_per_visit', 8, 2)->default(10); $table->timestamps(); }); \DB::table('salary_settings')->insert(['prime_per_visit' => 10]); } public function down(): void { Schema::dropIfExists('salary_settings'); } } ----- ./0001_01_01_000001_create_cache_table.php ----- string('key')->primary(); $table->mediumText('value'); $table->integer('expiration'); }); Schema::create('cache_locks', function (Blueprint $table) { $table->string('key')->primary(); $table->string('owner'); $table->integer('expiration'); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('cache'); Schema::dropIfExists('cache_locks'); } }; ----- ./2026_03_15_144113_create_locations_table.php ----- id(); $table->foreignId('user_id')->constrained()->onDelete('cascade'); $table->decimal('latitude', 10, 7); $table->decimal('longitude', 10, 7); $table->timestamp('recorded_at'); $table->timestamps(); $table->index(['user_id', 'recorded_at']); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('locations'); } }; ----- ./2025_11_01_192014_create_visit_products_table.php ----- id(); $table->foreignId('visit_id')->constrained(); $table->foreignId('product_id')->constrained(); $table->enum('type', ['propose','interesse','demande'])->default('propose'); $table->enum('etat', ['prescrit','non_prescrit','a_tester'])->nullable(); $table->integer('quantity')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('visit_products'); } }; ----- ./2025_11_01_191748_create_products_table.php ----- id(); $table->string('name'); $table->string('image_url')->nullable(); $table->text('description')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('products'); } }; ----- ./2025_11_01_191535_create_visit_types_table.php ----- id(); $table->string('label'); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('visit_types'); } }; ----- ./2025_12_09_195125_create_delegue_salaries_table.php ----- id(); $table->foreignId('user_id')->constrained()->onDelete('cascade'); $table->decimal('base_salary', 10, 2)->default(0); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('delegue_salaries'); } }; ----- ./2025_11_01_191702_create_listings_table.php ----- id(); $table->string('name'); $table->string('type'); $table->string('specialty')->nullable(); $table->text('address')->nullable(); $table->foreignId('city_id')->nullable()->constrained(); $table->decimal('lat', 10, 6)->nullable(); $table->decimal('lng', 10, 6)->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('listings'); } }; ----- ./2026_03_15_144230_create_work_sessions_table.php ----- id(); $table->foreignId('user_id')->constrained()->onDelete('cascade'); $table->timestamp('started_at'); $table->timestamp('ended_at')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('work_sessions'); } }; ----- ./2025_11_01_191917_create_cycles_table.php ----- id(); $table->string('name'); $table->date('start_date'); $table->date('end_date'); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('cycles'); } }; ----- ./2025_10_13_094015_create_personal_access_tokens_table.php ----- id(); $table->morphs('tokenable'); $table->text('name'); $table->string('token', 64)->unique(); $table->text('abilities')->nullable(); $table->timestamp('last_used_at')->nullable(); $table->timestamp('expires_at')->nullable()->index(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('personal_access_tokens'); } }; ----- ./2026_04_05_152915_create_visits_in_progress_table.php ----- id(); $table->foreignId('user_id')->constrained()->cascadeOnDelete(); $table->foreignId('listing_id')->constrained()->cascadeOnDelete(); $table->timestamp('start_time')->nullable(); $table->timestamp('end_time')->nullable(); $table->decimal('start_lat', 10, 7)->nullable(); $table->decimal('start_lng', 10, 7)->nullable(); $table->decimal('end_lat', 10, 7)->nullable(); $table->decimal('end_lng', 10, 7)->nullable(); $table->enum('status', ['in_progress', 'finished', 'cancelled']) ->default('in_progress'); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('visits_in_progress'); } }; ----- ./0001_01_01_000002_create_jobs_table.php ----- id(); $table->string('queue')->index(); $table->longText('payload'); $table->unsignedTinyInteger('attempts'); $table->unsignedInteger('reserved_at')->nullable(); $table->unsignedInteger('available_at'); $table->unsignedInteger('created_at'); }); Schema::create('job_batches', function (Blueprint $table) { $table->string('id')->primary(); $table->string('name'); $table->integer('total_jobs'); $table->integer('pending_jobs'); $table->integer('failed_jobs'); $table->longText('failed_job_ids'); $table->mediumText('options')->nullable(); $table->integer('cancelled_at')->nullable(); $table->integer('created_at'); $table->integer('finished_at')->nullable(); }); Schema::create('failed_jobs', function (Blueprint $table) { $table->id(); $table->string('uuid')->unique(); $table->text('connection'); $table->text('queue'); $table->longText('payload'); $table->longText('exception'); $table->timestamp('failed_at')->useCurrent(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('jobs'); Schema::dropIfExists('job_batches'); Schema::dropIfExists('failed_jobs'); } };