تحليل شامل لنظام الصيدليات باستخدام Laravel

تحليل شامل لنظام الصيدليات باستخدام Laravel

1. نظرة عامة على النظام

نظام الصيدليات هو تطبيق ويب شامل يهدف إلى إدارة جميع عمليات الصيدلية بكفاءة عالية، من إدارة المخزون والمبيعات إلى تتبع الوصفات الطبية وإدارة العملاء والموردين.

2. الأهداف الرئيسية للنظام

  • إدارة شاملة لمخزون الأدوية والمنتجات الطبية
  • تتبع تواريخ انتهاء الصلاحية والتنبيه المبكر
  • إدارة المبيعات ونقاط البيع (POS)
  • تتبع الوصفات الطبية والمرضى
  • إدارة الموردين وعمليات الشراء
  • تقارير مالية ومحاسبية شاملة
  • إدارة المستخدمين والصلاحيات
  • تتبع دقيق للعمليات والمعاملات

3. الوحدات الرئيسية

3.1 وحدة إدارة المستخدمين

  • تسجيل الدخول والمصادقة
  • إدارة الأدوار والصلاحيات
  • ملفات تعريف المستخدمين

3.2 وحدة إدارة المخزون

  • إضافة وتعديل المنتجات
  • تتبع الكميات والمستويات الدنيا
  • إدارة تواريخ الانتهاء
  • تصنيف المنتجات

3.3 وحدة المبيعات

  • نقطة البيع (POS)
  • إدارة الفواتير
  • طرق الدفع المتعددة
  • حسابات العملاء

3.4 وحدة الوصفات الطبية

  • تسجيل الوصفات
  • ربط المرضى بالوصفات
  • تتبع الأطباء
  • سجل استهلاك الوصفات

3.5 وحدة المشتريات

  • إدارة الموردين
  • طلبات الشراء
  • استلام البضائع
  • فواتير المشتريات

3.6 وحدة التقارير

  • تقارير المبيعات
  • تقارير المخزون
  • تقارير مالية
  • تقارير انتهاء الصلاحية

4. تصميم قواعد البيانات

4.1 جدول المستخدمين (users)

sql

4.2 جدول الفئات (categories)

sql

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->text('description')->nullable();
            $table->unsignedBigInteger('parent_id')->nullable();
            $table->boolean('is_active')->default(true);
            $table->timestamps();

            $table->foreign('parent_id')->references('id')->on('categories')->onDelete('set null');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('categories');
    }
};

4.3 جدول الموردين (suppliers)

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('suppliers', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('contact_person')->nullable();
            $table->string('email')->nullable();
            $table->string('phone', 20)->nullable();
            $table->text('address')->nullable();
            $table->string('city', 100)->nullable();
            $table->string('country', 100)->nullable();
            $table->string('tax_number', 50)->nullable();
            $table->string('payment_terms')->nullable();
            $table->boolean('is_active')->default(true);
            $table->text('notes')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('suppliers');
    }
};

4.4 جدول المنتجات (products)

sql

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('generic_name')->nullable();
            $table->string('brand')->nullable();
            $table->string('sku', 100)->unique();
            $table->string('barcode')->unique()->nullable();
            $table->unsignedBigInteger('category_id')->nullable();
            $table->unsignedBigInteger('supplier_id')->nullable();
            $table->text('description')->nullable();
            $table->text('composition')->nullable();
            $table->string('dosage')->nullable();
            $table->enum('form', ['tablet', 'capsule', 'syrup', 'injection', 'cream', 'drops', 'other'])->nullable();
            $table->string('unit', 50)->default('piece');
            $table->integer('pack_size')->default(1);
            $table->decimal('purchase_price', 10, 2);
            $table->decimal('selling_price', 10, 2);
            $table->decimal('margin_percentage', 5, 2)->nullable();
            $table->integer('min_stock_level')->default(10);
            $table->integer('max_stock_level')->default(1000);
            $table->boolean('requires_prescription')->default(false);
            $table->boolean('controlled_substance')->default(false);
            $table->enum('storage_temperature', ['room', 'cold', 'frozen'])->default('room');
            $table->boolean('is_active')->default(true);
            $table->string('image_path', 500)->nullable();
            $table->text('notes')->nullable();
            $table->timestamps();

            $table->foreign('category_id')->references('id')->on('categories')->onDelete('set null');
            $table->foreign('supplier_id')->references('id')->on('suppliers')->onDelete('set null');

            // Indexes
            $table->index(['name']);
            $table->index(['sku']);
            $table->index(['barcode']);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
};

