initial commit

This commit is contained in:
2026-09-23 12:45:02 +07:00
parent d16f454083
commit 507fc6ccdf
235 changed files with 19587 additions and 2835 deletions
@@ -20,8 +20,6 @@ return new class extends Migration
public function down(): void
{
Schema::table('cats', function (Blueprint $table) {
$table->dropSoftDeletes();
});
// No-op: kolom deleted_at dimiliki migration legacy sebelumnya.
}
};
@@ -57,6 +57,7 @@ return new class extends Migration
*/
public function down(): void
{
Schema::dropIfExists('breeding_tables');
Schema::dropIfExists('kittens');
Schema::dropIfExists('mattings');
}
};
@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void {
Schema::create('medical_records', function (Blueprint $table) {
$table->id();
// Relasi ke kucing
$table->foreignId('cat_id')->constrained()->onDelete('cascade');
// Jenis tindakan: Vaksin, Obat Cacing, Kutu, Grooming
$table->enum('type', ['Vaccine', 'Deworming', 'Flea Treatment', 'Grooming', 'Medical Checkup']);
$table->string('treatment_name'); // Misal: Felocell 4, Drontal, NexGard
$table->date('date_given'); // Tanggal pemberian
$table->date('next_schedule')->nullable(); // Tanggal jadwal berikutnya
$table->text('notes')->nullable(); // Catatan tambahan (misal: reaksi setelah vaksin)
// PIC yang memberikan tindakan
$table->foreignId('performed_by')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
});
}
public function down(): void {
Schema::dropIfExists('medical_records');
}
};
@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('medical_records', function (Blueprint $table) {
$table->string('dosage')->nullable()->after('treatment_name'); // Menyimpan "1/2", "0.5", atau "1"
$table->string('unit')->nullable()->after('dosage'); // Menyimpan "pcs", "tablet", atau "ml"
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('medical_records', function (Blueprint $table) {
//
});
}
};
@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('cats', function (Blueprint $table) {
$table->string('sertifikat_ped_file')->nullable()->after('pedigree');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('cats', function (Blueprint $table) {
//
});
}
};
@@ -0,0 +1,10 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Laragear\WebAuthn\Models\WebAuthnCredential;
return WebAuthnCredential::migration()->with(function (Blueprint $table) {
// Here you can add custom columns to the Two Factor table.
//
// $table->string('alias')->nullable();
});
@@ -0,0 +1,14 @@
<?php
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Migration legacy duplikat. Tabel medical_records sudah dibuat oleh migration sebelumnya.
* Sengaja no-op agar fresh migration dan rollback tidak menghapus tabel yang benar.
*/
public function up(): void {}
public function down(): void {}
};
@@ -0,0 +1,26 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('medicines', function (Blueprint $table) {
// Tambahkan kolom tanggal expired setelah unit
$table->date('expired_at')->nullable()->after('unit');
});
}
public function down(): void
{
Schema::table('medicines', function (Blueprint $table) {
$table->dropColumn('expired_at');
});
}
};
@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
Schema::table('foods', function (Blueprint $table) {
$table->date('expired_at')->nullable()->after('unit');
});
Schema::table('supplies', function (Blueprint $table) {
$table->date('expired_at')->nullable()->after('unit');
});
}
public function down()
{
Schema::table('foods', function (Blueprint $table) {
$table->dropColumn('expired_at');
});
Schema::table('supplies', function (Blueprint $table) {
$table->dropColumn('expired_at');
});
}
};
@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('cats', function (Blueprint $table) {
// Menambahkan kolom treatment_status
// Default 2 (Healthy/Sehat)
// Tipe integer agar ringan, diletakkan setelah kolom status yang sudah ada
$table->integer('treatment_status')->default(2)->after('status')->comment('1: Under Treatment, 2: Healthy');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('cats', function (Blueprint $table) {
$table->dropColumn('treatment_status');
});
}
};
@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('treatment_details', function (Blueprint $table) {
$table->id();
// Menghubungkan ke tabel rekam medis utama
$table->foreignId('treatment_id')->constrained('treatments')->onDelete('cascade');
// Menghubungkan ke tabel inventory obat (medicines)
// Jika kolom di tabel medicines adalah 'id', gunakan foreignId
$table->foreignId('medicine_id')->constrained('medicines');
$table->string('dosis')->nullable(); // Contoh: 0.5ml atau 1 tablet
$table->string('keterangan_pakai')->nullable(); // Contoh: Campur Nebu, Sesudah makan
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('treatment_details');
}
};
@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('treatments', function (Blueprint $table) {
// Menghapus kolom obat lama karena sudah digantikan oleh tabel detail
// Pastikan kolom ini memang ada sebelum dijalankan
if (Schema::hasColumn('treatments', 'nama_obat')) {
$table->dropColumn(['nama_obat', 'dosis', 'keterangan']);
}
});
}
public function down(): void
{
Schema::table('treatments', function (Blueprint $table) {
// Mengembalikan kolom jika rollback (opsional)
$table->string('nama_obat')->nullable();
$table->string('dosis')->nullable();
$table->text('keterangan')->nullable();
});
}
};
@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
Schema::table('treatments', function (Blueprint $table) {
$table->integer('status_perawatan')->default(1);
$table->text('remark_pasca_sakit')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('treatments', function (Blueprint $table) {
//
});
}
};
@@ -0,0 +1,131 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('cat_associations', function (Blueprint $table) {
$table->id();
$table->string('code', 30)->unique();
$table->string('name');
$table->string('country')->nullable();
$table->string('website')->nullable();
$table->boolean('is_active')->default(true);
$table->timestamps();
});
Schema::create('cat_registrations', function (Blueprint $table) {
$table->id();
$table->foreignId('cat_id')->constrained('cats')->cascadeOnDelete();
$table->foreignId('association_id')->constrained('cat_associations')->restrictOnDelete();
$table->string('registration_number')->nullable();
$table->string('pedigree_number')->nullable();
$table->string('certificate_number')->nullable();
$table->date('issue_date')->nullable();
$table->string('title')->nullable();
$table->string('ownership_status', 40)->nullable();
$table->boolean('is_primary')->default(false);
$table->text('notes')->nullable();
$table->timestamps();
$table->unique(['cat_id', 'association_id'], 'cat_registration_association_unique');
$table->index(['cat_id', 'is_primary']);
});
Schema::create('cat_registration_documents', function (Blueprint $table) {
$table->id();
$table->foreignId('cat_registration_id')->constrained('cat_registrations')->cascadeOnDelete();
$table->string('label')->default('Sertifikat Pedigree');
$table->string('document_type', 40)->default('pedigree');
$table->string('file_path');
$table->date('issued_at')->nullable();
$table->timestamps();
});
$associations = [
['code' => 'ICA', 'name' => 'Indonesian Cat Association', 'country' => 'Indonesia'],
['code' => 'CFA', 'name' => 'The Cat Fanciers\' Association', 'country' => 'Amerika Serikat'],
['code' => 'WCF', 'name' => 'World Cat Federation', 'country' => 'Internasional'],
['code' => 'FIFe', 'name' => 'Fédération Internationale Féline', 'country' => 'Internasional'],
['code' => 'FFF', 'name' => 'Federasi Feline Indonesia', 'country' => 'Indonesia'],
];
foreach ($associations as $association) {
DB::table('cat_associations')->updateOrInsert(
['code' => $association['code']],
array_merge($association, ['is_active' => 1, 'created_at' => now(), 'updated_at' => now()])
);
}
// Migrasi aman dari field pedigree/registry lama. Field lama tidak dihapus agar rollback mudah.
if (Schema::hasTable('cats')) {
DB::table('cats')->orderBy('id')->chunkById(100, function ($cats) {
foreach ($cats as $cat) {
$rawRegistry = $cat->registry ?? null;
$registries = [];
if (is_string($rawRegistry) && $rawRegistry !== '') {
$decoded = json_decode($rawRegistry, true);
if (json_last_error() === JSON_ERROR_NONE) {
$registries = is_array($decoded) ? $decoded : [$decoded];
} else {
$registries = preg_split('/[,;|]+/', $rawRegistry) ?: [];
}
}
$registries = array_values(array_unique(array_filter(array_map(fn($v) => trim((string)$v), $registries), fn($v) => $v && strtoupper($v) !== 'NON-PED')));
// Bila nomor pedigree lama ada tetapi registry kosong, simpan di asosiasi LEGACY.
if (!$registries && !empty($cat->pedigree)) {
$registries = ['LEGACY'];
}
foreach ($registries as $index => $code) {
$code = strtoupper($code);
$associationId = DB::table('cat_associations')->whereRaw('UPPER(code) = ?', [$code])->value('id');
if (!$associationId) {
$associationId = DB::table('cat_associations')->insertGetId([
'code' => $code,
'name' => $code === 'LEGACY' ? 'Registrasi Lama' : $code,
'is_active' => 1,
'created_at' => now(),
'updated_at' => now(),
]);
}
$registrationId = DB::table('cat_registrations')->insertGetId([
'cat_id' => $cat->id,
'association_id' => $associationId,
'registration_number' => $index === 0 ? ($cat->pedigree ?? null) : null,
'pedigree_number' => $index === 0 ? ($cat->pedigree ?? null) : null,
'is_primary' => $index === 0 ? 1 : 0,
'notes' => 'Dimigrasikan otomatis dari data registrasi lama.',
'created_at' => now(),
'updated_at' => now(),
]);
if ($index === 0 && !empty($cat->sertifikat_ped_file)) {
DB::table('cat_registration_documents')->insert([
'cat_registration_id' => $registrationId,
'label' => 'Sertifikat lama',
'document_type' => 'pedigree',
'file_path' => $cat->sertifikat_ped_file,
'created_at' => now(),
'updated_at' => now(),
]);
}
}
}
}, 'id');
}
}
public function down(): void
{
Schema::dropIfExists('cat_registration_documents');
Schema::dropIfExists('cat_registrations');
Schema::dropIfExists('cat_associations');
}
};
@@ -0,0 +1,26 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('api_tokens', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
$table->string('name')->default('Android');
$table->string('token_hash', 64)->unique();
$table->timestamp('last_used_at')->nullable();
$table->timestamp('expires_at')->nullable();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('api_tokens');
}
};