Upload files to "api"
This commit is contained in:
+267
-286
@@ -2,415 +2,351 @@
|
|||||||
// Session configuration
|
// Session configuration
|
||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
// Database configuration
|
// MySQL Database configuration
|
||||||
define('DB_PATH', __DIR__ . '/../db/markers.db');
|
define('DB_HOST', ' ');
|
||||||
|
define('DB_PORT', ' ');
|
||||||
|
define('DB_NAME', ' ');
|
||||||
|
define('DB_USER', ' ');
|
||||||
|
define('DB_PASS', ' ');
|
||||||
|
|
||||||
// Create db directory if it doesn't exist
|
// Connect to MySQL database
|
||||||
if (!is_dir(__DIR__ . '/../db')) {
|
|
||||||
mkdir(__DIR__ . '/../db', 0755, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect to SQLite database
|
|
||||||
function getDB() {
|
function getDB() {
|
||||||
|
static $db = null;
|
||||||
|
if ($db !== null) {
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$db = new PDO('sqlite:' . DB_PATH);
|
$dsn = 'mysql:host=' . DB_HOST . ';port=' . DB_PORT . ';dbname=' . DB_NAME . ';charset=utf8mb4';
|
||||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
$db = new PDO($dsn, DB_USER, DB_PASS, [
|
||||||
$db->exec('PRAGMA foreign_keys = ON');
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4'
|
||||||
|
]);
|
||||||
|
|
||||||
// Initialize database schema
|
// Initialize database schema
|
||||||
initializeDB($db);
|
initializeDB($db);
|
||||||
|
|
||||||
return $db;
|
return $db;
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
|
http_response_code(500);
|
||||||
die(json_encode(['error' => 'Database connection failed: ' . $e->getMessage()]));
|
die(json_encode(['error' => 'Database connection failed: ' . $e->getMessage()]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize database schema
|
// Initialize database schema (MySQL version)
|
||||||
function initializeDB($db) {
|
function initializeDB($db) {
|
||||||
// Create markers table for points
|
// Create markers table for points
|
||||||
$db->exec('
|
$db->exec('
|
||||||
CREATE TABLE IF NOT EXISTS markers (
|
CREATE TABLE IF NOT EXISTS markers (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
name VARCHAR(255) NOT NULL,
|
name VARCHAR(255) NOT NULL,
|
||||||
nomor_spbu VARCHAR(100),
|
nomor_spbu VARCHAR(100) DEFAULT NULL,
|
||||||
latitude REAL NOT NULL,
|
latitude DOUBLE NOT NULL,
|
||||||
longitude REAL NOT NULL,
|
longitude DOUBLE NOT NULL,
|
||||||
open_24_hours BOOLEAN DEFAULT 0,
|
open_24_hours TINYINT(1) DEFAULT 0,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
');
|
');
|
||||||
|
|
||||||
// Add nomor_spbu column to existing databases if it doesn't exist
|
|
||||||
try {
|
|
||||||
$db->exec('PRAGMA table_info(markers)');
|
|
||||||
$columns = $db->query('PRAGMA table_info(markers)')->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
$hasNomorSpbu = false;
|
|
||||||
|
|
||||||
foreach ($columns as $col) {
|
|
||||||
if ($col['name'] === 'nomor_spbu') {
|
|
||||||
$hasNomorSpbu = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$hasNomorSpbu) {
|
|
||||||
$db->exec('ALTER TABLE markers ADD COLUMN nomor_spbu VARCHAR(100)');
|
|
||||||
}
|
|
||||||
} catch (PDOException $e) {
|
|
||||||
// Table already has the column or other non-critical error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create roads table for polylines
|
// Create roads table for polylines
|
||||||
$db->exec('
|
$db->exec('
|
||||||
CREATE TABLE IF NOT EXISTS roads (
|
CREATE TABLE IF NOT EXISTS roads (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
name VARCHAR(255) NOT NULL,
|
name VARCHAR(255) NOT NULL,
|
||||||
road_type VARCHAR(50) NOT NULL CHECK(road_type IN (\'Nasional\', \'Provinsi\', \'Kabupaten\')),
|
road_type ENUM(\'Nasional\', \'Provinsi\', \'Kabupaten\') NOT NULL,
|
||||||
coordinates TEXT NOT NULL,
|
coordinates LONGTEXT NOT NULL,
|
||||||
length_meters REAL NOT NULL,
|
length_meters DOUBLE NOT NULL,
|
||||||
|
condition_status ENUM(\'normal\', \'minor_damage\', \'major_damage\') DEFAULT \'normal\',
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
');
|
');
|
||||||
|
|
||||||
// Create indexes for roads table
|
// Create indexes for roads table
|
||||||
try {
|
try {
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_roads_road_type ON roads(road_type)');
|
$db->exec('CREATE INDEX idx_roads_road_type ON roads(road_type)');
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_roads_created_at ON roads(created_at)');
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
} catch (PDOException $e) {
|
try {
|
||||||
// Indexes may already exist
|
$db->exec('CREATE INDEX idx_roads_created_at ON roads(created_at)');
|
||||||
}
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
|
|
||||||
// Create land_parcels table for polygons
|
// Create land_parcels table for polygons
|
||||||
$db->exec('
|
$db->exec('
|
||||||
CREATE TABLE IF NOT EXISTS land_parcels (
|
CREATE TABLE IF NOT EXISTS land_parcels (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
name VARCHAR(255) NOT NULL,
|
name VARCHAR(255) NOT NULL,
|
||||||
certificate_type VARCHAR(50) NOT NULL CHECK(certificate_type IN (\'SHM\', \'HGB\', \'HGU\', \'HP\')),
|
certificate_type ENUM(\'SHM\', \'HGB\', \'HGU\', \'HP\') NOT NULL,
|
||||||
coordinates TEXT NOT NULL,
|
coordinates LONGTEXT NOT NULL,
|
||||||
area_sqm REAL NOT NULL,
|
area_sqm DOUBLE NOT NULL,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
');
|
');
|
||||||
|
|
||||||
// Create indexes for land_parcels table
|
// Create indexes for land_parcels table
|
||||||
try {
|
try {
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_parcels_cert_type ON land_parcels(certificate_type)');
|
$db->exec('CREATE INDEX idx_parcels_cert_type ON land_parcels(certificate_type)');
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_parcels_created_at ON land_parcels(created_at)');
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
} catch (PDOException $e) {
|
|
||||||
// Indexes may already exist
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add condition_status column to roads table if it doesn't exist
|
|
||||||
try {
|
try {
|
||||||
$columns = $db->query('PRAGMA table_info(roads)')->fetchAll(PDO::FETCH_ASSOC);
|
$db->exec('CREATE INDEX idx_parcels_created_at ON land_parcels(created_at)');
|
||||||
$hasConditionStatus = false;
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
|
|
||||||
foreach ($columns as $col) {
|
|
||||||
if ($col['name'] === 'condition_status') {
|
|
||||||
$hasConditionStatus = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$hasConditionStatus) {
|
|
||||||
$db->exec('ALTER TABLE roads ADD COLUMN condition_status VARCHAR(20) DEFAULT \'normal\' CHECK(condition_status IN (\'normal\', \'minor_damage\', \'major_damage\'))');
|
|
||||||
}
|
|
||||||
} catch (PDOException $e) {
|
|
||||||
// Column may already exist
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create pontianak_areas table for choropleth boundaries
|
// Create pontianak_areas table for choropleth boundaries
|
||||||
$db->exec('
|
$db->exec('
|
||||||
CREATE TABLE IF NOT EXISTS pontianak_areas (
|
CREATE TABLE IF NOT EXISTS pontianak_areas (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
name VARCHAR(255) NOT NULL,
|
name VARCHAR(255) NOT NULL,
|
||||||
area_type VARCHAR(50) NOT NULL CHECK(area_type IN (\'kelurahan\', \'kecamatan\', \'city\')),
|
area_type ENUM(\'kelurahan\', \'kecamatan\', \'city\') NOT NULL,
|
||||||
geometry TEXT NOT NULL,
|
geometry LONGTEXT NOT NULL,
|
||||||
population INT DEFAULT 0,
|
population INT DEFAULT 0,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
UNIQUE(name, area_type)
|
UNIQUE KEY uq_area_name_type (name, area_type)
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
');
|
');
|
||||||
|
|
||||||
// Create indexes for pontianak_areas table
|
// Create indexes for pontianak_areas table
|
||||||
try {
|
try {
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_pontianak_areas_type ON pontianak_areas(area_type)');
|
$db->exec('CREATE INDEX idx_pontianak_areas_type ON pontianak_areas(area_type)');
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_pontianak_areas_name ON pontianak_areas(name)');
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
} catch (PDOException $e) {
|
try {
|
||||||
// Indexes may already exist
|
$db->exec('CREATE INDEX idx_pontianak_areas_name ON pontianak_areas(name)');
|
||||||
}
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
|
|
||||||
// Create area_statistics table for computed densities
|
// Create area_statistics table for computed densities
|
||||||
$db->exec('
|
$db->exec('
|
||||||
CREATE TABLE IF NOT EXISTS area_statistics (
|
CREATE TABLE IF NOT EXISTS area_statistics (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
pontianak_area_id INTEGER NOT NULL,
|
pontianak_area_id INT NOT NULL,
|
||||||
statistic_type VARCHAR(50) NOT NULL CHECK(statistic_type IN (\'population_density\', \'road_density\', \'damaged_roads_density\')),
|
statistic_type ENUM(\'population_density\', \'road_density\', \'damaged_roads_density\') NOT NULL,
|
||||||
value REAL NOT NULL,
|
value DOUBLE NOT NULL,
|
||||||
data_date DATE NOT NULL,
|
data_date DATE NOT NULL,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
FOREIGN KEY(pontianak_area_id) REFERENCES pontianak_areas(id) ON DELETE CASCADE,
|
UNIQUE KEY uq_area_stat_date (pontianak_area_id, statistic_type, data_date),
|
||||||
UNIQUE(pontianak_area_id, statistic_type, data_date)
|
FOREIGN KEY (pontianak_area_id) REFERENCES pontianak_areas(id) ON DELETE CASCADE
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
');
|
');
|
||||||
|
|
||||||
// Create indexes for area_statistics table
|
// Create indexes for area_statistics table
|
||||||
try {
|
try {
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_stats_area_type ON area_statistics(pontianak_area_id, statistic_type)');
|
$db->exec('CREATE INDEX idx_stats_area_type ON area_statistics(pontianak_area_id, statistic_type)');
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
// Indexes may already exist
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create masjids table
|
// Create masjids table
|
||||||
$db->exec('
|
$db->exec('
|
||||||
CREATE TABLE IF NOT EXISTS masjids (
|
CREATE TABLE IF NOT EXISTS masjids (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
name VARCHAR(255) NOT NULL,
|
name VARCHAR(255) NOT NULL,
|
||||||
latitude REAL NOT NULL,
|
latitude DOUBLE NOT NULL,
|
||||||
longitude REAL NOT NULL,
|
longitude DOUBLE NOT NULL,
|
||||||
radius_meters REAL NOT NULL DEFAULT 500,
|
radius_meters DOUBLE NOT NULL DEFAULT 500,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
');
|
');
|
||||||
|
|
||||||
// Create indexes for masjids table
|
// Create indexes for masjids table
|
||||||
try {
|
try {
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_masjids_created_at ON masjids(created_at)');
|
$db->exec('CREATE INDEX idx_masjids_created_at ON masjids(created_at)');
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_masjids_name ON masjids(name)');
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
} catch (PDOException $e) {
|
try {
|
||||||
// Indexes may already exist
|
$db->exec('CREATE INDEX idx_masjids_name ON masjids(name)');
|
||||||
}
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
|
|
||||||
// Create special needs points table
|
// Create special needs points table
|
||||||
$db->exec('
|
$db->exec('
|
||||||
CREATE TABLE IF NOT EXISTS need_points (
|
CREATE TABLE IF NOT EXISTS need_points (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
name VARCHAR(255) NOT NULL,
|
name VARCHAR(255) NOT NULL,
|
||||||
latitude REAL NOT NULL,
|
latitude DOUBLE NOT NULL,
|
||||||
longitude REAL NOT NULL,
|
longitude DOUBLE NOT NULL,
|
||||||
masjid_id INTEGER NOT NULL,
|
masjid_id INT NOT NULL,
|
||||||
household_name VARCHAR(255),
|
household_name VARCHAR(255) DEFAULT NULL,
|
||||||
head_name VARCHAR(255),
|
head_name VARCHAR(255) DEFAULT NULL,
|
||||||
economic_status VARCHAR(50),
|
economic_status VARCHAR(50) DEFAULT NULL,
|
||||||
is_verified INTEGER NOT NULL DEFAULT 0,
|
is_verified TINYINT(1) NOT NULL DEFAULT 0,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
FOREIGN KEY(masjid_id) REFERENCES masjids(id) ON DELETE CASCADE
|
FOREIGN KEY (masjid_id) REFERENCES masjids(id) ON DELETE CASCADE
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
');
|
');
|
||||||
|
|
||||||
// Create indexes for need_points table
|
// Create indexes for need_points table
|
||||||
try {
|
try {
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_need_points_masjid_id ON need_points(masjid_id)');
|
$db->exec('CREATE INDEX idx_need_points_masjid_id ON need_points(masjid_id)');
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_need_points_created_at ON need_points(created_at)');
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
} catch (PDOException $e) {
|
|
||||||
// Indexes may already exist
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add new columns to existing need_points table if they don't exist
|
|
||||||
try {
|
try {
|
||||||
$columns = $db->query('PRAGMA table_info(need_points)')->fetchAll(PDO::FETCH_ASSOC);
|
$db->exec('CREATE INDEX idx_need_points_created_at ON need_points(created_at)');
|
||||||
$hasHouseholdName = false;
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
$hasHeadName = false;
|
|
||||||
$hasEconomic = false;
|
|
||||||
$hasVerified = false;
|
|
||||||
foreach ($columns as $col) {
|
|
||||||
if ($col['name'] === 'household_name') $hasHouseholdName = true;
|
|
||||||
if ($col['name'] === 'head_name') $hasHeadName = true;
|
|
||||||
if ($col['name'] === 'economic_status') $hasEconomic = true;
|
|
||||||
if ($col['name'] === 'is_verified') $hasVerified = true;
|
|
||||||
}
|
|
||||||
if (!$hasHouseholdName) {
|
|
||||||
$db->exec('ALTER TABLE need_points ADD COLUMN household_name VARCHAR(255)');
|
|
||||||
}
|
|
||||||
if (!$hasHeadName) {
|
|
||||||
$db->exec('ALTER TABLE need_points ADD COLUMN head_name VARCHAR(255)');
|
|
||||||
}
|
|
||||||
if (!$hasEconomic) {
|
|
||||||
$db->exec('ALTER TABLE need_points ADD COLUMN economic_status VARCHAR(50)');
|
|
||||||
}
|
|
||||||
if (!$hasVerified) {
|
|
||||||
$db->exec('ALTER TABLE need_points ADD COLUMN is_verified INTEGER NOT NULL DEFAULT 0');
|
|
||||||
}
|
|
||||||
} catch (PDOException $e) {
|
|
||||||
// non-critical
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create households table for poverty alleviation base data
|
// Create households table for poverty alleviation base data
|
||||||
$db->exec('
|
$db->exec("
|
||||||
CREATE TABLE IF NOT EXISTS households (
|
CREATE TABLE IF NOT EXISTS households (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
household_code VARCHAR(100) NOT NULL UNIQUE,
|
household_code VARCHAR(100) NOT NULL UNIQUE,
|
||||||
head_name VARCHAR(255) NOT NULL,
|
head_name VARCHAR(255) NOT NULL,
|
||||||
nik_hash VARCHAR(255),
|
nik_hash VARCHAR(255) DEFAULT NULL,
|
||||||
latitude REAL NOT NULL,
|
latitude DOUBLE NOT NULL,
|
||||||
longitude REAL NOT NULL,
|
longitude DOUBLE NOT NULL,
|
||||||
need_point_id INTEGER UNIQUE,
|
need_point_id INT DEFAULT NULL UNIQUE,
|
||||||
masjid_id INTEGER,
|
masjid_id INT DEFAULT NULL,
|
||||||
pontianak_area_id INTEGER,
|
pontianak_area_id INT DEFAULT NULL,
|
||||||
monthly_income REAL NOT NULL DEFAULT 0,
|
monthly_income DOUBLE NOT NULL DEFAULT 0,
|
||||||
dependents_count INTEGER NOT NULL DEFAULT 0,
|
dependents_count INT NOT NULL DEFAULT 0,
|
||||||
housing_condition_score INTEGER NOT NULL DEFAULT 3 CHECK(housing_condition_score BETWEEN 1 AND 5),
|
housing_condition_score TINYINT NOT NULL DEFAULT 3,
|
||||||
employment_status VARCHAR(50) NOT NULL DEFAULT \'unknown\' CHECK(employment_status IN (\'formal\', \'informal\', \'unemployed\', \'daily_worker\', \'micro_business\', \'retired\', \'unknown\')),
|
employment_status ENUM('formal', 'informal', 'unemployed', 'daily_worker', 'micro_business', 'retired', 'unknown') NOT NULL DEFAULT 'unknown',
|
||||||
economic_status VARCHAR(50) NOT NULL DEFAULT \'unknown\' CHECK(economic_status IN (\'sangat_miskin\', \'miskin\', \'rentan\', \'cukup\', \'baik\', \'unknown\')),
|
economic_status ENUM('sangat_miskin', 'miskin', 'rentan', 'cukup', 'baik', 'unknown') NOT NULL DEFAULT 'unknown',
|
||||||
verification_status VARCHAR(30) NOT NULL DEFAULT \'unverified\' CHECK(verification_status IN (\'unverified\', \'field_verified\', \'admin_approved\', \'rejected\', \'needs_review\')),
|
verification_status ENUM('unverified', 'field_verified', 'admin_approved', 'rejected', 'needs_review') NOT NULL DEFAULT 'unverified',
|
||||||
vulnerability_notes TEXT,
|
vulnerability_notes TEXT DEFAULT NULL,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
FOREIGN KEY(need_point_id) REFERENCES need_points(id) ON DELETE SET NULL,
|
FOREIGN KEY (need_point_id) REFERENCES need_points(id) ON DELETE SET NULL,
|
||||||
FOREIGN KEY(masjid_id) REFERENCES masjids(id) ON DELETE SET NULL,
|
FOREIGN KEY (masjid_id) REFERENCES masjids(id) ON DELETE SET NULL,
|
||||||
FOREIGN KEY(pontianak_area_id) REFERENCES pontianak_areas(id) ON DELETE SET NULL
|
FOREIGN KEY (pontianak_area_id) REFERENCES pontianak_areas(id) ON DELETE SET NULL
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
');
|
");
|
||||||
|
|
||||||
// Create indexes for households table
|
// Create indexes for households table
|
||||||
try {
|
try {
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_households_code ON households(household_code)');
|
$db->exec('CREATE INDEX idx_households_code ON households(household_code)');
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_households_verification_status ON households(verification_status)');
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_households_masjid_id ON households(masjid_id)');
|
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_households_area_id ON households(pontianak_area_id)');
|
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_households_created_at ON households(created_at)');
|
|
||||||
} catch (PDOException $e) {
|
|
||||||
// Indexes may already exist
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add economic_status column to existing households table if it doesn't exist
|
|
||||||
try {
|
try {
|
||||||
$columns = $db->query('PRAGMA table_info(households)')->fetchAll(PDO::FETCH_ASSOC);
|
$db->exec('CREATE INDEX idx_households_verification_status ON households(verification_status)');
|
||||||
$hasEconomicStatus = false;
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
foreach ($columns as $col) {
|
try {
|
||||||
if ($col['name'] === 'economic_status') {
|
$db->exec('CREATE INDEX idx_households_masjid_id ON households(masjid_id)');
|
||||||
$hasEconomicStatus = true;
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
break;
|
try {
|
||||||
}
|
$db->exec('CREATE INDEX idx_households_area_id ON households(pontianak_area_id)');
|
||||||
}
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
if (!$hasEconomicStatus) {
|
try {
|
||||||
$db->exec("ALTER TABLE households ADD COLUMN economic_status VARCHAR(50) NOT NULL DEFAULT 'unknown'");
|
$db->exec('CREATE INDEX idx_households_created_at ON households(created_at)');
|
||||||
}
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
} catch (PDOException $e) {
|
|
||||||
// non-critical
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create assistance distributions table
|
// Create assistance distributions table
|
||||||
$db->exec('
|
$db->exec("
|
||||||
CREATE TABLE IF NOT EXISTS assistance_distributions (
|
CREATE TABLE IF NOT EXISTS assistance_distributions (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
household_id INTEGER NOT NULL,
|
household_id INT NOT NULL,
|
||||||
assistance_type VARCHAR(50) NOT NULL CHECK(assistance_type IN (\'pangan\', \'tunai\', \'kesehatan\', \'pendidikan\', \'usaha_mikro\', \'lainnya\')),
|
assistance_type ENUM('pangan', 'tunai', 'kesehatan', 'pendidikan', 'usaha_mikro', 'lainnya') NOT NULL,
|
||||||
assistance_value REAL NOT NULL DEFAULT 0,
|
assistance_value DOUBLE NOT NULL DEFAULT 0,
|
||||||
assistance_frequency VARCHAR(30) NOT NULL DEFAULT \'sekali\' CHECK(assistance_frequency IN (\'sekali\', \'mingguan\', \'bulanan\', \'triwulanan\', \'tahunan\', \'insidental\')),
|
assistance_frequency ENUM('sekali', 'mingguan', 'bulanan', 'triwulanan', 'tahunan', 'insidental') NOT NULL DEFAULT 'sekali',
|
||||||
distribution_date DATE NOT NULL,
|
distribution_date DATE NOT NULL,
|
||||||
delivery_status VARCHAR(30) NOT NULL DEFAULT \'pending\' CHECK(delivery_status IN (\'pending\', \'delivered\', \'failed\')),
|
delivery_status ENUM('pending', 'delivered', 'failed') NOT NULL DEFAULT 'pending',
|
||||||
delivered_by VARCHAR(255),
|
delivered_by VARCHAR(255) DEFAULT NULL,
|
||||||
notes TEXT,
|
notes TEXT DEFAULT NULL,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
FOREIGN KEY(household_id) REFERENCES households(id) ON DELETE CASCADE
|
FOREIGN KEY (household_id) REFERENCES households(id) ON DELETE CASCADE
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
');
|
");
|
||||||
|
|
||||||
// Create indexes for assistance distributions table
|
// Create indexes for assistance distributions table
|
||||||
try {
|
try {
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_assistance_household_id ON assistance_distributions(household_id)');
|
$db->exec('CREATE INDEX idx_assistance_household_id ON assistance_distributions(household_id)');
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_assistance_date ON assistance_distributions(distribution_date)');
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_assistance_status ON assistance_distributions(delivery_status)');
|
try {
|
||||||
} catch (PDOException $e) {
|
$db->exec('CREATE INDEX idx_assistance_date ON assistance_distributions(distribution_date)');
|
||||||
// Indexes may already exist
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
}
|
try {
|
||||||
|
$db->exec('CREATE INDEX idx_assistance_status ON assistance_distributions(delivery_status)');
|
||||||
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
|
|
||||||
// Create verification logs table
|
// Create verification logs table
|
||||||
$db->exec('
|
$db->exec("
|
||||||
CREATE TABLE IF NOT EXISTS verification_logs (
|
CREATE TABLE IF NOT EXISTS verification_logs (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
household_id INTEGER NOT NULL,
|
household_id INT NOT NULL,
|
||||||
verification_status VARCHAR(30) NOT NULL CHECK(verification_status IN (\'field_verified\', \'admin_approved\', \'rejected\', \'needs_review\')),
|
verification_status ENUM('field_verified', 'admin_approved', 'rejected', 'needs_review') NOT NULL,
|
||||||
verifier_name VARCHAR(255) NOT NULL,
|
verifier_name VARCHAR(255) NOT NULL,
|
||||||
verifier_role VARCHAR(100),
|
verifier_role VARCHAR(100) DEFAULT NULL,
|
||||||
field_note TEXT,
|
field_note TEXT DEFAULT NULL,
|
||||||
evidence_photo_count INTEGER NOT NULL DEFAULT 0,
|
evidence_photo_count INT NOT NULL DEFAULT 0,
|
||||||
data_confidence_score REAL,
|
data_confidence_score DOUBLE DEFAULT NULL,
|
||||||
verified_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
verified_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
FOREIGN KEY(household_id) REFERENCES households(id) ON DELETE CASCADE
|
FOREIGN KEY (household_id) REFERENCES households(id) ON DELETE CASCADE
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
');
|
");
|
||||||
|
|
||||||
// Create indexes for verification logs table
|
// Create indexes for verification logs table
|
||||||
try {
|
try {
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_verification_household_id ON verification_logs(household_id)');
|
$db->exec('CREATE INDEX idx_verification_household_id ON verification_logs(household_id)');
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_verification_status ON verification_logs(verification_status)');
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_verification_verified_at ON verification_logs(verified_at)');
|
try {
|
||||||
} catch (PDOException $e) {
|
$db->exec('CREATE INDEX idx_verification_status ON verification_logs(verification_status)');
|
||||||
// Indexes may already exist
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
}
|
try {
|
||||||
|
$db->exec('CREATE INDEX idx_verification_verified_at ON verification_logs(verified_at)');
|
||||||
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
|
|
||||||
// Create household scores table (Option B)
|
// Create household scores table
|
||||||
$db->exec('
|
$db->exec("
|
||||||
CREATE TABLE IF NOT EXISTS household_scores (
|
CREATE TABLE IF NOT EXISTS household_scores (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
household_id INTEGER NOT NULL UNIQUE,
|
household_id INT NOT NULL UNIQUE,
|
||||||
skr REAL NOT NULL DEFAULT 0,
|
skr DOUBLE NOT NULL DEFAULT 0,
|
||||||
sag REAL NOT NULL DEFAULT 0,
|
sag DOUBLE NOT NULL DEFAULT 0,
|
||||||
spi REAL NOT NULL DEFAULT 0,
|
spi DOUBLE NOT NULL DEFAULT 0,
|
||||||
priority_level VARCHAR(30) NOT NULL DEFAULT \'low\' CHECK(priority_level IN (\'very_high\', \'high\', \'medium\', \'low\')),
|
priority_level ENUM('very_high', 'high', 'medium', 'low') NOT NULL DEFAULT 'low',
|
||||||
score_version VARCHAR(30) NOT NULL DEFAULT \'v1\',
|
score_version VARCHAR(30) NOT NULL DEFAULT 'v1',
|
||||||
components_json TEXT,
|
components_json TEXT DEFAULT NULL,
|
||||||
computed_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
computed_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
FOREIGN KEY(household_id) REFERENCES households(id) ON DELETE CASCADE
|
FOREIGN KEY (household_id) REFERENCES households(id) ON DELETE CASCADE
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
');
|
");
|
||||||
|
|
||||||
// Create indexes for household_scores table
|
// Create indexes for household_scores table
|
||||||
try {
|
try {
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_household_scores_spi ON household_scores(spi DESC)');
|
$db->exec('CREATE INDEX idx_household_scores_spi ON household_scores(spi)');
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_household_scores_priority ON household_scores(priority_level)');
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_household_scores_computed_at ON household_scores(computed_at)');
|
try {
|
||||||
} catch (PDOException $e) {
|
$db->exec('CREATE INDEX idx_household_scores_priority ON household_scores(priority_level)');
|
||||||
// Indexes may already exist
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
}
|
try {
|
||||||
|
$db->exec('CREATE INDEX idx_household_scores_computed_at ON household_scores(computed_at)');
|
||||||
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
|
|
||||||
// Create score metadata table for versioning/tuning
|
// Create score metadata table for versioning/tuning
|
||||||
$db->exec('
|
$db->exec('
|
||||||
CREATE TABLE IF NOT EXISTS score_metadata (
|
CREATE TABLE IF NOT EXISTS score_metadata (
|
||||||
key_name VARCHAR(100) PRIMARY KEY,
|
key_name VARCHAR(100) PRIMARY KEY,
|
||||||
key_value TEXT NOT NULL,
|
key_value TEXT NOT NULL,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
');
|
');
|
||||||
|
|
||||||
// Create users table for authentication
|
// Create users table for authentication
|
||||||
$db->exec('
|
$db->exec("
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
username VARCHAR(100) NOT NULL UNIQUE,
|
username VARCHAR(100) NOT NULL UNIQUE,
|
||||||
email VARCHAR(255) NOT NULL UNIQUE,
|
email VARCHAR(255) NOT NULL UNIQUE,
|
||||||
password_hash VARCHAR(255) NOT NULL,
|
password_hash VARCHAR(255) NOT NULL,
|
||||||
role VARCHAR(50) NOT NULL DEFAULT \'Petugas\' CHECK(role IN (\'Admin\', \'Petugas\', \'Pimpinan\')),
|
role ENUM('Admin', 'Petugas', 'Pimpinan') NOT NULL DEFAULT 'Petugas',
|
||||||
is_active BOOLEAN NOT NULL DEFAULT 1,
|
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
');
|
");
|
||||||
|
|
||||||
// Create indexes for users table
|
// Create indexes for users table
|
||||||
try {
|
try {
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_users_email ON users(email)');
|
$db->exec('CREATE INDEX idx_users_email ON users(email)');
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_users_username ON users(username)');
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
$db->exec('CREATE INDEX IF NOT EXISTS idx_users_role ON users(role)');
|
try {
|
||||||
} catch (PDOException $e) {
|
$db->exec('CREATE INDEX idx_users_username ON users(username)');
|
||||||
// Indexes may already exist
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
}
|
try {
|
||||||
|
$db->exec('CREATE INDEX idx_users_role ON users(role)');
|
||||||
|
} catch (PDOException $e) { /* Index may already exist */ }
|
||||||
|
|
||||||
// Initialize default admin user
|
// Initialize default admin user
|
||||||
try {
|
try {
|
||||||
$adminCount = $db->query('SELECT COUNT(*) as cnt FROM users WHERE role = \'Admin\'')->fetch(PDO::FETCH_ASSOC);
|
$adminCount = $db->query("SELECT COUNT(*) as cnt FROM users WHERE role = 'Admin'")->fetch(PDO::FETCH_ASSOC);
|
||||||
if ($adminCount['cnt'] == 0) {
|
if ($adminCount['cnt'] == 0) {
|
||||||
$adminPassword = password_hash('admin123', PASSWORD_BCRYPT, ['cost' => 12]);
|
$adminPassword = password_hash('admin123', PASSWORD_BCRYPT, ['cost' => 12]);
|
||||||
$stmt = $db->prepare('INSERT INTO users (username, email, password_hash, role, is_active) VALUES (?, ?, ?, ?, 1)');
|
$stmt = $db->prepare('INSERT INTO users (username, email, password_hash, role, is_active) VALUES (?, ?, ?, ?, 1)');
|
||||||
@@ -433,7 +369,7 @@ function initializeDB($db) {
|
|||||||
'population_reference' => '288315899'
|
'population_reference' => '288315899'
|
||||||
];
|
];
|
||||||
|
|
||||||
$metaStmt = $db->prepare('INSERT OR IGNORE INTO score_metadata (key_name, key_value) VALUES (?, ?)');
|
$metaStmt = $db->prepare('INSERT IGNORE INTO score_metadata (key_name, key_value) VALUES (?, ?)');
|
||||||
foreach ($defaultMeta as $key => $value) {
|
foreach ($defaultMeta as $key => $value) {
|
||||||
$metaStmt->execute([$key, $value]);
|
$metaStmt->execute([$key, $value]);
|
||||||
}
|
}
|
||||||
@@ -895,15 +831,55 @@ function syncNeedPointsToHouseholds($db) {
|
|||||||
$updatedCount = 0;
|
$updatedCount = 0;
|
||||||
$insertedCount = 0;
|
$insertedCount = 0;
|
||||||
|
|
||||||
$updateStmt = $db->prepare("\n UPDATE households\n SET economic_status = (\n SELECT COALESCE(NULLIF(TRIM(np.economic_status), ''), 'unknown')\n FROM need_points np\n WHERE np.id = households.need_point_id\n ),\n updated_at = CURRENT_TIMESTAMP\n WHERE need_point_id IS NOT NULL\n AND (economic_status IS NULL OR TRIM(economic_status) = '')\n ");
|
$updateStmt = $db->prepare("
|
||||||
|
UPDATE households
|
||||||
|
SET economic_status = (
|
||||||
|
SELECT COALESCE(NULLIF(TRIM(np.economic_status), ''), 'unknown')
|
||||||
|
FROM need_points np
|
||||||
|
WHERE np.id = households.need_point_id
|
||||||
|
),
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE need_point_id IS NOT NULL
|
||||||
|
AND (economic_status IS NULL OR TRIM(economic_status) = '')
|
||||||
|
");
|
||||||
$updateStmt->execute();
|
$updateStmt->execute();
|
||||||
$updatedCount += $updateStmt->rowCount();
|
$updatedCount += $updateStmt->rowCount();
|
||||||
|
|
||||||
$missingStmt = $db->query("\n SELECT\n np.id,\n np.name,\n np.latitude,\n np.longitude,\n np.masjid_id,\n np.head_name,\n np.economic_status,\n np.is_verified\n FROM need_points np\n LEFT JOIN households h ON h.need_point_id = np.id\n WHERE h.id IS NULL\n ORDER BY np.id ASC\n ");
|
$missingStmt = $db->query("
|
||||||
|
SELECT
|
||||||
|
np.id,
|
||||||
|
np.name,
|
||||||
|
np.latitude,
|
||||||
|
np.longitude,
|
||||||
|
np.masjid_id,
|
||||||
|
np.head_name,
|
||||||
|
np.economic_status,
|
||||||
|
np.is_verified
|
||||||
|
FROM need_points np
|
||||||
|
LEFT JOIN households h ON h.need_point_id = np.id
|
||||||
|
WHERE h.id IS NULL
|
||||||
|
ORDER BY np.id ASC
|
||||||
|
");
|
||||||
$missingRows = $missingStmt->fetchAll(PDO::FETCH_ASSOC);
|
$missingRows = $missingStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
if (!empty($missingRows)) {
|
if (!empty($missingRows)) {
|
||||||
$insertStmt = $db->prepare("\n INSERT INTO households (\n household_code,\n head_name,\n latitude,\n longitude,\n need_point_id,\n masjid_id,\n monthly_income,\n dependents_count,\n housing_condition_score,\n employment_status,\n economic_status,\n verification_status,\n vulnerability_notes\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ");
|
$insertStmt = $db->prepare("
|
||||||
|
INSERT INTO households (
|
||||||
|
household_code,
|
||||||
|
head_name,
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
need_point_id,
|
||||||
|
masjid_id,
|
||||||
|
monthly_income,
|
||||||
|
dependents_count,
|
||||||
|
housing_condition_score,
|
||||||
|
employment_status,
|
||||||
|
economic_status,
|
||||||
|
verification_status,
|
||||||
|
vulnerability_notes
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
");
|
||||||
|
|
||||||
foreach ($missingRows as $row) {
|
foreach ($missingRows as $row) {
|
||||||
$pointId = (int)$row['id'];
|
$pointId = (int)$row['id'];
|
||||||
@@ -945,7 +921,13 @@ function syncNeedPointsToHouseholds($db) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ensureHouseholdScoresForAllHouseholds($db) {
|
function ensureHouseholdScoresForAllHouseholds($db) {
|
||||||
$missingStmt = $db->query("\n SELECT h.*\n FROM households h\n LEFT JOIN household_scores hs ON hs.household_id = h.id\n WHERE hs.household_id IS NULL\n ORDER BY h.id ASC\n ");
|
$missingStmt = $db->query("
|
||||||
|
SELECT h.*
|
||||||
|
FROM households h
|
||||||
|
LEFT JOIN household_scores hs ON hs.household_id = h.id
|
||||||
|
WHERE hs.household_id IS NULL
|
||||||
|
ORDER BY h.id ASC
|
||||||
|
");
|
||||||
$missingHouseholds = $missingStmt->fetchAll(PDO::FETCH_ASSOC);
|
$missingHouseholds = $missingStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
$computed = 0;
|
$computed = 0;
|
||||||
@@ -1160,14 +1142,13 @@ function upsertHouseholdScore($db, $householdId, $scoreData) {
|
|||||||
updated_at
|
updated_at
|
||||||
)
|
)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
||||||
ON CONFLICT(household_id)
|
ON DUPLICATE KEY UPDATE
|
||||||
DO UPDATE SET
|
skr = VALUES(skr),
|
||||||
skr = excluded.skr,
|
sag = VALUES(sag),
|
||||||
sag = excluded.sag,
|
spi = VALUES(spi),
|
||||||
spi = excluded.spi,
|
priority_level = VALUES(priority_level),
|
||||||
priority_level = excluded.priority_level,
|
score_version = VALUES(score_version),
|
||||||
score_version = excluded.score_version,
|
components_json = VALUES(components_json),
|
||||||
components_json = excluded.components_json,
|
|
||||||
computed_at = CURRENT_TIMESTAMP,
|
computed_at = CURRENT_TIMESTAMP,
|
||||||
updated_at = CURRENT_TIMESTAMP
|
updated_at = CURRENT_TIMESTAMP
|
||||||
');
|
');
|
||||||
|
|||||||
+11
-3
@@ -13,11 +13,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
$data = json_decode(file_get_contents('php://input'), true);
|
$rawData = file_get_contents('php://input');
|
||||||
|
$data = json_decode($rawData, true);
|
||||||
|
|
||||||
if (!isset($data['email']) || !isset($data['password'])) {
|
if (!$data) {
|
||||||
|
$data = $_POST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($data['email']) || empty($data['password'])) {
|
||||||
http_response_code(400);
|
http_response_code(400);
|
||||||
die(json_encode(['error' => 'Email and password are required']));
|
die(json_encode([
|
||||||
|
'error' => 'Email and password are required',
|
||||||
|
'debug' => ['raw' => $rawData, 'post' => $_POST]
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = loginUser($data['email'], $data['password']);
|
$result = loginUser($data['email'], $data['password']);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$db = getDB();
|
$db = getDB();
|
||||||
$stmt = $db->prepare('INSERT INTO score_metadata (key_name, key_value, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP) ON CONFLICT(key_name) DO UPDATE SET key_value = excluded.key_value, updated_at = CURRENT_TIMESTAMP');
|
$stmt = $db->prepare('INSERT INTO score_metadata (key_name, key_value, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP) ON DUPLICATE KEY UPDATE key_value = VALUES(key_value), updated_at = CURRENT_TIMESTAMP');
|
||||||
$stmt->execute(['target_nasional', number_format($targetNasional, 2, '.', '')]);
|
$stmt->execute(['target_nasional', number_format($targetNasional, 2, '.', '')]);
|
||||||
$stmt->execute(['population_reference', (string)$populationReference]);
|
$stmt->execute(['population_reference', (string)$populationReference]);
|
||||||
|
|
||||||
|
|||||||
@@ -77,13 +77,13 @@ try {
|
|||||||
|
|
||||||
// Insert Pontianak areas
|
// Insert Pontianak areas
|
||||||
$stmt = $db->prepare('
|
$stmt = $db->prepare('
|
||||||
INSERT OR IGNORE INTO pontianak_areas (name, area_type, geometry, population)
|
INSERT IGNORE INTO pontianak_areas (name, area_type, geometry, population)
|
||||||
VALUES (?, ?, ?, ?)
|
VALUES (?, ?, ?, ?)
|
||||||
');
|
');
|
||||||
|
|
||||||
$today = date('Y-m-d');
|
$today = date('Y-m-d');
|
||||||
$stats_stmt = $db->prepare('
|
$stats_stmt = $db->prepare('
|
||||||
INSERT OR IGNORE INTO area_statistics (pontianak_area_id, statistic_type, value, data_date)
|
INSERT IGNORE INTO area_statistics (pontianak_area_id, statistic_type, value, data_date)
|
||||||
VALUES (?, ?, ?, ?)
|
VALUES (?, ?, ?, ?)
|
||||||
');
|
');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user