4.5 جدول المخزون (inventory)

sql

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('inventory', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('product_id');
            $table->string('batch_number')->nullable();
            $table->integer('quantity')->default(0);
            $table->decimal('purchase_price', 10, 2)->nullable();
            $table->decimal('selling_price', 10, 2)->nullable();
            $table->date('manufacturing_date')->nullable();
            $table->date('expiry_date')->nullable();
            $table->unsignedBigInteger('supplier_id')->nullable();
            $table->string('location')->nullable();
            $table->enum('status', ['available', 'reserved', 'expired', 'damaged'])->default('available');
            $table->timestamps();

            $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
            $table->foreign('supplier_id')->references('id')->on('suppliers')->onDelete('set null');

            // Indexes
            $table->index(['product_id']);
            $table->index(['expiry_date']);
            $table->index(['status']);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('inventory');
    }
};

4.6 جدول العملاء (customers)

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('customers', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->nullable();
            $table->string('phone', 20)->nullable();
            $table->date('date_of_birth')->nullable();
            $table->enum('gender', ['male', 'female'])->nullable();
            $table->text('address')->nullable();
            $table->string('city', 100)->nullable();
            $table->string('emergency_contact')->nullable();
            $table->string('insurance_number')->nullable();
            $table->text('allergies')->nullable();
            $table->text('medical_conditions')->nullable();
            $table->boolean('is_active')->default(true);
            $table->decimal('total_purchases', 10, 2)->default(0);
            $table->integer('loyalty_points')->default(0);
            $table->timestamps();

            // Indexes
            $table->index(['phone']);
            $table->index(['name']);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('customers');
    }
};

4.7 جدول الأطباء (doctors)

sql

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('doctors', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('specialty')->nullable();
            $table->string('license_number')->unique()->nullable();
            $table->string('phone', 20)->nullable();
            $table->string('email')->nullable();
            $table->string('hospital_clinic')->nullable();
            $table->text('address')->nullable();
            $table->string('city', 100)->nullable();
            $table->boolean('is_active')->default(true);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('doctors');
    }
};

4.8 جدول الوصفات الطبية (prescriptions)

sql

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('prescriptions', function (Blueprint $table) {
            $table->id();
            $table->string('prescription_number')->unique();
            $table->unsignedBigInteger('customer_id');
            $table->unsignedBigInteger('doctor_id')->nullable();
            $table->date('issue_date');
            $table->date('expiry_date')->nullable();
            $table->enum('status', ['pending', 'partial', 'completed', 'expired'])->default('pending');
            $table->decimal('total_amount', 10, 2)->default(0);
            $table->text('notes')->nullable();
            $table->string('image_path', 500)->nullable();
            $table->unsignedBigInteger('created_by')->nullable();
            $table->timestamps();

            $table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade');
            $table->foreign('doctor_id')->references('id')->on('doctors')->onDelete('set null');
            $table->foreign('created_by')->references('id')->on('users')->onDelete('set null');

            // Indexes
            $table->index(['customer_id']);
            $table->index(['issue_date']);
            $table->index(['status']);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('prescriptions');
    }
};

4.9 جدول تفاصيل الوصفات (prescription_items)

sql

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('prescription_items', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('prescription_id');
            $table->unsignedBigInteger('product_id');
            $table->integer('quantity');
            $table->string('dosage')->nullable();
            $table->string('frequency')->nullable();
            $table->string('duration')->nullable();
            $table->text('instructions')->nullable();
            $table->integer('dispensed_quantity')->default(0);
            $table->enum('status', ['pending', 'partial', 'completed'])->default('pending');
            $table->timestamps();

            $table->foreign('prescription_id')->references('id')->on('prescriptions')->onDelete('cascade');
            $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('prescription_items');
    }
};

4.10 جدول المبيعات (sales)

sql

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('sales', function (Blueprint $table) {
            $table->id();
            $table->string('invoice_number')->unique();
            $table->unsignedBigInteger('customer_id')->nullable();
            $table->unsignedBigInteger('prescription_id')->nullable();
            $table->unsignedBigInteger('cashier_id');
            $table->datetime('sale_date');
            $table->decimal('subtotal', 10, 2);
            $table->decimal('tax_amount', 10, 2)->default(0);
            $table->decimal('discount_amount', 10, 2)->default(0);
            $table->decimal('total_amount', 10, 2);
            $table->decimal('paid_amount', 10, 2)->default(0);
            $table->decimal('change_amount', 10, 2)->default(0);
            $table->enum('payment_method', ['cash', 'card', 'insurance', 'credit']);
            $table->enum('payment_status', ['pending', 'paid', 'partial', 'refunded'])->default('paid');
            $table->text('notes')->nullable();
            $table->timestamps();

            $table->foreign('customer_id')->references('id')->on('customers')->onDelete('set null');
            $table->foreign('prescription_id')->references('id')->on('prescriptions')->onDelete('set null');
            $table->foreign('cashier_id')->references('id')->on('users')->onDelete('cascade');

            // Indexes
            $table->index(['sale_date']);
            $table->index(['customer_id']);
            $table->index(['cashier_id']);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('sales');
    }
};

