devsofttech_hms_ci4/app/Database/Migrations/2026-08-15-000001_AddAadhaarVaultToPatientMaster.php

96 lines
3.0 KiB
PHP

<?php
namespace App\Database\Migrations;
use App\Libraries\AadhaarVaultService;
use CodeIgniter\Database\Migration;
class AddAadhaarVaultToPatientMaster extends Migration
{
public function up(): void
{
if (! $this->db->tableExists('patient_master')) {
return;
}
$fields = $this->db->getFieldNames('patient_master') ?? [];
$add = [];
if (! in_array('udai_enc', $fields, true)) {
$add['udai_enc'] = ['type' => 'TEXT', 'null' => true, 'comment' => 'AES-256-GCM encrypted Aadhaar'];
}
if (! in_array('udai_hash', $fields, true)) {
$add['udai_hash'] = ['type' => 'CHAR', 'constraint' => 64, 'null' => true, 'comment' => 'HMAC-SHA256 of Aadhaar for exact-match search'];
}
if (! in_array('udai_last4', $fields, true)) {
$add['udai_last4'] = ['type' => 'VARCHAR', 'constraint' => 4, 'null' => true, 'comment' => 'Last 4 digits for display'];
}
if ($add !== []) {
$this->forge->addColumn('patient_master', $add);
}
if (! $this->indexExists('patient_master', 'idx_patient_udai_hash')) {
$this->db->query('CREATE INDEX idx_patient_udai_hash ON patient_master (udai_hash)');
}
$this->migrateExistingAadhaar();
}
public function down(): void
{
if (! $this->db->tableExists('patient_master')) {
return;
}
if ($this->indexExists('patient_master', 'idx_patient_udai_hash')) {
$this->db->query('DROP INDEX idx_patient_udai_hash ON patient_master');
}
$fields = $this->db->getFieldNames('patient_master') ?? [];
foreach (['udai_enc', 'udai_hash', 'udai_last4'] as $column) {
if (in_array($column, $fields, true)) {
$this->forge->dropColumn('patient_master', $column);
}
}
}
/**
* Move any plaintext Aadhaar already in udai into the vault and mask the column.
*/
private function migrateExistingAadhaar(): void
{
$vault = new AadhaarVaultService();
$rows = $this->db->table('patient_master')
->select('id, udai')
->where('udai IS NOT NULL', null, false)
->where("TRIM(udai) <> ''", null, false)
->where('udai_enc IS NULL', null, false)
->get()
->getResultArray();
foreach ($rows as $row) {
$digits = $vault->normalize((string) ($row['udai'] ?? ''));
if ($digits === '') {
continue;
}
$this->db->table('patient_master')
->where('id', (int) $row['id'])
->update($vault->buildColumns($digits));
}
}
private function indexExists(string $table, string $indexName): bool
{
foreach ($this->db->query('SHOW INDEX FROM ' . $table)->getResultArray() as $row) {
if (($row['Key_name'] ?? '') === $indexName) {
return true;
}
}
return false;
}
}