thibitisha / kmpdc-seeder
Laravel package to seed KMPDC practitioner data
Installs: 120
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/thibitisha/kmpdc-seeder
Requires
- php: ^8.2
- league/csv: ^9.16
- symfony/css-selector: ^7.0
- symfony/dom-crawler: ^7.0
- dev-main
- 0.0.47-alpha
- 0.0.46-alpha
- 0.0.45-alpha
- 0.0.44-alpha
- 0.0.43-alpha
- 0.0.42-alpha
- 0.0.41-alpha
- 0.0.40-alpha
- 0.0.39-alpha
- 0.0.38-alpha
- 0.0.37-alpha
- 0.0.36-alpha
- 0.0.35-alpha
- 0.0.34-alpha
- 0.0.33-alpha
- 0.0.32-alpha
- 0.0.31-alpha
- 0.0.30-alpha
- 0.0.29-alpha
- 0.0.27-alpha
- 0.0.26-alpha
- 0.0.25-alpha
- 0.0.24-alpha
- 0.0.23-alpha
- 0.0.22-alpha
- 0.0.21-alpha
- 0.0.20-alpha
- 0.0.19-alpha
- 0.0.18-alpha
- 0.0.17-alpha
- 0.0.16-alpha
- 0.0.15-alpha
- 0.0.14-alpha
- 0.0.13-alpha
- 0.0.12-alpha
- 0.0.11-alpha
- 0.0.1
This package is auto-updated.
Last update: 2025-12-05 15:36:25 UTC
README
A Laravel 12+ package for scraping, cleaning, and importing practitioner data from the Kenya Medical Practitioners and Dentists Council (KMPDC) master register.
This package is designed for:
- ๐งโ๐ซ Teaching structured data ingestion and seeding in Laravel
๐ Features
โ
Scrapes KMPDC register HTML into structured CSVs
โ
Extracts & normalizes:
- Practitioner details, qualifications, degrees, institutions
โ Imports structured data into related tables
โ Works seamlessly with Eloquent models
๐ฆ Installation
composer require thibitisha/kmpdc-seeder:^0.0.47-alpha
๐งฉ Database Schema
The package models relationships between practitioners, qualifications, degrees, institutions, and related entities.
erDiagram
practitioners ||--|| statuses : has
practitioners ||--|| specialities : belongs_to
practitioners }o--|| sub_specialities : may_specialize_in
practitioners ||--o{ qualifications : holds
practitioners ||--o{ contacts : has
practitioners ||--o{ licenses : issued
practitioners ||--o{ practitioner_documents : uploads
qualifications }|--|| degrees : is_type
qualifications }|--|| institutions : awarded_by
sub_specialities }|--|| specialities : under
licenses ||--o{ payments : renewed_via
users ||--|| roles : assigned_role
verification_logs }o--|| practitioners : attempts_to_verify
practitioners {
BIGINT id PK
VARCHAR registration_number UK
VARCHAR full_name
VARCHAR profile_photo_url "nullable"
BIGINT status_id FK
BIGINT speciality_id FK "nullable"
BIGINT sub_speciality_id FK "nullable"
DATE date_of_registration "nullable"
TIMESTAMP created_at
TIMESTAMP updated_at
}
sub_specialities {
BIGINT id PK
VARCHAR name
BIGINT speciality_id FK
}
Loading
๐ Notes
- All inserts and relationships are handled via Eloquent models
๐งฉ Model Setup & Relationships
Before running the import commands, ensure that all Eloquent models and their respective relationships are correctly defined according to the database schema provided above.
Each model should reflect its table structure and foreign key relationships.
โ ๏ธ Note: the $fillable propery should also be defined in each model
For example:
-
PractitionerbelongsToโStatus,Speciality,SubSpecialityhasManyโContact,License,Qualification,PractitionerDocument,VerificationLog
-
QualificationbelongsToโPractitioner,Degree,Institution
-
SubSpecialitybelongsToโSpeciality
-
LicensebelongsToโPractitionerhasManyโPayment
These relationships are essential for the import command to correctly associate records during data seeding. Ensure that:
- Foreign keys are properly defined in migrations.
- Model relationships use typed relationship methods (as required in Laravel 12).
- Nullable foreign keys (e.g.,
speciality_id,sub_speciality_id) are handled gracefully to avoid integrity constraint violations.
โ ๏ธ Note: The package assumes these model relationships exist and are correctly implemented. Missing or incorrectly defined relationships may cause the import process to fail or produce inconsistent data.
๐ Workflow Overview
This package processes practitioner data in three main stages:
| Step | Command | Input โ Output | Description |
|---|---|---|---|
| ๐งญ 1. Sync | php artisan kmpdc:sync |
Web data โ timestamped CSV file | Crawls the KMPDC register and generates a timestamped CSV file containing all practitioners' details (name, registration number, qualifications, address, status, speciality, etc.). |
| ๐งฎ 2. Extract | php artisan kmpdc:extract |
CSV โ JSON files | Parses the latest CSV, extracts structured data (degrees, institutions, statuses, specialities), and saves normalized JSON files. |
| ๐ฅ 3. Import | php artisan kmpdc:import |
JSON files โ Database | Imports structured data into your Laravel models, preserving relationships and handling duplicates safely. |
๐งฉ Run in this order:
sync โ extract โ import
๐งญ Step 1 โ Sync (Generate CSV)
The sync command crawls the KMPDC register and saves a timestamped CSV file to your Laravel storage directory.
php artisan kmpdc:sync
Output Example:
storage/app/kmpdc-data/csv
โโโ 0000_00_00_122105_kmpdc_practitioners.csv
Each run produces a uniquely named file based on the timestamp, ensuring previous syncs remain preserved.
Included columns:
- Fullname
- Registration Number
- Address
- Qualifications
- Discipline / Speciality
- Sub-speciality
- Status
- Profile link
๐งฎ Step 2 โ Extract (Generate JSON)
The extract command reads the latest timestamped CSV and produces clean, structured JSON files.
php artisan kmpdc:extract
๐ฅ Step 3 โ Import (Save to Database)
Imports the normalized JSON into your relational schema.
php artisan kmpdc:import
๐ง Verify Imports
You can verify successful import via Tinker:
php artisan tinker
use App\Models\Practitioner; Practitioner::with(['status', 'speciality', 'subSpeciality', 'qualifications'])->first();
Examples
use App\Models\Practitioner; // Fetch one doctor $doctor = Practitioner::with(['status', 'speciality', 'subSpeciality', 'qualifications.degree', 'qualifications.institution'])->first(); $doctor->full_name; // "Dr JOHN DOE" $doctor->status->name; // "ACTIVE" $doctor->speciality?->name; // "SURGERY" $doctor->subSpeciality?->name; // "CARDIOLOGY" // Get all unique institutions \App\Models\Institution::pluck('name'); // Find all practitioners under Internal Medicine \App\Models\Practitioner::whereHas('speciality', fn($q) => $q->where('name', 'INTERNAL MEDICINE'))->count();
๐ค Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/my-feature) - Commit your changes (
git commit -m 'Add my feature') - Push to your branch (
git push origin feature/my-feature) - Open a Pull Request ๐
๐๏ธ Acknowledgement & Disclaimer
This package utilizes publicly accessible practitioner data from the
official Kenya Medical Practitioners and Dentists Council (KMPDC) website.
The author, KDBZ, is not affiliated with, endorsed, or sponsored by KMPDC.
All practitioner data, formats, and associated intellectual property remain the exclusive property of KMPDC.
This project is provided solely for educational, analytical, and research purposes.
It is not intended for redistribution, resale, or use in any commercial or official capacity.
Users are responsible for ensuring that their use of this tool complies with:
- The KMPDC websiteโs terms of service
- Applicable data protection and privacy laws
- Relevant ethical and professional standards
For any commercial or institutional use, explicit authorization should be sought directly from KMPDC.
๐ License
This package is open-sourced software licensed under the MIT license.
Author: KDBZ Repository: https://github.com/kdbz/kmpdc-seeder