4.11 جدول تفاصيل المبيعات (sale_items)

sql

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('sale_items', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('sale_id');
            $table->unsignedBigInteger('product_id');
            $table->unsignedBigInteger('inventory_id')->nullable();
            $table->integer('quantity');
            $table->decimal('unit_price', 10, 2);
            $table->decimal('discount_percentage', 5, 2)->default(0);
            $table->decimal('discount_amount', 10, 2)->default(0);
            $table->decimal('total_price', 10, 2);
            $table->string('batch_number')->nullable();
            $table->date('expiry_date')->nullable();
            $table->timestamps();

            $table->foreign('sale_id')->references('id')->on('sales')->onDelete('cascade');
            $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
            $table->foreign('inventory_id')->references('id')->on('inventory')->onDelete('set null');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('sale_items');
    }
};

4.12 جدول طلبات الشراء (purchase_orders)

sql

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('purchase_orders', function (Blueprint $table) {
            $table->id();
            $table->string('order_number')->unique();
            $table->unsignedBigInteger('supplier_id');
            $table->date('order_date');
            $table->date('expected_delivery_date')->nullable();
            $table->date('actual_delivery_date')->nullable();
            $table->enum('status', ['pending', 'confirmed', 'shipped', 'delivered', 'cancelled'])->default('pending');
            $table->decimal('subtotal', 10, 2);
            $table->decimal('tax_amount', 10, 2)->default(0);
            $table->decimal('shipping_cost', 10, 2)->default(0);
            $table->decimal('total_amount', 10, 2);
            $table->enum('payment_status', ['pending', 'paid', 'partial'])->default('pending');
            $table->text('notes')->nullable();
            $table->unsignedBigInteger('created_by')->nullable();
            $table->timestamps();

            $table->foreign('supplier_id')->references('id')->on('suppliers')->onDelete('cascade');
            $table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('purchase_orders');
    }
};

4.13 جدول تفاصيل طلبات الشراء (purchase_order_items)

sql

CREATE TABLE purchase_order_items (
    id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    purchase_order_id BIGINT UNSIGNED NOT NULL,
    product_id BIGINT UNSIGNED NOT NULL,
    quantity INT NOT NULL,
    unit_price DECIMAL(10,2) NOT NULL,
    total_price DECIMAL(10,2) NOT NULL,
    received_quantity INT DEFAULT 0,
    status ENUM('pending', 'partial', 'received') DEFAULT 'pending',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (purchase_order_id) REFERENCES purchase_orders(id) ON DELETE CASCADE,
    FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE
);

4.14 جدول حركات المخزون (inventory_movements)

sql

CREATE TABLE inventory_movements (
    id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    product_id BIGINT UNSIGNED NOT NULL,
    inventory_id BIGINT UNSIGNED,
    movement_type ENUM('purchase', 'sale', 'adjustment', 'expired', 'damaged', 'returned') NOT NULL,
    quantity INT NOT NULL,
    unit_price DECIMAL(10,2),
    reference_type ENUM('sale', 'purchase_order', 'adjustment', 'expiry') NULL,
    reference_id BIGINT UNSIGNED NULL,
    batch_number VARCHAR(255),
    expiry_date DATE,
    notes TEXT,
    created_by BIGINT UNSIGNED,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE,
    FOREIGN KEY (inventory_id) REFERENCES inventory(id) ON DELETE SET NULL,
    FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL
);

4.15 جدول الخصومات (discounts)

sql

CREATE TABLE discounts (
    id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    code VARCHAR(100) UNIQUE,
    type ENUM('percentage', 'fixed_amount') NOT NULL,
    value DECIMAL(10,2) NOT NULL,
    minimum_amount DECIMAL(10,2) DEFAULT 0,
    maximum_discount DECIMAL(10,2),
    applicable_to ENUM('all', 'category', 'product', 'customer_group') DEFAULT 'all',
    start_date DATE,
    end_date DATE,
    usage_limit INT,
    used_count INT DEFAULT 0,
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

4.16 جدول الإعدادات (settings)

sql

CREATE TABLE settings (
    id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    key VARCHAR(255) UNIQUE NOT NULL,
    value TEXT,
    type ENUM('string', 'integer', 'boolean', 'json') DEFAULT 'string',
    group_name VARCHAR(100),
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

4.17 جدول سجل النشاطات (activity_logs)

sql

CREATE TABLE activity_logs (
    id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    user_id BIGINT UNSIGNED,
    action VARCHAR(255) NOT NULL,
    model_type VARCHAR(255),
    model_id BIGINT UNSIGNED,
    old_values JSON,
    new_values JSON,
    ip_address VARCHAR(45),
    user_agent TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
);

5. العلاقات بين الجداول

العلاقات الرئيسية:

  • المنتجات ← الفئات: علاقة واحد إلى متعدد
  • المنتجات ← المخزون: علاقة واحد إلى متعدد (لتتبع الدفعات المختلفة)
  • العملاء ← الوصفات: علاقة واحد إلى متعدد
  • الوصفات ← تفاصيل الوصفات: علاقة واحد إلى متعدد
  • المبيعات ← تفاصيل المبيعات: علاقة واحد إلى متعدد
  • الموردين ← طلبات الشراء: علاقة واحد إلى متعدد

6. الفهارس المقترحة للأداء

sql

-- فهارس للمنتجات والبحث
CREATE INDEX idx_products_sku ON products(sku);
CREATE INDEX idx_products_barcode ON products(barcode);
CREATE INDEX idx_products_name ON products(name);
CREATE INDEX idx_products_category ON products(category_id);

-- فهارس للمخزون
CREATE INDEX idx_inventory_product ON inventory(product_id);
CREATE INDEX idx_inventory_expiry ON inventory(expiry_date);
CREATE INDEX idx_inventory_status ON inventory(status);

-- فهارس للمبيعات
CREATE INDEX idx_sales_date ON sales(sale_date);
CREATE INDEX idx_sales_customer ON sales(customer_id);
CREATE INDEX idx_sales_cashier ON sales(cashier_id);

-- فهارس للوصفات
CREATE INDEX idx_prescriptions_customer ON prescriptions(customer_id);
CREATE INDEX idx_prescriptions_date ON prescriptions(issue_date);
CREATE INDEX idx_prescriptions_status ON prescriptions(status);

-- فهارس للعملاء
CREATE INDEX idx_customers_phone ON customers(phone);
CREATE INDEX idx_customers_name ON customers(name);

7. الميزات التقنية المطلوبة

7.1 مصادقة وتفويض

  • استخدام Laravel Sanctum أو Passport للمصادقة
  • نظام أدوار وصلاحيات متقدم
  • تسجيل دخول متعدد المستويات

7.2 إدارة المخزون

  • تتبع FIFO/LIFO للدفعات
  • تنبيهات انتهاء الصلاحية
  • إدارة المستويات الدنيا والعليا
  • باركود سكانر دعم

7.3 نقطة البيع (POS)

  • واجهة سريعة وسهلة الاستخدام
  • دعم طرق دفع متعددة
  • طباعة الفواتير
  • إدارة الصندوق

7.4 التقارير والتحليلات

  • تقارير مبيعات يومية/شهرية/سنوية
  • تحليل الأرباح والخسائر
  • تقارير المخزون والحركة
  • تحليل سلوك العملاء

7.5 النسخ الاحتياطي والأمان

  • نسخ احتياطية تلقائية
  • تشفير البيانات الحساسة
  • سجل شامل للعمليات
  • مراجعة الأمان

8. متطلبات الأداء

  • دعم معاملات متزامنة متعددة
  • استجابة سريعة لعمليات البحث
  • معالجة فعالة لكميات كبيرة من البيانات
  • واجهة مستخدم متجاوبة وسريعة

9. الامتثال والمعايير

  • الامتثال لقوانين الأدوية المحلية
  • حماية بيانات المرضى (HIPAA)
  • معايير المحاسبة والضرائب
  • متطلبات التدقيق والمراجعة

هذا التحليل يوفر أساساً قوياً لبناء نظام صيدليات شامل وفعال باستخدام إطار عمل Laravel مع قاعدة بيانات MySQL محسنة للأداء والموثوقية.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->string('phone', 20)->nullable();
            $table->enum('role', ['admin', 'pharmacist', 'cashier', 'manager'])->default('cashier');
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->boolean('is_active')->default(true);
            $table->timestamp('last_login_at')->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
};